Шаблон параметров, конфигурация в Legacy .NET-приложении с простым инжектором - PullRequest
0 голосов
/ 08 ноября 2018

В этой статье https://medium.com/@dmitryzaets/legacy-net-applications-configuration-management-net-framework-4-5-1-68220335d9d8, описывается, как использовать шаблон параметров вместе с Autofac. Я попытался перевести это для использования с простым инжектором. Но мне не повезло. Вот мой код МОК

public class IocBootstrap2
{
    private Container Container { get; }
    public IocBootstrap2()
    {
        Container = new Container();
        var configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Configuration"))
            .AddJsonFile("settings.json", optional: false, reloadOnChange: true);
        var configuration = configurationBuilder.Build();
        //Register Options
        Container.Register(typeof(IOptions<>), typeof(OptionsManager<>));
        Container.Register(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>));
        Container.Register(typeof(IOptionsFactory<>), typeof(OptionsFactory<>));
        Container.Register(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>));
        // Register ConfigurationOptions
        Container.RegisterConfigurationOptions2<MailingOptions>(configuration.GetSection("mailing"));

    #if DEBUG
        Container.Verify();
    #endif   
 }
}

public static class ConfigurationSetupExtensions2
{
    public static void RegisterConfigurationOptions2<TOptions>(this Container container, IConfiguration config)
        where TOptions : class
    {
        container.Register(typeof(IOptionsChangeTokenSource<TOptions>),
            () => new ConfigurationChangeTokenSource<TOptions>(config), Lifestyle.Transient);
        container.Register(typeof(IConfigureOptions<TOptions>),
            () => new ConfigureFromConfigurationOptions<TOptions>(config), Lifestyle.Transient);
    }
}
 public class MailingOptions
{
    public MailingOptions()
    {
        BatchSize = 1;
    }
    public int BatchSize { get; set; }
    public int BatchDelay { get; set; }
}

settings.json

{
  "mailing": {
    "batchSize": 15, 
    "batchDelay": 1
  }
}

Затем я внедряю его в конструктор ViewModel: s, как этот

  public class BlockViewModel 
    {
        private readonly MailingOptions _options;

        #region Constructor
        public BlockViewModel(IOptions<MailingOptions> options) 
        {
            _options = options.Value;
        }
        #endregion

    }

Когда я запускаю его, я получаю исключения в Container.Verify.

Конструктор типа OptionsFactory содержит параметр с именем 'setups' и типом IEnumerable >, который не зарегистрирован. Убедитесь, что IEnumerable > зарегистрирован, или измените конструктор OptionsFactory . Однако есть регистрация для IConfigureOptions ; Вы хотели зависеть от IConfigureOptions ?

StackTrace:

в SimpleInjector.Container.ThrowParameterTypeMustBeRegistered (цель InjectionTargetInfo)

Как мне зарегистрировать IEnumerable<IConfigureOptions<MailingOptions>>? Может кто-нибудь сказать мне, что я делаю неправильно, или, точнее, что я не понимаю?

1 Ответ

0 голосов
/ 08 ноября 2018

Краткий ответ: не вводите IOptions<T> в компоненты вашего приложения. Как объяснено здесь , это только усложнит ваши компоненты, их модульные тесты и, как вы уже заметили, вашу конфигурацию.

Вместо этого пусть BlockViewModel напрямую зависит от MailingOptions:

public class BlockViewModel 
{
    private readonly MailingOptions _options;

    public BlockViewModel(MailingOptions options) 
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
    }
}

Это позволяет упростить вашу конфигурацию до следующего:

Container = new Container();
var configutation = new ConfigurationBuilder()
  .SetBasePath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration"))
    .AddJsonFile("settings.json", optional: false);
    .Build();

MailingOptions options = configuration.GetSection("mailing").Get<MailingOptions>();
Container.RegisterInstance<MailingOptions>(options);

// Register View Models
Container.Register<BlockViewModel>();

Container.Verify();
...