Внедрение зависимостей: статические параметры и сервисы - PullRequest
0 голосов
/ 01 мая 2018

У меня есть эта служба, которая будет внедрена в некоторые другие контроллеры.

Требуется служба и строка подключения, взятая из файла конфигурации.

public class MyService : IMyService
{
  public MyService(IService1 service1, IService2 service2, string connectionString){
     //...
  }
}

Я бы хотел, чтобы IService1 и IService2 вводились, а connectionString указывалось вручную. Я не могу придумать, как это решить, примеры, которые я видел, были либо чрезвычайно сложными, либо просто не тем, чего я хотел достичь.

public void ConfigureServices(IServiceCollection services)
{
    var cfg = new MyConfiguration();   
    Configuration.Bind("config", cfg);
    var connectionString = cfg["myConnectionString"];
    services.AddSingleton<IMyService, MyService>(/*what can I do here?*/)
}

Может ли это быть достигнуто просто?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

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

Более правильным решением в мире ASP.NET Core было бы использование шаблона параметров. По сути, вместо того, чтобы требовать передачи строки подключения конструктору, вы создаете новый тип конфигурации, который настраивает вашу службу. Затем вы можете настроить этот объект, используя шаблон параметров.

Это будет выглядеть так:

public class MyService : IMyService
{
    public MyService(IService1 service1, IService2 service2, IOptions<MyServiceOptions> serviceOptions)
    {
        var connectionString = serviceOptions.Value.ConnectionString;

        //...
    }
}

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

А затем при запуске просто зарегистрируйте свой тип и настройте параметры:

services.AddSingleton<IMyService, MyService>();
services.Configure<MyServiceOptions>(options => {
    options.ConnectionString = "connection string";
});

Если вы поместите конфигурацию для строки подключения в отдельный раздел конфигурации, вы можете даже сделать это:

services.Configure<MyServiceOption>(configuration.GetSection("MyService"));

Предполагается, что ваша конфигурация выглядит следующим образом:

{
    "MyService": {
        "ConnectionString": "…"
    },
    // …
}
0 голосов
/ 01 мая 2018

У вас есть доступ к поставщику услуг в рамках фабричного делегата.

Разрешите другие зависимости и введите статическую переменную при инициализации службы.

//...
var connectionString = cfg["myConnectionString"];
services.AddSingleton<IMyService>(_ => 
    new MyService(_.GetService<IService1>(), _.GetService<IService2>(), connectionString));

В приведенном выше примере _ в фабричном делегате представляет собой IServiceProvider, а GetService<T> метод расширения используется для разрешения других служб при условии, что они также зарегистрированы в коллекции служб.

Фабричный делегат будет вызван при первом запросе IMyService.

В качестве альтернативы, ссылка Шаблон параметров в ASP.NET Core

И, например, settings.json file

{
  "myConnectionString": "value1_from_json",
}

рассмотрите возможность использования IOptions<T>, предоставляемого расширением конфигурации.

создать класс для хранения желаемой конфигурации.

public class MyConnections {
    public string MyConnectionString { get; set; }
}

рефакторинг класса зависит от IOption<MyConnections>

public class MyService : IMyService {
    private string connectionString;
    public MyService(IService1 service1, IService2 service2, IOptions<MyConnections> options){
        connectionString = options.Value.MyConnectionString;
        //...
    }

    //...
}

и настройте его при запуске

//...

services.Configure<MyConnections>(Configuration);
services.AddSingleton<IMyService, MyService>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...