马克·西曼做对了。我同情你的困惑。当我学会使用自动依赖注入容器时,我自己经历过。问题是有许多有效和合理的方法来设计和使用对象。然而,只有其中一些方法适用于自动依赖注入容器。
我的个人经历:早在我学会如何使用 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 类都是有效的设计。但是第二个可用于自动依赖注入,而第一个则不能。