C# 从多个程序集注册IoC容器
我试图了解从一个解决方案的不同项目将对象注册到ioc容器中的最佳实践是什么 我有一个包含4个项目的解决方案,我看到了一个在每个项目中创建安装程序的解决方案,然后在一个地方调用somtehing,如下所示: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(
_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);
}