Registering IoC containers from multiple assemblies

I am trying to figure out what is best for registering objects in an ioc container from different projects of the same solution.

I have a solution with 4 projects, and I saw a solution to create installers in each of the projects, then call somtehing in one place like this:

_container = new WindsorContainer();
            var assemblyNames = new[] {"Dal", "Utils" };
            _container.Install(assemblyNames.Select(
                    x => (IWindsorInstaller)new AssemblyInstaller(Assembly.Load(x),
                        new InstallerFactory())).ToArray());

      

But I also saw a solution that creates a container in each project, and inside there is a registration of objects that belong to this particular project.

My question is, what is the best practice for this situation?

+3


source to share


3 answers


We have an example: a web solution made up of many projects: One Core and many others that reference the core. They all end up in different folders (or copied after build to the kernel / bin, if you like). At startup, we load them dynamically and then load the IWindsorInstallers from them. We load the following DLLs:

public static void LoadMoules()
{            
    string basePath = AppDomain.CurrentDomain.BaseDirectory;
    string binPath = Path.Combine(basePath, "bin");
    DirectoryInfo binFolder = new DirectoryInfo(binPath);
    IEnumerable<FileInfo> binFiles = binFolder.EnumerateFiles("*.dll", SearchOption.AllDirectories);
    Assembly[] domainAssemblies = AppDomain.CurrentDomain.GetAssemblies();
    try
    {
        foreach (var binFile in binFiles)
        {
            AssemblyName assemblyName = AssemblyName.GetAssemblyName(binFile.FullName);
            if (domainAssemblies.All(x => x.FullName != assemblyName.FullName))
            {
                Assembly.Load(assemblyName.FullName);
                Debug.WriteLine($"Loading {assemblyName.FullName}");
            }
        }
    }
    catch (Exception exception)
    {
       DynamicModuleLoaderEventSource.Log.FailedToLoadAssembly(exception.Message + exception.StackTrace);

    }    }

      

Then we get the registration:



    try
    {
        foreach(Assembly moduleAssembly in installationModules)
        {
            // satellite proejct assemblies 

            Debug.WriteLine(moduleAssembly.FullName);
            ContainerRegisterEventSource.Log.InstallAssembly(moduleAssembly.FullName);
            container.Install(FromAssembly.Instance(moduleAssembly));
        }

        container.Install(FromAssembly.This()); // the core assembly
    }
    catch(Exception exception)
    {
        ContainerRegisterEventSource.Log.Exception(exception.Message + exception.StackTrace);
        Trace.WriteLine("SetupContainerForMigrations error : " + exception.Message + Environment.NewLine + exception.StackTrace);
    }

      

By doing this, you will end up with one container with all dependencies.

0


source


I usually create one project that contains most of my shared resources such as models, libraries, and also the IoC config that I use in other projects. While configuring the IoC container from this project, I keep a few parentheses. That being said, I retain the ability to override the config from the project where you are using that config.



After all, it's all about maintainability. If you use the same dependencies across all of your projects, it would be painful to customize it from time to time for each individual project.

+1


source


Each executable project must have its own container, since it is able to work independently of other executable projects. A library project usually provides dependencies that are consumed in an executable project, and so the responsibility for executing the project to register these dependencies in its container depends on whether it wants to use them if the library does not have its own container.

Having multiple containers can lead to a lot of problems, for example if a class is registered as monochromatic (one link shared between all dependency consumers) containing multiple containers will result in multiple instances of the class being created (one per container)

It can also cause a problem if there are dependencies between projects, since the container will not be able to resolve a dependency registered in another container.

+1


source







All Articles