C# 通过构造函数在IoC中实施依赖关系?
我试图接受使用IoC/依赖注入,同时编程到契约而不是特定类。我面临的困境是:C# 通过构造函数在IoC中实施依赖关系?,c#,interface,dependency-injection,inversion-of-control,abstract-class,C#,Interface,Dependency Injection,Inversion Of Control,Abstract Class,我试图接受使用IoC/依赖注入,同时编程到契约而不是特定类。我面临的困境是: 为IoC编写接口程序:我开始时IoC非常依赖接口。从Spring的示例项目来看,接口是与IoC签订合同进行编程时的必经之路 (…虽然抽象类通常更受欢迎:) 通过构造函数明确类依赖关系 我的直觉是,将依赖项传递给类的构造函数是一种很好的编程实践。事实上,这就是依赖注入 。。。除非您不能在接口/抽象类中强制构造函数签名:接口或抽象类都不允许定义构造函数签名。 另请参见不要在抽象类型中定义公共或受保护的内部构造函数。。。只有
Edit2:谢谢你的回答,非常有帮助。你的IoC容器必须从一个具体类型构造一个对象,即使你传递的是一个接口。构造函数不是行为或状态契约,因此它不属于接口或抽象类的公共成员
构造函数是一种实现细节,因此不需要将其定义与具体类分开。不能在接口中定义构造函数签名。无论如何,这是没有意义的,因为接口不应该强制执行实现的构造方式 但是抽象类确实可以有构造函数。它们必须得到保护,因为公共构造函数也没有意义。它们只能由具体的子类调用 IoC原则规定,您不应该让类A了解并实例化类B,而应该将对IB的引用传递给A的构造函数。这样,A就不需要了解类B,因此您可以轻松地用IB的其他实现替换类B
因为您正在传入一个已经实例化的类B对象,所以IB接口不需要有构造函数签名 我一直认为用一个(虚构的)例子来解释这一点更容易 假设您有一个ICustomerRepository接口、一个IShoppingCartRepository接口和一个ICheckout接口。您有这些接口的具体实现—CustomerRepository、ShoppingCartRepository和CheckoutService 您的CheckoutService具体类有一个构造函数,它接受ICCustomerRepository和IShoppingCartRepository,例如
public CheckoutService(ICustomerRepository customerRepository, IShoppingCartRepository shoppingCartRepository)
{
// Set fields for use in some methods later...
_customerRepository = customerRepository;
_shoppingCartRepository = shoppingCartRepository;
}
然后,当您希望ICheckoutService实现执行一些工作时,您可以告诉IoC容器它应该为每个接口类型使用哪个具体类,并要求它构建ICheckoutService。IoC容器将为您构建类,将正确的具体类注入CheckoutService的构造函数中。它还将构建从类继承权一直到类继承权的依赖关系,因此,例如,如果ShoppingCartRepository在构造函数中采用IDatabaseSession接口,那么只要您告诉IoC容器要将哪个具体类用于IDatabaseService,IoC容器也将注入该依赖关系
以下是一些在配置(例如)为IoC容器时可能使用的代码(此代码通常在应用程序启动时调用):
公共类权限:注册表
{
公共评估学()
{
ForRequestedType()。默认的ConcreteType();
ForRequestedType()。默认的ConcreteType();
//等等。。。
}
}
然后,要构建ICheckoutService实例并准备就绪,并将所有依赖项传递到构造函数中,您可以使用以下方法:
var checkoutService = ObjectFactory.GetInstance<ICheckoutService>();
var checkoutService=ObjectFactory.GetInstance();
我希望这是有道理的 啊哈!因此,我可以继续使用构造函数参数来明确依赖关系,同时对契约进行编程。但是让IoC容器担心如何正确注入这些依赖项。谢谢,这完全澄清了这一点。
var checkoutService = ObjectFactory.GetInstance<ICheckoutService>();