因此,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));;

请注意:


SetItemGetItem是位于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项目仅此而已。

07-24 16:52