依赖注入似乎是件好事。一般来说,应该在需要它们的方法中注入依赖项,还是应该在类的构造函数中注入它们?
请参阅下面的示例,以演示注入相同依赖关系的两种方法。
//Inject the dependency into the methods that require ImportantClass
Class Something {
public Something()
{
//empty
}
public void A()
{
//do something without x
}
public void B(ImportantClass x)
{
//do something with x
}
public void C(ImportantClass x)
{
//do something with x
}
}
//Inject the dependency into the constructor once
Class Something {
private ImportantClass _x
public Something(ImportantClass x)
{
this._x = x;
}
public void A()
{
//do something without x
}
public void B()
{
//do something with this._x
}
public void C()
{
//do something with this._x
}
}
答案 0 :(得分:14)
构造函数注入的主要好处是它允许将字段标记为final。例如:
class Foo {
private final Bar _bar;
Foo(Bar bar) {
_bar=bar;
}
}
以下页面列出了专业人士和骗子:Guice Best Practices:
方法注入
构造函数注入
答案 1 :(得分:3)
通过不在每个方法中注入依赖项,然后强制每个调用者知道或检索依赖项。
同样从工具的角度来看,有许多框架可用(至少在.NET中),使得构造函数注入更容易实现。这不应该影响决定,但会使其更具吸引力。
祝你好运。答案 2 :(得分:3)
如果您在方法期间注入,则不会将行为抽象与具体依赖项区分开来。这是一个很大的没有没有:)。您希望依赖于抽象,因此您不会依赖于类依赖项的依赖项。 。 。
由于您的构造函数不会出现在您的具体类支持的任何接口中,而不是您没有耦合到该依赖项。但方法调用会有这个问题。
这是一篇关于这个问题的好文章:
http://chrisdonnan.com/blog/2007/05/20/conquest-through-extreme-composition-glue-part-2/
答案 3 :(得分:2)
另一种方法是为依赖项用户设置setter。有时这与构造函数注入相结合。如果您想要更改以后使用的实现而无需重新创建实例,这将非常有用。
public interface IFoo
{
void Do();
}
public class DefaultFoo : IFoo
{
public void Do()
{
}
}
public class UsesFoo
{
private IFoo foo;
public IFoo Foo
{
set { this.foo = value; }
}
public UsesFoo()
{
this.Foo = new DefaultFoo();
}
public UsesFoo( IFoo foo )
{
this.Foo = foo;
}
public void DoFoo()
{
this.Foo.Do();
}
}
答案 4 :(得分:1)
Crazy Bob Lee表示尽可能使用构造函数注入。当您无法控制实例化时(例如在servlet中),仅使用方法注入。