我是 .NET C# 和 autofac 中 DI 的新手,当我无法完全控制调用方时,我很难理解如何使用 DI。
有两种情况我很难理解。
场景 1:调用者期望一个默认构造函数(不带任何参数)
在构造类的时候还想注入(inject)一些Service Interface怎么办?我在考虑构造函数链接,但这意味着我必须知 Prop 体类型并且它围绕 DI 的想法工作。 (至少我认为)。
public class ServiceWorker
{
IService _service;
public ServiceWorker(IService service)
{
_service = service
}
}
public class Caller
{
// No way to change this.
var serviceWorker = new ServiceWorker();
}
场景 2:调用者需要一个特定的构造函数签名(例如
同样的问题。当调用者期望构造函数签名完全匹配时,如何注入(inject)额外的依赖项?
我认为我理解这个概念的主要问题是,当并非所有内容都由 DI(调用者)构建时,我看不到如何仅部分地执行 DI
public class ServiceWorker
{
IService _service;
public ServiceWorker(string name, string id, IService service)
{
_service = service
}
}
public class Caller
{
// No way to change this.
var serviceWorker = new ServiceWorker(name, id);
}
我知道,这是非常基础的,但我相信在继续之前我需要先了解这一点。有其他选择吗?
最佳答案
正如 Steven 在他的评论中正确指出的那样,仅限于特定的构造函数签名是 Constrained Construction 反模式的一个实例。然而,有时这可能不在您的控制范围内。
一个例子是 so-called 'Provider pattern', which isn't a pattern at all .在这样的示例中,您可能必须遵守第三方框架的规则,因此您无能为力。这样的框架应该被认为对依赖注入(inject)不友好。
考虑 OP 中的场景 2,因为场景 1 只是场景 2 的特例。如果您必须提供一个具有特定构造函数的类,您可以创建一个 Facade具有所需的构造函数签名。这使您能够避免使用第三方框架施加的约束污染使用依赖注入(inject)的精心设计的类。它可能看起来像这样:
public class ServiceWorker
{
IService _service;
public ServiceWorker(string name, string id, IService service)
{
_service = service
}
}
public class ServiceWorkerFacade
{
ServiceWorker imp;
public ServiceWorkerFacade(string name, string id)
{
imp =
new ServiceWorker(
name,
id,
new FooService(
new BarService(),
new BazService());
}
}
public class Caller
{
// No way to change this.
var serviceWorker = new ServiceWorkerFacade(name, id);
}
FooService
实现了 IService
。为了让事情变得有趣,我假设 FooService
有它自己的依赖关系,并且这些依赖关系由 BarService
和 BazService
满足。
正如 Steven 所建议的那样,您可以(出于必要)将 Facade 的构造函数视为 Composition Root .
如果您有任何机会影响相关框架的设计,您可以向开发人员指出 my guidance on designing DI-friendly frameworks .
关于c# - 当调用者期望特定的构造函数签名时使用构造函数注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45306403/