我是.NET C#中的DI新手。 autofac并且在我无法完全控制来电方时遇到问题以了解如何使用DI。
我有两个问题需要理解。
当我还想在构造类时注入一些服务接口时,如何处理这种情况?我在考虑构造函数链接,但这意味着我必须知道具体的类型,并且它围绕DI的思想工作。 (至少我认为)。
public class ServiceWorker
{
IService _service;
public ServiceWorker(IService service)
{
_service = service
}
}
public class Caller
{
// No way to change this.
var serviceWorker = new ServiceWorker();
}
这里也有同样的问题。当调用者期望构造函数签名完全匹配时,如何注入其他依赖项?
我认为我理解这个概念的主要问题是,当不是所有东西都由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);
}
我知道,这是非常基本的,但我相信在继续之前我需要首先理解这一点。还有替代品吗?
答案 0 :(得分:1)
正如史蒂文(Steven)在其评论中正确指出的那样,仅限于特定的构造函数签名是 Constrained Construction 反模式的一个实例。但是,有时这可能超出您的控制范围。
一个示例是so-called 'Provider pattern', which isn't a pattern at all。在这样的示例中,您可能必须遵循第三方框架的规则,因此您无能为力。这样的框架应该被认为对依赖注入不友好。
请考虑OP中的方案2,因为方案1只是方案2的特例。如果必须提供具有特定构造函数的类,则可以创建一个Facade具有所需的构造函数签名。这使您能够避免使用由第三方框架强加的约束的,使用依赖注入的精心设计的类。看起来可能像这样:
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。