.NET Core中“依赖关系中的依赖关系”应遵循的模式是什么?

时间:2018-09-04 12:38:47

标签: c# design-patterns asp.net-core dependency-injection

请考虑以下内容:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSingleton<ILogger, Logger>();
        ...
    }

因此,很明显,如图所示,我显然希望在控制器方法中创建一个日志记录类,但我还有许多其他组件对它们来说是通用的-所有这些 组件都希望引用我的记录器。毕竟这是一个单例(我想这可能是反模式,但无论如何)。

如何正确地在ConfigureServices方法中传递“依赖关系中的依赖关系”?我想我可以做这样的事情:

    public void ConfigureServices(IServiceCollection services)
    {
        Logger l = new Logger();
        services.AddSingleton<ILogger, Logger>((provider) =>
        {
            return l;
        });
        services.AddScoped<IFoo, Foo>((provider) =>
        {
            return new Foo(l);
        });
        ...
    }

我可以做类似的事情!但是它看起来和感觉都像黑客一样。我确定我不应该在这样的ConfigureServices方法中解析/制作实际的具体构造,但是我不知道一种告诉Foo构造函数(如控制器方法)依赖ILogger的方法。

执行此操作的预期机制是什么?或者我应该考虑遵循完全不同的模式吗?

1 个答案:

答案 0 :(得分:1)

据我所知,您的依赖项中没有任何“怪异”方式的依赖项...

您需要做的就是像这样注册每个服务的实现:

services.AddSingleton<ILogger, Logger>();

执行此行时,您可以在构造函数的定义中“请求”一个ILogger,框架将处理实例化(或不取决于实例,取决于服务范围等)并将引用传递给您的调用。

这意味着,如果您的IFoo在其构造函数之一中“请求”一个ILogger,则只要您在ILogger提供者之后注册了IFoo服务提供者,就不需要做任何棘手的事情来解决它。下面是一个运行中的简单示例,其中Foo实现在构造函数中请求ILogger

public class Foo : IFoo
{
    private readonly ILogger<Foo> _logger;

    public Foo(ILogger<Foo> logger)
    {
        _logger = logger;
    }

    public Task WriteMessage(string message)
    {
        _logger.LogInformation("Foo.WriteMessage called. Message:{MESSAGE}", message);

        return Task.FromResult(0);
    }
}