protected override void Load()

in edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/modules/AgentModule.cs [145:349]


        protected override void Load(ContainerBuilder builder)
        {
            // ISerde<ModuleSet>
            builder.Register(
                    c => new ModuleSetSerde(
                        new Dictionary<string, Type>
                        {
                            { DockerType, typeof(DockerModule) }
                        }))
                .As<ISerde<ModuleSet>>()
                .SingleInstance();

            // ISerde<DeploymentConfig>
            builder.Register(
                    c =>
                    {
                        ISerde<DeploymentConfig> serde = new TypeSpecificSerDe<DeploymentConfig>(DeploymentConfigTypeMapping);
                        return serde;
                    })
                .As<ISerde<DeploymentConfig>>()
                .SingleInstance();

            // ISerde<DeploymentConfigInfo>
            builder.Register(
                    c =>
                    {
                        ISerde<DeploymentConfigInfo> serde = new TypeSpecificSerDe<DeploymentConfigInfo>(DeploymentConfigTypeMapping);
                        return serde;
                    })
                .As<ISerde<DeploymentConfigInfo>>()
                .SingleInstance();

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

            // IRocksDbOptionsProvider
            // For EdgeAgent, we don't need high performance from RocksDb, so always turn off optimizeForPerformance
            builder
                .Register(c => new RocksDbOptionsProvider(
                    c.Resolve<ISystemEnvironment>(),
                    false,
                    this.storageTotalMaxWalSize,
                    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();
            }

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

                        if (this.usePersistentStorage)
                        {
                            // Create partition for mma
                            var partitionsList = new List<string> { "moduleState", "deploymentConfig" };
                            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 (!ExceptionEx.IsFatal(ex))
                            {
                                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<IStoreProvider>
            builder.Register(async c =>
            {
                var dbStoreProvider = await c.Resolve<Task<IDbStoreProvider>>();
                IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                return storeProvider;
            })
            .As<Task<IStoreProvider>>()
            .SingleInstance();

            // IEntityStore<string, ModuleState>
            builder.Register(async c =>
                {
                    IStoreProvider storeProvider = await c.Resolve<Task<IStoreProvider>>();
                    return storeProvider.GetEntityStore<string, ModuleState>("moduleState");
                })
                .As<Task<IEntityStore<string, ModuleState>>>()
                .SingleInstance();

            // IEntityStore<string, DeploymentConfigInfo>
            builder.Register(async c =>
                {
                    IStoreProvider storeProvider = await c.Resolve<Task<IStoreProvider>>();
                    return storeProvider.GetEntityStore<string, string>("deploymentConfig");
                })
                .As<Task<IEntityStore<string, string>>>()
                .SingleInstance();

            // IRestartManager
            builder.Register(c => new RestartPolicyManager(this.maxRestartCount, this.coolOffTimeUnitInSeconds))
                .As<IRestartPolicyManager>()
                .SingleInstance();

            // IPlanner
            builder.Register(
                    async c =>
                    {
                        var commandFactory = c.Resolve<Task<ICommandFactory>>();
                        var entityStore = c.Resolve<Task<IEntityStore<string, ModuleState>>>();
                        var policyManager = c.Resolve<IRestartPolicyManager>();

                        return new HealthRestartPlanner(await commandFactory, await entityStore, this.intensiveCareTime, policyManager) as IPlanner;
                    })
                .As<Task<IPlanner>>()
                .SingleInstance();

            // IPlanRunner
            builder.Register(c => new OrderedRetryPlanRunner(this.maxRestartCount, this.coolOffTimeUnitInSeconds, SystemTime.Instance))
                .As<IPlanRunner>()
                .SingleInstance();

            // IEncryptionDecryptionProvider
            builder.Register(
                    async c =>
                    {
                        IEncryptionProvider provider = await this.workloadUri.Map(
                            async uri =>
                            {
                                IEncryptionProvider encryptionProvider = await EncryptionProvider.CreateAsync(
                                    this.storagePath,
                                    uri,
                                    this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")),
                                    Constants.EdgeletClientApiVersion,
                                    this.moduleId,
                                    this.moduleGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                                    Constants.EdgeletInitializationVectorFileName);
                                return encryptionProvider;
                            }).GetOrElse(() => Task.FromResult<IEncryptionProvider>(NullEncryptionProvider.Instance));

                        return provider;
                    })
                .As<Task<IEncryptionProvider>>()
                .SingleInstance();

            // IAvailabilityMetric
            builder.Register(c => new DeploymentMetrics(c.Resolve<IMetricsProvider>(), this.storagePath))
                .As<IDeploymentMetrics>()
                .SingleInstance();

            // Task<Agent>
            builder.Register(
                    async c =>
                    {
                        var configSource = c.Resolve<Task<IConfigSource>>();
                        var environmentProvider = c.Resolve<Task<IEnvironmentProvider>>();
                        var planner = c.Resolve<Task<IPlanner>>();
                        var planRunner = c.Resolve<IPlanRunner>();
                        var reporter = c.Resolve<IReporter>();
                        var moduleIdentityLifecycleManager = c.Resolve<IModuleIdentityLifecycleManager>();
                        var deploymentConfigInfoSerde = c.Resolve<ISerde<DeploymentConfigInfo>>();
                        var deploymentConfigInfoStore = await c.Resolve<Task<IEntityStore<string, string>>>();
                        var encryptionProvider = c.Resolve<Task<IEncryptionProvider>>();
                        var availabilityMetric = c.Resolve<IDeploymentMetrics>();
                        return await Agent.Create(
                            await configSource,
                            await planner,
                            planRunner,
                            reporter,
                            moduleIdentityLifecycleManager,
                            await environmentProvider,
                            deploymentConfigInfoStore,
                            deploymentConfigInfoSerde,
                            await encryptionProvider,
                            availabilityMetric);
                    })
                .As<Task<Agent>>()
                .SingleInstance();

            base.Load(builder);
        }