这里的诀窍是通过容器将信息传递给包。您可以通过使用容器的 Items 字典来做到这一点,这很像 ASP.NET 的 HttpContext.Items 集合。这可以按如下方式完成:
using SimpleInjector.Advanced;
container.SetItem(typeof(RootCompositionSettings), settings);
container.RegisterPackages();
现在在您的包中,您可以执行以下操作:
变量设置 =
(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 项目也不过如此。