. net core 3: настройка контейнера DI для разных сред - PullRequest
0 голосов
/ 06 января 2020

Я портирую старый. net v 4.5.1 проект на самое последнее. net ядро. Для внедрения зависимостей в старом. net каркасном проекте используется контейнер Unity, в котором все регистрации служб хранятся в web.config.

Global.asax:

    UnityConfigurationSection section
        = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
    section.Configure(container, "unityContainer");

web.config:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container name="primaryUnityContainer">
      <register type="ILogger" mapTo="Log4NetLogger"/>

Задача состоит в следующем: каков наилучший способ. net core 3 для настройки служб в файле конфигурации вне приложения, например в настройках приложения. json, например, так что могут быть реализованы разные реализации зарегистрирован для разных сред.

Можно ли расширить встроенный контейнер или лучше использовать какую-либо стороннюю систему с этой функцией?

Каковы другие подходы к реализации служб для конкретной среды c?

Ответы [ 2 ]

3 голосов
/ 06 января 2020

Нельзя настроить службы в ASP. NET Ядро вне приложения. Microsoft.Extensions.DependencyInjection полностью основан на коде, и хотя вы можете использовать другие контейнеры DI, они должны использоваться и настраиваться в рамках Microsoft.Extensions.DependencyInjection фасада.

При этом «среды» в ASP . NET Ядро основано на конфигурации. Вы не компилируете приложение несколько раз для нескольких разных сред. Вместо этого вы задаете среду при запуске через переменную среды, такую ​​как ASPNETCORE_ENVIRONMENT, или передаваете среду во время выполнения, например, через аргумент CLI.

В любом случае вы можете затем выполнить переход в своем коде на основе ценность окружающей среды. На самом деле существует три способа использования значения среды для настройки служб по-разному для каждой среды.

  1. Внедрение IWebHostEnvironment в Startup

    private readonly IWebHostEnvironment _env;
    
    public Startup(IWebHostEnvironment env)
    {
        _env = env;
    }
    

    Затем в ConfigureServices:

    if (_env.IsDevelopment())
    {
        ...
    }
    
    if (_env.IsProduction())
    {
        ...
    }
    
    if (_env.IsEnvironment("Foo"))
    {
        ...
    }
    
  2. Использование именования на основе соглашений с ConfigureServices. Другими словами, вы можете определить различные Configure{EnvironmentName}Services методы для вашего Startup класса:

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureProductionServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureFooServices(IServiceCollection services)
    {
        ...
    }
    
  3. Использовать именование на основе соглашений с самим классом Startup. На самом деле вы можете определить несколько Startup классов, таких как StartupDevelopment, StartupProduction, StartupFoo и др. c. Единственный улов заключается в том, что вы больше не можете использовать метод generi c UseStartup<T> при настройке хоста в Program.cs. Вместо этого вам нужен не-generi c UseStartup, который принимает строку имени сборки (поскольку вы не будете знать, какой класс запуска вам действительно нужен во время компиляции):

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var assemblyName = typeof(Startup).GetTypeInfo().Assembly.FullName;
    
        return WebHost.CreateDefaultBuilder(args)
            .UseStartup(assemblyName);
    }
    
0 голосов
/ 06 января 2020

Вы ниже тип настройки конфигурации:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
    .AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
    .AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}
...