对需要参数的对象的依赖注入

时间:2010-04-03 23:36:30

标签: c# dependency-injection

我们的所有报告都是根据从我们的域对象转换而来的对象图创建的。为了实现这一点,我们为每个报告都有一个Translator类,并且一直使用依赖注入来传递依赖关系。

这很好用,并且会产生这样结构很好的类:

public class CheckTranslator : ICheckTranslator
{
   public CheckTranslator (IEmployeeService empSvc
                         , IPaycheckService paySvc)
   {
      _empSvc = empSvc;
      _paySvc = paySvc;
   }

   public Check CreateCheck()
   {
      //do the translation...
   }
}

但是,在某些情况下,映射有许多不同的分组选项。结果,c-tor将变成类依赖关系和参数的混合。

public class CheckTranslator : ICheckTranslator
{
   public CheckTranslator (IEmployeeService empSvc
                         , IPaycheckService paySvc
                         , bool doTranslateStubData
                         , bool doAttachLogo)
   {
      _empSvc = empSvc;
      _paySvc = paySvc;
      _doTranslateStubData = doTranslateStubData;
      _doAttachLogo = doAttachLogo;
   }

   public Check CreateCheck()
   {
      //do the translation...
   }
}  

现在,我们仍然可以测试它,但它不再适用于IoC容器,至少以干净的方式。另外,如果每次检查的设置不同,我们就不能再调用CreateCheck两次。

虽然我认识到这是一个问题,但我不一定能看到正确的解决方案。为每个班级创建工厂似乎有点奇怪...或者这是最好的方式吗?

1 个答案:

答案 0 :(得分:13)

在黑暗中拍摄,但是你可以将这些参数移到方法中吗?

换句话说:

public Check CreateCheck(bool doTranslateStubData, bool doAttachLogo)
{
   //do the translation...
}

这些参数是否已通过构造函数传递

(注意 - 如果您对此的回答是“有太多方法可以实现”,那么部分问题可能是抽象太粗糙了。)


另一个选择(如果不了解域模型和注入模式,很难说)将引入一个本身由注入器管理的参数对象:

public interface ICheckConfiguration
{
    bool AttachLogo { get; }
    bool TranslateStubData { get; }
}

然后使用构造函数注入:

public CheckTranslator (IEmployeeService empSvc, IPaycheckService paySvc,
    ICheckConfiguration config)
{
    // etc.
}   

这个应该就足够了。然后,您可以创建一个具体的CheckConfiguration类,在其构造函数中获取这两个bool属性,并配置容器以基于更高级别的DI参数创建参数对象(接口)的不同实例。


我认为我应该提到的最后一件事是,仅仅因为你使用DI并不意味着所有必须由容器管理。如果只有一种“翻译者”,那么以临时方式创建CheckTranslator个对象并不是一件坏事。只要译者仍然依赖抽象,它就在这里,那么也许你根本不应该注入它,只需让更高级别的DI启用它们来创建它们。 / p>