Шаблон параметров, конфигурация в Legacy .NET-приложении с простым инжектором
В этой статье, 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 ?
Трассировки стека:
в SimpleInjector.Container.ThrowParameterTypeMustBeRegistered (цель InjectionTargetInfo)
Как я могу зарегистрировать IEnumerable<IConfigureOptions<MailingOptions>>
? Может кто-нибудь сказать мне, что я делаю не так, или точнее, что я не понимаю?
1 ответ
Короткий ответ: не вводить 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();