【问题标题】:Drawbacks to Passing an Instance to ASP.NET Core Dependency Injection将实例传递给 ASP.NET Core 依赖注入的缺点
【发布时间】:2020-02-14 22:02:48
【问题描述】:

我有一个类需要一个连接字符串作为其构造函数的参数:

public class MyClassHere
{
     private string connectionString;

     public MyClassHere(string connectionString)
     {
        this.connectionString = connectionString;
     }
}

我已将该类作为单例添加到我的服务中,如下所示:

services.AddSingleton<MyClassHere>();

显然这不起作用,因为它在构造函数中需要一个字符串。

我见过这样的例子:

services.AddSingleton<MyClassHere>(new MyClassHere("Some Connnection String"));

但我也读过一些模糊的说法,当你这样做时,依赖注入系统不会为你清理你的对象。

将实例传递到依赖注入系统(而不是让它为您实现)有哪些缺点(如果有的话)?

【问题讨论】:

  • 这是一个人为的例子,还是你专门将连接字符串传递给你的类,以便在这种特殊情况下它可以实例化一个连接到它本身的数据库上下文?我问是因为让 DI 容器提供 db 上下文实例会更典型?
  • “依赖注入系统不会为你清理你的对象”——没错。将实际实例注册为单例时,DI 容器不会在容器被释放时释放它们。但这仅在它们实际上是一次性的(例如,需要释放非托管资源或连接)时才重要。当容器被释放时,这通常意味着应用程序无论如何都会关闭。

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


【解决方案1】:

这样做的一个缺点是,如果要更改MyClassHere 的构造函数,则必须在 DI 注册中更新它的用法。取决于它的使用方式,这可能是微不足道的,也可能不是微不足道的。

无论如何,在 .NET Core 中处理这种情况同时保持依赖注入的所有好处的一种方法是使用 Options pattern


根据您的示例,这可能看起来像这样:

public class MyOptions
{
    public string ConnectionString { get; set; }
}

public class MyClassHere
{
    private readonly string _connectionString;

    public MyClassHere(IOptions<MyOptions> options)
    {
        _connectionString = options.Value.ConnectionString;
    }

    public void Foo() => Console.WriteLine(_connectionString);
}

下面是一个注册示例:

static void Main(string[] args)
{
    var myClass = new ServiceCollection()
        .Configure<MyOptions>(o =>
        {
            o.ConnectionString = "bar";
        })
        .AddSingleton<MyClassHere>()
        .BuildServiceProvider()
        .GetService<MyClassHere>();

    myClass.Foo();

    Console.ReadLine();
}

按预期输出“bar”。

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 2018-03-23
    • 1970-01-01
    • 2020-10-13
    • 2023-03-09
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多