我正在尝试接受使用 IoC/依赖注入(inject),同时根据契约(Contract)而不是特定类进行编程。我面临的困境是:
为 IoC 的接口(interface)编写程序:我开始时 IoC 非常依赖接口(interface)。从 Spring 的示例项目来看,接口(interface)是使用 IoC 进行契约编程的方式。
( ... 尽管通常首选抽象类:the main drawback of interfaces is that they are much less flexible than classes when it comes to allowing for evolution of APIs )
通过构造函数使类依赖显式化 我的直觉是,将依赖项传递给类的构造函数是一种很好的编程习惯。事实上,这是依赖注入(inject)。
...除非您不能在接口(interface)/抽象类中强制执行构造函数签名:接口(interface)或抽象类都不允许定义构造函数签名( easily / elegantly ) . 另见 Framework Design Guidelines section 4.4: 不要在抽象类型中定义公共(public)或 protected 内部构造函数。 ...仅当用户需要创建该类型的实例时,构造函数才应公开。
这个问题与之前的 stackoverflow 问题有关:Interface defining a constructor signature?
但我的问题是:
由于您不能在 C# 接口(interface)/抽象类中定义构造函数,正如上面的问题所问,在实际层面上:
您如何将此与 passing dependencies in via a constructor 的明智做法相协调? ?
编辑:感谢您的回答。我希望了解在这种情况下我应该做什么。只是不使用构造函数参数?使用某种确实采用依赖项的 Init() 方法? Edit2:感谢您的出色回答,非常有帮助。
最佳答案
我一直认为用(编造的)示例更容易解释...
假设您有一个 ICustomerRepository 接口(interface)、一个 IShoppingCartRepository 接口(interface)和一个 ICheckout 接口(interface)。您具有这些接口(interface)的具体实现 - CustomerRepository、ShoppingCartRepository 和 CheckoutService。
您的 CheckoutService 具体类有一个采用 ICustomerRepository 和 IShoppingCartRepository 的构造函数 - 例如
public CheckoutService(ICustomerRepository customerRepository, IShoppingCartRepository shoppingCartRepository)
{
// Set fields for use in some methods later...
_customerRepository = customerRepository;
_shoppingCartRepository = shoppingCartRepository;
}
然后,当您希望 ICheckoutService 实现执行一些工作时,您告诉 IoC 容器它应该为每种接口(interface)类型使用哪个具体类,并要求它为您构建一个 ICheckoutService。您的 IoC 容器将为您构建类,将正确的具体类注入(inject) CheckoutService 的构造函数。它还将在此处沿类层次结构一直构建依赖项,因此,例如,如果您的 ShoppingCartRepository 在构造函数中采用 IDatabaseSession 接口(interface),那么只要您告诉它要使用哪个具体类,您的 IoC 容器也会注入(inject)该依赖项为您的 IDatabaseService。
以下是您在配置时可能会用到的一些代码(例如)StructureMap作为您的 IoC 容器(此代码通常会在应用程序启动期间调用):
public class AppRegistry : Registry
{
public AppRegistry()
{
ForRequestedType<ICheckoutService>().TheDefaultIsConcreteType<CheckoutService>();
ForRequestedType<ICustomerRepository>().TheDefaultIsConcreteType<CustomerRepository>();
// etc...
}
}
然后为了获得 ICheckoutService 的实例并准备好运行,将所有依赖项传递给您的构造函数,您可以使用如下内容:
var checkoutService = ObjectFactory.GetInstance<ICheckoutService>();
我希望这是有道理的!
关于c# - 通过构造函数在 IoC 中强制执行依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/756541/