【问题标题】:Dependency mapping by a type of constructor parameter一种构造函数参数的依赖映射
【发布时间】:2016-10-26 03:00:01
【问题描述】:

我有多种报告类型,每种都接受某种类型的配置:

interface IConfig { ... }
interface IReport { ... }

class ConfigA : IConfig { ... }
class ConfigB : IConfig { ... }

class ReportA : IReport
{
    public ReportA (ConfigA config)
    { ... }
}

class ReportB : IReport
{
    public ReportB (ConfigB config)
    { ... }
}

如何配置 Unity 容器以通过传递的构造函数参数类型解析 IReport

var reportA = unityContainer.Resolve<IReport>(new ConfigA()); // Should be ReportA
var reportB = unityContainer.Resolve<IReport>(new ConfigB()); // Should be ReportB

我知道可以创建一种工厂,其中包含类型映射,但在这里我想依赖 Unity 并让我的对象不被容器感知。

【问题讨论】:

    标签: c# dependency-injection unity-container


    【解决方案1】:

    试试DependencyOverride:

    var reportA = unityContainer.Resolve<IReport>(new DependencyOverride<IConfig>(new ConfigA()); // Should be ReportA
    var reportB = unityContainer.Resolve<IReport>(new DependencyOverride<IConfig>(new ConfigB()); // Should be ReportB
    

    【讨论】:

    • 我应该添加哪些注册?当然,我不想为每个解决方案都更改它们。
    • @stop-cran 你可以使用任何注册。
    • 我应该如何让容器从传递的参数类型ConfigA推断类型ReportA?我可以通过其他方式进行这样的映射,但我想知道我是否可以通过配置 Unity 容器来做到这一点?因此,我只需调用 Resolve 来获取传递 ConfigA 实例的已配置容器,并将其映射到 ReportA 类型并实例化它。
    • 我现在的解决方案是引入一个字典来将配置类型映射到报告工厂方法。也许有人有更好的解决方案。
    • 最后我通过自定义注入成员完成了这项工作,请参阅我的答案。
    【解决方案2】:

    在搜索现有方法失败后,我创建了一个自定义注入成员来执行此操作 - 请参阅此 Nuget package

    首先,假设我们已经注册了两个报告:

    var unityContainer = new UnityContainer();
    
    unityContainer.RegisterType<IReport, ReportA>("ReportA");
    unityContainer.RegisterType<IReport, ReportB>("ReportB");
    

    然后我们只需将IReport 的另一个注册添加到InjectionMember

    unityContainer.RegisterType<IReport>(new InjectionConstructorLookup<IConfig>());
    

    这里的IConfig 类型参数表示我们将寻找具有单个构造函数参数的IReport-inherited 对象,继承自IConfig

    那么有两种解决IReport的方法。第一个是@Backs提到的:

    var reportA = unityContainer.Resolve<IReport>(new DependencyOverride<IConfig>(new ConfigA())); // Should be ReportA
    var reportB = unityContainer.Resolve<IReport>(new DependencyOverride<IConfig>(new ConfigB())); // Should be ReportB
    

    第二个是委托工厂:

    var factory = unityContainer.Resolve<Func<IConfig, IReport>>();
    
    var reportA1 = factory(new ConfigA()); // Should be ReportA
    var reportB1 = factory(new ConfigB()); // Should be ReportB
    

    由于结果缓存,调用工厂更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-19
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多