protected override void Load()

in edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.Service/modules/CommonModule.cs [115:487]


        protected override void Load(ContainerBuilder builder)
        {
            // IMetricsListener
            builder.Register(
                    c =>
                        this.metricsConfig.Enabled
                            ? new MetricsListener(this.metricsConfig.ListenerConfig, c.Resolve<IMetricsProvider>())
                            : new NullMetricsListener() as IMetricsListener)
                .As<IMetricsListener>()
                .SingleInstance();

            // IMetricsProvider
            builder.Register(
                    c =>
                        this.metricsConfig.Enabled
                            ? new MetricsProvider(MetricsConstants.EdgeHubMetricPrefix, this.iothubHostName, this.edgeDeviceId, this.metricsConfig.HistogramMaxAge)
                            : new NullMetricsProvider() as IMetricsProvider)
                .As<IMetricsProvider>()
                .SingleInstance();

            // ISignatureProvider
            builder.Register(
                    c =>
                    {
                        ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                                cs =>
                                {
                                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                                    return new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider;
                                })
                            .GetOrElse(
                                () =>
                                {
                                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                                    string workloadUri = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                                    string workloadApiVersion = this.workloadApiVersion.Expect(() => new InvalidOperationException("workloadUri version is missing"));
                                    return new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, workloadApiVersion, Constants.WorkloadApiVersion) as ISignatureProvider;
                                });
                        return signatureProvider;
                    })
                .As<ISignatureProvider>()
                .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
                .As<ISystemEnvironment>()
                .SingleInstance();

            // DataBase options
            builder
                .Register(c => new RocksDbOptionsProvider(
                    c.Resolve<ISystemEnvironment>(),
                    this.optimizeForPerformance,
                    this.storageMaxTotalWalSize,
                    this.storageMaxManifestFileSize,
                    this.storageMaxOpenFiles,
                    this.storageLogLevel))
                .As<IRocksDbOptionsProvider>()
                .SingleInstance();

            if (!this.usePersistentStorage && this.useBackupAndRestore)
            {
                // Backup and restore serialization
                builder.Register(c => new ProtoBufDataBackupRestore())
                    .As<IDataBackupRestore>()
                    .SingleInstance();
            }

            // IStorageSpaceChecker
            builder.Register(
                c =>
                {
                    IStorageSpaceChecker spaceChecker = !this.usePersistentStorage
                       ? new MemorySpaceChecker(() => 0L) as IStorageSpaceChecker
                       : new NullStorageSpaceChecker();
                    return spaceChecker;
                })
                .As<IStorageSpaceChecker>()
                .SingleInstance();

            // IDbStoreProvider
            builder.Register(
                    async c =>
                    {
                        var loggerFactory = c.Resolve<ILoggerFactory>();
                        ILogger logger = loggerFactory.CreateLogger(typeof(RoutingModule));

                        if (this.usePersistentStorage)
                        {
                            // Create partitions for messages and twins
                            var partitionsList = new List<string> { Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey };
                            try
                            {
                                IDbStoreProvider dbStoreProvider = DbStoreProvider.Create(
                                    c.Resolve<IRocksDbOptionsProvider>(),
                                    this.storagePath,
                                    partitionsList);
                                logger.LogInformation($"Created persistent store at {this.storagePath}");
                                return dbStoreProvider;
                            }
                            catch (Exception ex) when (!ex.IsFatal())
                            {
                                logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                                IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                                return dbStoreProvider;
                            }
                        }
                        else
                        {
                            logger.LogInformation($"Using in-memory store");
                            IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                            return dbStoreProvider;
                        }
                    })
                .As<Task<IDbStoreProvider>>()
                .SingleInstance();

            // Task<Option<IEncryptionProvider>>
            builder.Register(
                    async c =>
                    {
                        Option<IEncryptionProvider> encryptionProviderOption = await this.workloadUri
                            .Map(
                                async uri =>
                                {
                                    var encryptionProvider = await EncryptionProvider.CreateAsync(
                                        this.storagePath,
                                        new Uri(uri),
                                        this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")),
                                        Constants.WorkloadApiVersion,
                                        this.edgeHubModuleId,
                                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                                        Constants.InitializationVectorFileName) as IEncryptionProvider;
                                    return Option.Some(encryptionProvider);
                                })
                            .GetOrElse(() => Task.FromResult(Option.None<IEncryptionProvider>()));
                        return encryptionProviderOption;
                    })
                .As<Task<Option<IEncryptionProvider>>>()
                .SingleInstance();

            // Task<IStoreProvider>
            builder.Register(async c =>
                {
                    var dbStoreProvider = await c.Resolve<Task<IDbStoreProvider>>();
                    IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                    return storeProvider;
                })
                .As<Task<IStoreProvider>>()
                .SingleInstance();

            // Task<IMetadataStore>
            builder.Register(
                    async c =>
                    {
                        var storeProvider = await c.Resolve<Task<IStoreProvider>>();
                        IKeyValueStore<string, string> entityStore = storeProvider.GetEntityStore<string, string>("ProductInfo", "MetadataStore");
                        IMetadataStore metadataStore = new MetadataStore(entityStore, this.productInfo);
                        return metadataStore;
                    })
                .As<Task<IMetadataStore>>()
                .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ClientTokenProvider(c.Resolve<ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
                .Named<ITokenProvider>("EdgeHubClientAuthTokenProvider")
                .SingleInstance();

            // ITokenProvider
            builder.Register(
                    c =>
                    {
                        string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                        string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                        return new ClientTokenProvider(c.Resolve<ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1));
                    })
                .Named<ITokenProvider>("EdgeHubServiceAuthTokenProvider")
                .SingleInstance();

            builder.Register(
                    c =>
                    {
                        var loggerFactory = c.Resolve<ILoggerFactory>();
                        var logger = loggerFactory.CreateLogger<RoutingModule>();
                        return Proxy.Parse(this.proxy, logger);
                    })
                .As<Option<IWebProxy>>()
                .SingleInstance();

            // IServiceIdentityHierarchy
            builder.Register<IServiceIdentityHierarchy>(
                    c =>
                    {
                        if (this.nestedEdgeEnabled)
                        {
                            return new ServiceIdentityTree(this.edgeDeviceId);
                        }
                        else
                        {
                            return new ServiceIdentityDictionary(this.edgeDeviceId);
                        }
                    })
                .As<IServiceIdentityHierarchy>()
                .SingleInstance();

            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                    async c =>
                    {
                        IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                        if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                        {
                            var edgeHubTokenProvider = c.ResolveNamed<ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                            var proxy = c.Resolve<Option<IWebProxy>>();

                            IServiceIdentityHierarchy serviceIdentityHierarchy = c.Resolve<IServiceIdentityHierarchy>();

                            string hostName = this.gatewayHostName.GetOrElse(this.iothubHostName);
                            IDeviceScopeApiClientProvider securityScopesApiClientProvider = new DeviceScopeApiClientProvider(hostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider, serviceIdentityHierarchy, proxy);
                            IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClientProvider, this.nestedEdgeEnabled);
                            IKeyValueStore<string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache");
                            deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceIdentityHierarchy, serviceProxy, encryptedStore, this.scopeCacheRefreshRate, this.scopeCacheRefreshDelay);
                        }
                        else
                        {
                            deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                        }

                        return deviceScopeIdentitiesCache;
                    })
                .As<Task<IDeviceScopeIdentitiesCache>>()
                .AutoActivate()
                .SingleInstance();

            // IRegistryApiClient
            builder.Register(
                    c =>
                    {
                        string upstreamHostname = this.gatewayHostName.GetOrElse(this.iothubHostName);
                        var proxy = c.Resolve<Option<IWebProxy>>();
                        var edgeHubTokenProvider = c.ResolveNamed<ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                        return new RegistryOnBehalfOfApiClient(upstreamHostname, proxy, edgeHubTokenProvider);
                    })
                .As<IRegistryOnBehalfOfApiClient>()
                .SingleInstance();

            // Task<ICredentialsCache>
            builder.Register(
                    async c =>
                    {
                        ICredentialsCache underlyingCredentialsCache;
                        if (this.persistTokens)
                        {
                            IKeyValueStore<string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache");
                            return new PersistedTokenCredentialsCache(encryptedStore);
                        }
                        else
                        {
                            underlyingCredentialsCache = new NullCredentialsCache();
                        }

                        ICredentialsCache credentialsCache;

                        if (this.nestedEdgeEnabled)
                        {
                            credentialsCache = new NestedCredentialsCache(underlyingCredentialsCache);
                        }
                        else
                        {
                            credentialsCache = new CredentialsCache(underlyingCredentialsCache);
                        }

                        return credentialsCache;
                    })
                .As<Task<ICredentialsCache>>()
                .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(
                    async c =>
                    {
                        IAuthenticator tokenAuthenticator;
                        IAuthenticator certificateAuthenticator;
                        IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                        var credentialsCacheTask = c.Resolve<Task<ICredentialsCache>>();
                        // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped
                        deviceScopeIdentitiesCache = await c.Resolve<Task<IDeviceScopeIdentitiesCache>>();
                        certificateAuthenticator = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true, this.nestedEdgeEnabled);
                        switch (this.authenticationMode)
                        {
                            case AuthenticationMode.Cloud:
                                tokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                                break;

                            case AuthenticationMode.Scope:
                                tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true, this.nestedEdgeEnabled);
                                break;

                            default:
                                IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                                tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true, this.nestedEdgeEnabled);
                                break;
                        }

                        ICredentialsCache credentialsCache = await credentialsCacheTask;
                        return new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator;
                    })
                .As<Task<IAuthenticator>>()
                .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(c.Resolve<IIdentityProvider>(), this.productInfo))
                .As<IClientCredentialsFactory>()
                .SingleInstance();

            // IClientCredentials "EdgeHubCredentials"
            builder.Register(
                    c =>
                    {
                        var identityFactory = c.Resolve<IClientCredentialsFactory>();
                        IClientCredentials edgeHubCredentials = this.edgeHubConnectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse(
                            () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeHubModuleId));
                        return edgeHubCredentials;
                    })
                .Named<IClientCredentials>("EdgeHubCredentials")
                .SingleInstance();

            // ServiceIdentity "EdgeHubIdentity"
            builder.Register(
                    c =>
                    {
                        return new ServiceIdentity(
                            this.edgeDeviceId,
                            this.edgeHubModuleId,
                            deviceScope: null,
                            parentScopes: new List<string>(),
                            this.edgeHubGenerationId.GetOrElse("0"),
                            capabilities: new List<string>(),
                            new ServiceAuthentication(ServiceAuthenticationType.None),
                            ServiceIdentityStatus.Enabled);
                    })
                .Named<ServiceIdentity>("EdgeHubIdentity")
                .SingleInstance();

            // ConnectionReauthenticator
            builder.Register(
                    async c =>
                    {
                        var edgeHubCredentials = c.ResolveNamed<IClientCredentials>("EdgeHubCredentials");
                        var connectionManagerTask = c.Resolve<Task<IConnectionManager>>();
                        var authenticatorTask = c.Resolve<Task<IAuthenticator>>();
                        var credentialsCacheTask = c.Resolve<Task<ICredentialsCache>>();
                        var deviceScopeIdentitiesCacheTask = c.Resolve<Task<IDeviceScopeIdentitiesCache>>();
                        var deviceConnectivityManager = c.Resolve<IDeviceConnectivityManager>();
                        IConnectionManager connectionManager = await connectionManagerTask;
                        IAuthenticator authenticator = await authenticatorTask;
                        ICredentialsCache credentialsCache = await credentialsCacheTask;
                        IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                        var connectionReauthenticator = new ConnectionReauthenticator(
                            connectionManager,
                            authenticator,
                            credentialsCache,
                            deviceScopeIdentitiesCache,
                            TimeSpan.FromMinutes(5),
                            edgeHubCredentials.Identity,
                            deviceConnectivityManager);
                        return connectionReauthenticator;
                    })
                .As<Task<ConnectionReauthenticator>>()
                .SingleInstance();

            base.Load(builder);
        }