protected override void Load()

in src/common/LoggingModule.cs [58:230]


        protected override void Load(ContainerBuilder builder)
        {
            // OperationContext
            builder.RegisterType<OperationContext>()
                   .OnActivating(c =>
                   {
                       c.Instance.Version = AssemblyVersionUtilities.GetCallingAssemblyInformationalVersion();
                       c.Instance.StartTime = DateTime.UtcNow;
                       c.Instance.LoggingProperties[Property.ApplicationName] = this.ApplicationName;
                       c.Instance.LoggingProperties[Property.DeviceOperatingSystem] = RuntimeInformation.OSDescription;
                       c.Instance.LoggingProperties[Property.Framework] = RuntimeInformation.FrameworkDescription;
                       if (MacAddressHash != null)
                       {
                           c.Instance.LoggingProperties[Property.MacAddressHash] = MacAddressHash(c.Context);
                       }
                   })
                   .As<IOperationContext>()
                   .IfNotRegistered(typeof(IOperationContext))
                   .InstancePerLifetimeScope();

            builder.RegisterType<AssemblyMetadataProvider>()
                   .As<IAssemblyMetadataProvider>()
                   .IfNotRegistered(typeof(IAssemblyMetadataProvider))
                   .SingleInstance();

            builder.RegisterType<SourceUserAgentProvider>()
                   .WithParameter(TypedParameter.From(this.ApplicationName))
                   .AsSelf()
                   .IfNotRegistered(typeof(SourceUserAgentProvider))
                   .SingleInstance();

            // This allows to automatically carry the context down Autofac LifetimeScopes
            builder.RegisterBuildCallback(c =>
            {
                void inheritContext(object x, LifetimeScopeBeginningEventArgs y)
                {
                    var oldContext = ((ILifetimeScope)x).Resolve<IOperationContext>();
                    var newContext = y.LifetimeScope.Resolve<IOperationContext>();
                    newContext.Inherit(oldContext);
                    y.LifetimeScope.ChildLifetimeScopeBeginning += inheritContext;
                };
                c.ChildLifetimeScopeBeginning += inheritContext;
            });

            // Add custom properties to the Operation Context
            builder.RegisterBuildCallback(c =>
            {
                var operationContext = c.Resolve<IOperationContext>();
                var environmentVariables = c.Resolve<IEnvironmentVariables>();

                operationContext.Version = c.Resolve<IAssemblyMetadataProvider>().AssemblyVersion;
                operationContext.LoggingProperties[Property.ProcessId] = Process.GetCurrentProcess().Id;
                operationContext.LoggingProperties[Property.TargetEnvironment] = environmentVariables.ReleaseEnvironment.ToString();
                operationContext.UserAgent = c.Resolve<SourceUserAgentProvider>().UserAgent;

                // Add any application-specific Operation Context properties.
                this.OperationContextInitializer?.Invoke(c, operationContext);
            });

            // Note:
            // Logger Writers are single instance since they don't reference context and are only outputting to a single TelemetryClient or File.
            // Example of writers are ApplicationInsights TelemetryClient and ThreadSafeFileWriter since they are the last class of the pipeline that finally send or persist the data.
            //
            // Logger are InstancePerLifetimeScope since they point to an InstancePerLifeTimeScope ContextResolver.
            // Loggers are middleware classes between the standard ILog API and the specific implementation of the logger writer they rely on. E.g. ApplicationInsightsLogger wraps TelemetryClient

            if (this.EnableDefaultLogFile ||
                !string.IsNullOrWhiteSpace(this.LogFileDirectory) ||
                !string.IsNullOrWhiteSpace(this.FullLogFilePath))
            {
                string defaultFileName = $"{Constants.Product.NameAbbreviation.ToLowerInvariant()}-{this.ApplicationName.ToLowerInvariant()}-{DateTime.UtcNow.ToString("yyyy-MM-dd-HH-mm-ss")}-{Process.GetCurrentProcess().Id}.txt";
                string logFilePath = Path.Combine(Path.GetTempPath(), Constants.DirectoryName.Logs, defaultFileName);
                if (!string.IsNullOrWhiteSpace(this.LogFileDirectory))
                {
                    logFilePath = Path.Combine(this.LogFileDirectory, defaultFileName);
                }
                if (!string.IsNullOrWhiteSpace(this.FullLogFilePath))
                {
                    logFilePath = this.FullLogFilePath;
                }

                builder.RegisterType<ThreadSafeFileWriter>()
                       .WithParameter(TypedParameter.From(logFilePath))
                       .Named<IThreadSafeFileWriter>(logFilePath)
                       .SingleInstance();

                builder.RegisterType<FileLoggerConfig>()
                       .WithParameter(TypedParameter.From(this.ApplicationName))
                       .As<IFileLoggerConfig>()
                       .IfNotRegistered(typeof(IFileLoggerConfig))
                       .SingleInstance();

                builder.Register(c => new FileLogger(c.Resolve<IOperationContext>(), c.ResolveNamed<IThreadSafeFileWriter>(logFilePath), c.Resolve<IFileLoggerConfig>()))
                       .As<IFileLogger>()
                       .As<ILogger>()
                       .InstancePerLifetimeScope();
            }

            if (this.ConsoleLoggingEnabled)
            {
                builder.RegisterType<EnvironmentVariables>()
                       .As<IEnvironmentVariables>()
                       .IfNotRegistered(typeof(IEnvironmentVariables))
                       .SingleInstance();

                builder.RegisterType<ConsoleLoggerConfig>()
                       .WithParameter(TypedParameter.From(this.ApplicationName))
                       .As<IConsoleLoggerConfig>()
                       .IfNotRegistered(typeof(IConsoleLoggerConfig))
                       .SingleInstance();

                builder.RegisterType<ConsoleLogger>()
                       .As<ILogger>()
                       .PreserveExistingDefaults()
                       .InstancePerLifetimeScope();
            }

            if (this.ApplicationInsightsEnabled)
            {
                builder.RegisterType<EnvironmentVariables>()
                       .As<IEnvironmentVariables>()
                       .IfNotRegistered(typeof(IEnvironmentVariables))
                       .SingleInstance();

                builder.Register<TelemetryConfiguration>(c =>
                           new TelemetryConfiguration
                           {
                               InstrumentationKey = this.ApplicationInsightsInstrumentationKey(c),
                               TelemetryChannel = new ApplicationInsights.Channel.InMemoryChannel()
                           })
                       .AsSelf() // May override a default registration
                       .SingleInstance();

                // Telemetry Initializer
                builder.RegisterType<OperationContextTelemetryInitializer>()
                       .As<IOperationContextTelemetryInitializer>()
                       .InstancePerLifetimeScope();

                builder.RegisterType<ApplicationInsightsLoggerConfig>()     // By default, this type gets registered to send AI telemetry which can be disabled via an env variable or providing an expliciting callback function
                       .As<IApplicationInsightsLoggerConfig>()
                       .IfNotRegistered(typeof(IApplicationInsightsLoggerConfig))
                       .SingleInstance();

                builder.Register<TelemetryClient>(c =>
                       {
                           var telClient = new TelemetryClient(c.Resolve<TelemetryConfiguration>());
                           var operationContext = c.Resolve<IOperationContext>();

                           telClient.InstrumentationKey = this.ApplicationInsightsInstrumentationKey(c);

                           try
                           {
                               telClient.Context.Device.OperatingSystem = (string)operationContext.LoggingProperties[Property.DeviceOperatingSystem];
                           }
                           catch { }
                           return telClient;
                       })
                       .AsSelf() // May override a default registration
                       .SingleInstance();

                builder.RegisterType<ApplicationInsightsLogger>()
                       .WithParameter(TypedParameter.From(this))
                       .OnActivating(e => e.Instance.ShouldScramblePii = e.Context.Resolve<IEnvironmentVariables>().ReleaseEnvironment.IsProduction())
                       .As<ILogger>()
                       .AsSelf()
                       .InstancePerLifetimeScope();
            }

            builder.RegisterType<Log>()
                   .As<ILog>()
                   .InstancePerLifetimeScope()
                   .IfNotRegistered(typeof(ILog));
        }