C#依赖注入和策略模式

时间:2011-04-15 06:01:26

标签: c# dependency-injection

我在MVC3项目中使用Munq作为DI容器。我有一个服务层,可以从存储库中检索DTO。根据DTO中的属性,我需要使用两种策略之一来对DTO执行计算。我可以在容器中注册一个命名类型,例如

Container.Register<ICalculation>("Type1", c => new Type1Calculation);
Container.Register<ICalculation>("Type2", c => new Type2Calculation);

然后我可以在尝试实例化适当的策略时直接引用容器,例如

var calc = Container.Resolve<ICalculation>(dto.ServiceType);

但这让我依赖于容器本身以及相关的耦合和测试问题。我需要传递给服务构造函数,这将允许我获得正确的计算,但不依赖于容器?我是否应该传入工厂,因此依赖项是在工厂而不是在服务类中?

2 个答案:

答案 0 :(得分:5)

不确定Munq,但Autofac允许您传递Func s,以便您可以完全跳过所有工厂:

public class Foo
{
    public Foo(Func<string, IBar> barFactory) { }
}

检查Munq是否允许这种行为。

否则 - 是的,你将不得不诉诸手写工厂来提供另一层次的间接。

答案 1 :(得分:0)

我已经为此添加了Munq解决方案。首先包含 IDependencyResolver 接口的工厂允许工厂使用容器来解析工厂方法中的依赖关系:

public class CalculationFactory
{
    private readonly IDependencyResolver _resolver;
    public CalculationFactory(IDependencyResolver resolver)
    {
        ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
        _resolver = resolver;
    }

    public static ICalculation CreateCalculator(int serviceType)
    {
        switch (serviceType)
        {
            case 1: return _resolver.Resolve<ICalculation>("Type1");
            case 2: return _resolver.Resolve<ICalculation>("Type2");
            default: return _resolver.Resolve<ICalculation>("InvalidType");
        }
    }
}

然后在Global.asax.cs中注册相应的接口/类,将容器传递给工厂。所以现在我可以设置我的测试,并且工厂内唯一的额外依赖是 IDependencyResolver

ioc.Register(c => new CalculationFactory(c));
ioc.Register<ICalculation>("Type1", c => c.Resolve<Type1Calculation>());
ioc.Register<ICalculation>("Type2", c => c.Resolve<Type2Calculation>());
ioc.Register<ICalculation>("InvalidType", c => c.Resolve<InvalidCalculation>());