c# - 当调用者期望特定的构造函数签名时使用构造函数注入(inject)

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

我是 .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 有它自己的依赖关系,并且这些依赖关系由 BarServiceBazService 满足。

正如 Steven 所建议的那样,您可以(出于必要)将 Facade 的构造函数视为 Composition Root .

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

关于c# - 当调用者期望特定的构造函数签名时使用构造函数注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45306403/

相关文章:

c# - 如何修复 Visual Studio 2015 中的错误 "Could not load file or assembly ' Microsoft.VisualStudio.Web?

c# - Visual Studio 2008 设计 View 不工作?

javascript - 从 javascript 调用隐藏代码

javascript - 如果类是在带有元注释的组件之后立即定义的,则该类不可注入(inject)

inversion-of-control - 洋葱架构与 IoC 矛盾吗

c# - 如何解析 ConfigureServices 中的 IOptions 实例?

c# - 使用没有外部变量的 LINQ 连接字典(值)中的所有字符串

java - Guice Injector 保持应用程序运行

php - Laravel 在特征构造函数中传递参数

java - 在没有循环引用的情况下使用 Spring IOC 连接 MVP?