.NET Core 2, DI, файл конфигурации - PullRequest
       30

.NET Core 2, DI, файл конфигурации

0 голосов
/ 10 сентября 2018

Я изучаю .NET Core 2, и мне не нравится, как управляется DI ... В Интернете я читаю что-то вроде следующих шагов:

  1. создание интерфейса, подобного IService

  2. создание реализации для IService

  3. добавление его в область видимости контейнера .NET Core в метод Startup.Configuration для разрешения зависимости.

  4. наконец, я могу использовать его в конструкторе моего пользовательского контроллера.

В .NET classic я использовал выделенный файл конфигурации XML для управления зависимостями: могу ли я использовать файл конфигурации (одинаковые JSON или XML), чтобы сделать то же самое, что и метод Startup.Configuration?

... в противном случае кто-то может объяснить мне причину, по которой конфигурировать сервисы в Startup. Конфигурация - лучший способ?

Большое спасибо ...

1 Ответ

0 голосов
/ 10 сентября 2018

Во-первых, чтобы ответить на ваш вопрос «могу ли я использовать файл конфигурации», ответ категорически «да». Почему бы вам не ответить позже, но сейчас, вот бедная версия того, как вы могли бы сделать это, добавив в свой файл appsettings.json. Обратите внимание, что этот код не является оптимальным, но предназначен для того, чтобы показать вам, как вы могли бы реализовать это решение.

Давайте начнем с некоторых классов для хранения данных:

public class ServicesConfiguration
{
    public IEnumerable<ServiceItem> Singleton { get; set; }
    public IEnumerable<ServiceItem> Transient { get; set; }
}

public class ServiceItem
{
    public string Service { get; set; }
    public string Implementation { get; set; }
}

Теперь добавьте раздел в свой JSON-файл, вы можете даже захотеть оставить этот файл внешним по отношению к основной конфигурации, но я подробно остановлюсь на деталях реализации:

{
    //snip main config....

    "Services" : {
        "Singleton": [
            { 
                "Service": "YourNamespace.IFoo1, YourNamespace", 
                "Implementation": "YourNamespace.Foo1, YourNamespace" 
            },   
            {
                "Service": "YourNamespace.IFoo2, YourNamespace", 
                "Implementation": "YourNamespace.Foo2, YourNamespace" 
            }  
        ],
        "Transient": [
            {
                "Service": "YourNamespace.IBar1, YourNamespace",
                "Implementation": "YourNamespace.Bar1, YourNamespace"
            }    
        ]
    }
}

А теперь метод расширения для настройки всего этого:

public static IServiceCollection AddFromConfigurationFile(this IServiceCollection services, 
    IConfigurationSection configuration)
{
    var servicesConfiguration = configuration.Get<ServicesConfiguration>();

    foreach(var service in servicesConfiguration.Singleton)
    {
        services.AddSingleton(Type.GetType(service.Service), Type.GetType(service.Implementation));
    }

    foreach(var service in servicesConfiguration.Transient)
    {
        services.AddTransient(Type.GetType(service.Service), Type.GetType(service.Implementation));
    }

    //Other scopes here...

    return services;
}

И назовите это ConifigureServices так:

services.AddFromConfigurationFile(Configuration.GetSection("Services"));

Итак, хорошо и просто, верно? Почему бы тебе не сделать это? Несколько идей из головы:

  1. Зачем менять работу почти всех реализаций DI? Если это не сломано, зачем это чинить? То, что вы привыкли к определенному методу, не означает, что это хорошая идея.
  2. Безопасность типов: вы теряете проверку времени компиляции типов, указанных вами в файле конфигурации.
  3. Безопасность: наличие этого в конфигурационном файле позволило бы кому-то изменить реализацию на класс по своему выбору.

Я уверен, что есть и другие, но ... это ваше приложение!

...