马克·西曼说得对。我理解你的困惑。当我学习使用自动依赖注入容器时,我自己也经历了这个过程。问题在于,有许多有效和合理的设计和使用对象的方式,但只有其中一些方法能够与自动依赖注入容器配合工作。
我的个人经历:在学习如何使用Unity或Castle Windsor等控制反转容器之前,我就已经学习了面向对象构建和控制反转的OO原则。我养成了编写以下代码的习惯:
public class Foo
{
IService _service;
int _accountNumber;
public Foo(IService service, int accountNumber)
{
_service = service;
_accountNumber = accountNumber;
}
public void SaveAccount()
{
_service.Save(_accountNumber);
}
}
public class Program
{
public static void Main()
{
Foo foo = new Foo(new Service(),1234);
foo.Save();
}
}
在这个设计中,我的Foo类负责将账户保存到数据库中。它需要一个账户号码来完成此操作,并且需要一个服务来处理相关工作。这与您提供的具体类有些相似,每个对象在构造函数中都需要一些独特的值。当您使用自己的代码实例化对象时,这种方法很有效。您可以在适当的时间传递适当的值。
然而,当我了解到自动依赖注入容器时,我不再手动实例化Foo。容器会为我实例化构造函数的参数。这对于像IService这样的服务非常方便。但对于整数和字符串等情况,这显然并不太好。在这些情况下,它会提供默认值(例如整数的零)。相反,我习惯于传递上下文相关的值,如账户号码、名称等。因此,我不得不调整我的编码和设计风格以适应这种情况:
public class Foo
{
IService _service;
public Foo(IService service)
{
_service = service;
}
public void SaveAccount(int accountNumber)
{
_service.Save(accountNumber);
}
}
public class Program
{
public static void Main()
{
Foo foo = new Foo(new Service());
foo.Save(1234);
}
}
看起来两种Foo类的设计都是合法的。但第二种能够与自动依赖注入一起使用,而第一种则不能。
ConcurrentQueue<T>
,这也是依赖注入的有效候选吗? - Thomas