Search code examples
c#dynamicinitializationautofacconfiguration-files

How to load dynamically Autofac configuration to initialize


I have two ways of execute a program (console), as client calling services or as server calling its own local services. In the first way Autofac initialization is very fast cause only registers two modules, the server way it's slower because Autofac must intialize all server modules (more than 1 minute). The way of executing depends on a param of the console.

Waiting for a better solution I've implemented it on the Console Module, loading the server modules when it's necessary, but it's a bit hardcoded (extracting modules and configurations/properties from files), because I've configured them mixing files and modules (samples below) and I would keep the configuration on files.

I would like to select dynamically the file:

<autofac configSource="autofac-client.config" />

or

<autofac configSource="autofac-server.config" />

CODE:

autofac-client.config:

<autofac defaultAssembly="Console1">
    <files>
        <file name=".\BaseSettings\ClientServices.config" section="clientServices" />
    </files>
    <modules>
        <module type="Console1.AutofacModules.ComponentModule, Console1" />
    </modules>
</autofac>

autofac-server.config:

<autofac defaultAssembly="Console1">
    <files>
        <file name=".\BaseSettings\ClientServices.config" section="clientServices" />
        <file name=".\BaseSettings\AutofacRegistrationModules.config" section="AutofacRegistrationModules" />
    </files>
    <modules>
        <module type="assembly1.AutofacModules.ComponentModule, assembly1" />
        <module type="assembly2.AutofacModules.PrintManagerModule, assembly2" />
        <module type="assembly3.AutofacModules.ComponentModule, assembly3" />
        <module type="assembly4.AutofacModules.FormEngineServicesComponentModule, assembly4" />
        <module type="assembly5.ReportManagerServicesComponentModule, assembly5" />
        <module type="assembly6.NHibernateComponentModule, assembly6">
            <properties>
                <property name="DatabaseConfigurationSectionName" value="databaseSettingsEClient" />
            </properties>
        </module>
        <module type="assembly7.AutofacModules.ComponentModule, assembly7" />
        <module type="assembly8.AutofacModules.ComponentModule, assembly8" />
        <module type="assembly9.AutofacModules.ComponentModule, assembly9" />
        <module type="Console1.AutofacModules.ComponentModule, Console1" />
    </modules>
</autofac>

As you can see, there's a lot of configuration to replicate on code using builder.RegisterModule.


Solution

  • Finally I've used the method builder.RegisterModule to register the modules:

        protected override void Load(ContainerBuilder builder)
        {
            ...
            bool executeLocal = false;
            var executeLocalObj = Thread.GetData(Thread.GetNamedDataSlot("ExecuteLocal"));
            if (executeLocalObj != null)
            {
                executeLocal = (bool)executeLocalObj;
            }
            if (executeLocal)
            {
                builder.RegisterModule(new mpm.seg.Common.Database.AutofacModules.NHibernateComponentModule());
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly1.ComponentModule, assembly1")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly2.AutofacModules.ComponentModule, assembly1")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly3.AutofacModules.ComponentModule, assembly3")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly4.AutofacModules.ComponentModule, assembly4")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly5.AutofacModules.ComponentModule, assembly5")) as IModule);
                builder.RegisterModule(new assembly6.AutofacModules.NHibernateComponentModule() { DatabaseConfigurationSectionName = "databaseSettings" });
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly7.AutofacModules.ComponentModule, assembly7")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly8.AutofacModules.ComponentModule, assembly8")) as IModule);
                builder.RegisterModule(Activator.CreateInstance(Type.GetType("assembly9.AutofacModules.ComponentModule, assembly9")) as IModule);
            }
        }
    

    Where executeLocal is a flag sent to Load through Data of the Thread:

    Thread.SetData(Thread.GetNamedDataSlot("ExecuteLocal"), executeLocal);