- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在我的 C# 项目中使用依赖注入(inject),通常一切正常。尽管如此,我经常听到这样的规则“构造函数必须只包含微不足道的操作——分配依赖关系,什么都不做”,即:
//dependencies
interface IMyFooDependency
{
string GetBuzz();
int DoOtherStuff();
}
interface IMyBarDependency
{
void CrunchMe();
}
//consumer
class MyNiceConsumer
{
private readonly IMyFooDependency foo;
private readonly IMyBarDependency bar;
private /*readonly*/ string buzz;//<---question here
MyNiceConsumer(IMyFooDependency foo, IMyBarDependency bar)
{
//omitting null checks
this.foo = foo;
this.bar = bar;
//OR
this.buzz = foo.GetBuzz();//is this a bad thing to do?
}
}
UPD:假设 IMyFooDependency
不能替换为 GetBuzz()
,因为在那种情况下答案很明显:“做不依赖于 foo
”。
UPD2:请理解,这个问题不是关于消除假设代码中 foo 的依赖,而是关于理解良好构造函数设计的原则。
所以,我的问题如下:这真的是一个坏模式在构造函数中包含非平凡的逻辑吗(即获取buzz
值,根据依赖关系进行一些计算.)
就我个人而言,除非需要延迟加载,否则我会在构造函数中包含 foo.GetBuzz()
,因为对象需要在调用其构造函数后进行初始化。
我看到的唯一缺点:通过包含非平凡的逻辑,你会增加可能出错的地方的数量,并且你会从你的 IoC 容器中得到一个混淆的错误消息(但同样的事情会发生在无效参数的情况下, 所以缺点很小)
关于省略非平凡构造函数的任何其他注意事项?
最佳答案
如果您只需要 IMyFooDependency
来创建 buzz
,那么您实际上需要 buzz:
class MyNiceConsumer
{
private readonly IMyBarDependency bar;
private readonly string buzz;
MyNiceConsumer(string buzz, IMyBarDependency bar)
{
this.buzz = buzz;
this.bar = bar;
}
}
并以这种方式创建 nice consumer 的实例:
new MyNiceConsumer(foo.GetBuzz(), bar);
我看不出在将参数传递给构造函数之前获取 buzz 与在构造函数中获取它之间有什么区别。将从存储库返回相同的值。因此,您不需要依赖存储库。
更新:从技术上讲,构造函数中的复杂初始化逻辑没有任何问题。查看 winforms InitializeComponent
方法,其中创建、初始化所有控件并将其添加到窗体。
但它违反了SRP(创建和初始化)并且很难测试。您可以阅读有关此缺陷的更多信息 on writing testable code guide .主要思想:
Do not create collaborators in your constructor, but pass them in. (Don’t look for things! Ask for things!)
关于c# - IoC 范式中的非平凡构造函数是一件坏事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10591310/
我是一名优秀的程序员,十分优秀!