当调用者期望特定的构造函数签名时使用构造函数注入

时间:2017-07-25 14:33:42

标签: c# dependency-injection inversion-of-control autofac

我是.NET C#中的DI新手。 autofac并且在我无法完全控制来电方时遇到问题以了解如何使用DI。

我有两个问题需要理解。

场景1:调用者期望默认构造函数(不带任何参数)

当我还想在构造类时注入一些服务接口时,如何处理这种情况?我在考虑构造函数链接,但这意味着我必须知道具体的类型,并且它围绕DI的思想工作。 (至少我认为)。

public class ServiceWorker
{
    IService _service;

    public ServiceWorker(IService service) 
    { 
        _service = service
    }
}

public class Caller
{
    // No way to change this. 
    var serviceWorker = new ServiceWorker();
}

Scneario 2:调用者需要特定的构造函数签名(例如

这里也有同样的问题。当调用者期望构造函数签名完全匹配时,如何注入其他依赖项?

我认为我理解这个概念的主要问题是,当不是所有东西都由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);
}

我知道,这是非常基本的,但我相信在继续之前我需要首先理解这一点。还有替代品吗?

1 个答案:

答案 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有其自己的依赖性,并且BarServiceBazService满足了这些依赖性。

那么,正如史蒂文(Steven)所建议的那样,您可以(根据需要)将Facade的构造函数视为Composition Root

如果您有机会影响相关框架的设计,则可以将开发人员指向my guidance on designing DI-friendly frameworks