是否存在使用DI的不良做法?在previous question中,用户提到DI应该只在UI层中使用。
答案 0 :(得分:5)
我认为你可能误解了Daren Dimitrov提供的答案。除非我弄错了,产生这个问题的界限是:“你也不应该在应用程序的业务层中创建与DI框架的依赖关系。”
我相信他所说的是应该在应用程序的最高级别创建所有依赖性信息/映射。这并不是说应用程序的所有层都不会存在依赖关系,只是较低级别不负责设置映射。
如果我的解释是正确的,那么我同意他的观点 - 在应用程序的表面设置依赖关系映射。相反,如果他说你永远不应该在较低层解决依赖,那么我将不得不反对。
答案 1 :(得分:4)
依赖注入(DI)应该无处不在。但是,请注意DI只是一组模式 - 而不是框架或库。考虑DI的最佳方式是构造函数注入启用松散耦合代码。您可以撰写DI-friendly code all the way without ever referencing a DI Container或使用Service Locator anti-pattern。
然后,想到的下一个问题是应该组成组件吗?这可能是原始语句的含义:only compose the application in the outermost layer - UI或(web)服务接口。这就是我所说的组合根。它使代码的其余部分模块化和灵活。
在Composition Root,您可以使用穷人的DI 或正确的 DI容器。我强烈建议您使用DI容器,但这不是必需的。
为了说明DI的意思,这是一个例子:
public class Foo : IFoo
{
private readonly IBar bar;
public Foo(IBar bar)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
this.bar = bar;
}
public IBaz Baz(ISnafu snafu)
{
return this.bar.Snafize(snafu).ToBaz();
}
}
IBaz实现可以在定义Foo类的完全独立的库中实现。此外,堆栈中较高的消费者不需要了解有关Foo和IBar的任何信息 - 他们只能消费IFoo:
public class MyClass : ISomeInterface
{
private readonly IFoo foo;
public MyClass(IFoo foo)
{
if (foo == null)
{
throw new ArgumentNullException("foo");
}
this.foo = foo;
}
// ...
}
这提供了松散耦合,这是DI的动机。尽可能重复。
答案 2 :(得分:3)
DI应该用于任何一个组件依赖于另一个组件的情况,无论它是UI - >商业,商业 - >数据访问或其他。我不认为它只应该用于UI,只是DI使得测试用户界面更容易,因此似乎有更多的直接好处。
答案 3 :(得分:2)
我不同意这种说法。您引用的上一个问题是不正确的,或者您误解了它。
DI当然不仅仅在UI层中。我只会同意控制器是视图层的一部分。
您可以在可以正确提供依赖关系的地方使用DI。
您是选择使用工厂还是DI解决方案。