Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从多个程序集注册IoC容器_C#_.net_Inversion Of Control_Castle Windsor_Ioc Container - Fatal编程技术网

C# 从多个程序集注册IoC容器

C# 从多个程序集注册IoC容器,c#,.net,inversion-of-control,castle-windsor,ioc-container,C#,.net,Inversion Of Control,Castle Windsor,Ioc Container,我试图了解从一个解决方案的不同项目将对象注册到ioc容器中的最佳实践是什么 我有一个包含4个项目的解决方案,我看到了一个在每个项目中创建安装程序的解决方案,然后在一个地方调用somtehing,如下所示: _container = new WindsorContainer(); var assemblyNames = new[] {"Dal", "Utils" }; _container.Install(assemblyNames.Select(

我试图了解从一个解决方案的不同项目将对象注册到ioc容器中的最佳实践是什么

我有一个包含4个项目的解决方案,我看到了一个在每个项目中创建安装程序的解决方案,然后在一个地方调用somtehing,如下所示:

_container = new WindsorContainer();
            var assemblyNames = new[] {"Dal", "Utils" };
            _container.Install(assemblyNames.Select(
                    x => (IWindsorInstaller)new AssemblyInstaller(Assembly.Load(x),
                        new InstallerFactory())).ToArray());
但我也看到了一个解决方案,在每个项目中,都有一个容器的创建,其中有一个与这个特定项目相关的对象的注册


我的问题是:对于这种情况,什么是最佳实践?

通常我创建一个项目,其中包含我在其他项目中使用的大多数共享资源,如模型、库和IoC配置。通过从这个项目配置IoC容器,我节省了一些复制粘贴。这样,我就有可能覆盖使用此配置的项目中的配置


最后,这一切都是关于可维护性的。如果您在所有项目中都使用相同的依赖项,那么为每个单独的项目一次又一次地配置它将是一件痛苦的事情。

每个可执行项目都应该有自己的容器,因为它们能够独立于其他可执行项目运行。库项目通常提供在可执行项目中使用的依赖项,因此,如果要在库没有自己的容器的情况下使用这些依赖项,可执行项目有责任在其容器中注册这些依赖项

拥有多个容器可能会导致各种问题,例如,如果一个类注册为单例(依赖项的所有使用者共享一个引用),拥有多个容器将导致创建多个类实例(每个容器中一个)


如果存在跨项目依赖关系,也可能会导致问题,因为容器无法解析在另一个容器中注册的依赖关系。

我们这里有一个示例:一个web解决方案,由多个项目组成:一个核心项目和多个引用核心项目的其他项目。所有这些文件最终都会放在不同的文件夹中(如果您愿意,也可以在构建后复制到核心/bin)。在开始时,我们动态加载它们,然后从中加载iwindsorInstaller。我们加载DLL的方式如下:

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);

    }    }
这样做,您将得到一个包含所有依赖项的容器

    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);
    }