我们的所有报告都是根据从我们的域对象转换而来的对象图创建的。为了实现这一点,我们为每个报告都有一个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两次。
虽然我认识到这是一个问题,但我不一定能看到正确的解决方案。为每个班级创建工厂似乎有点奇怪...或者这是最好的方式吗?
答案 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>