【问题标题】:How to pass configuration parameters to SimpleInjector packaging?如何将配置参数传递给 SimpleInjector 打包?
【发布时间】:2014-09-26 06:48:57
【问题描述】:

所以 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

...那么我们如何将参数传递给包装实例?有没有办法通过容器做到这一点?

【问题讨论】:

    标签: configuration settings inversion-of-control packaging simple-injector


    【解决方案1】:

    这里的诀窍是通过容器将信息传递给包。您可以通过使用容器的 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 项目也不过如此。

    【讨论】:

      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多