Недостатки передачи экземпляра в ASP. NET Внедрение зависимостей ядра - PullRequest
1 голос
/ 15 февраля 2020

У меня есть класс, которому нужна строка подключения в качестве параметра для его конструктора:

public class MyClassHere
{
     private string connectionString;

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

Я добавил этот класс в качестве одиночного к моей службе, например:

services.AddSingleton<MyClassHere>();

Понятно, что это не работает, потому что он принимает строку в конструкторе.

Я видел примеры, которые говорят, что делают это:

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

Но я также читал расплывчатые вещи, которые говорят, что когда вы делаете это, система внедрения зависимостей не будет очищать ваши объекты для вас.

Какие (если таковые имеются) недостатки в передаче экземпляра в систему внедрения зависимостей (вместо того, чтобы просто позволить ему сделать это для вас)?

1 Ответ

2 голосов
/ 15 февраля 2020

Один из недостатков этого состоит в том, что если изменить конструктор MyClassHere, вам придется обновить его использование при регистрации DI. Что может или не может быть тривиальным в зависимости от того, как оно используется.

Независимо от этого, один из способов справиться с этим сценарием в. NET Ядро при сохранении всех преимуществ внедрения зависимостей - использование параметров 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();
}

Который выводит «бар» как положено.

...