因此,SimpleInjector现在具有一个打包nuget,可用于隔离根组成的不同方面。
假设我在一个库中有一个可配置的合成根,该根可被应用程序中的多个项目重用。例如,在Azure解决方案中,我可能具有一个Web角色和一个Worker角色,这些角色在大多数情况下共享大量相同的依赖项,但是根据使用者的不同,配置选项也会稍有不同。当我编写根目录时,我可以传入一个普通的RootCompositionSettings
对象,该对象具有告诉SimpleInjector如何注册依赖项的属性。
但是,我不确定如何(或是否)可以将这些设置传递给IPackage
实例。是否可以将自定义设置传递给SimpleInjector包,如果可以,如何进行?
我看到注册软件包的标准做法是调用
container.RegisterPackages(); // scans all loaded assemblies for IPackage
// or
container.RegisterPackages(IEnumerable<Assembly>) // specific assemblies only
...那么我们如何将参数传递给包装实例?有什么办法可以通过容器做到这一点?
最佳答案
这里的技巧是将信息与容器一起传递给包装。您可以使用容器的Items
字典来完成此操作,这与ASP.NET的HttpContext.Items
集合非常相似。可以按以下步骤完成:
using SimpleInjector.Advanced;
container.SetItem(typeof(RootCompositionSettings), settings);
container.RegisterPackages();
现在,在包中,您可以执行以下操作:
var设置=
(RootCompositionSettings)container.GetItem(typeof(RootCompositionSettings));;
请注意:
SetItem
和GetItem
是位于SimpleInjector.Advanced
名称空间中的扩展方法。这些方法使您可以访问(内部)Items
词典。您可以传递任何您喜欢的密钥。在这种情况下,传入
typeof(RootCompositionSettings)
只是很方便,但不是必需的。如果您需要在更多位置调用设置,则创建一个更具体的扩展方法(使您可以访问设置实例)可能会很有用,但这取决于您。
另一个选择是根本不使用
IPackage
接口和SimpleInjector.Packaging库。在大多数情况下,它实际上并没有添加任何内容,您可以在程序集中简单地定义一个与包相同的公共静态方法。例如:public static class BusinessLayerBootstrapper
{
public static void Bootstrap(Container container, ScopedLifestyle scopedLifestyle,
RootCompositionSettings settings)
{
// Here the same logic as what you would write in your package.
}
}
大多数应用程序不是动态地需要动态加载程序集,并且启动项目通常对所有其他程序集具有硬引用。在那种情况下,简单地调用静态方法是完全明智的。
即使您需要动态加载程序集并允许它们在容器中注册其内容,也可以用构建自己的
IPackage
抽象来实现:// Your own IPackage interface
public interface IPackage
{
void RegisterServices(Container container, RootCompositionSettings settings);
}
// Your own extension method
public static void RegisterPackages(this Container container,
RootCompositionSettings settings)
{
var packages =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetExportedTypes()
where typeof(IPackage).IsAssignableFrom(type)
where !type.IsAbstract
select (IPackage)Activator.CreateInstance(type);
packages.ToList().ForEach(p => p.RegisterServices(container, settings));
}
实际上,除了进行一些额外的验证和滤除动态程序集之外,SimpleInjector.Packaging项目仅此而已。