gpt4 book ai didi

c# - 如何将 ASP.NET Core 应用程序设置与简单注入(inject)器一起使用

转载 作者:太空狗 更新时间:2023-10-29 21:53:02 30 4
gpt4 key购买 nike

我是 ASP.NET Core 的新手,需要一些指导。我试图找出一个简单的场景,在 ASP.NET Core 中使用应用程序设置,同时还使用简单注入(inject)器。

我首先按照说明设置我的强类型配置设置 here里克斯特拉尔。这很好用。

  public class MySettings
{
public string ApplicationName { get; set; }
}

应用设置.json

{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"MySettings": {
"ApplicationName": "Test Service"
}
}

启动.cs

    public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();

// Add Options
services.AddOptions();

// Add our Config object so it can be injected
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
services.AddSingleton(GetTestBroker(container));

//Simple Injector
//services.AddSingleton<IControllerActivator>(new SimpleInjectorControllerActivator(container));
//services.AddSingleton<IViewComponentActivator>(new SimpleInjectorViewComponentActivator(container));


}

在我们的其他项目中,我们正在使用 Simple Injector for DI。添加 Simple Injector 包并按照说明配置它后,我发现我的 IOptions 配置中断了。

我想知道的是,在 ASP.NET Core 中实现配置并同时使用另一个 DI 库(如 Simple Injector)的最佳实践是什么?

最佳答案

ASP.NET Core integration guide for Simple Injector陈述如下:

.NET Core contains a new configuration model based on an IOptions<T> abstraction. We advise against injecting IOptions<T> dependencies into your application components. Instead let components depend directly on configuration objects and register those objects as instances (using RegisterInstance). This ensures that configuration values are read during application start up and it allows verifying them at that point in time, allowing the application to fail fast.

Letting application components depend on IOptions<T> has some unfortunate downsides. First of all, it causes application code to take an unnecessary dependency on a framework abstraction. This is a violation of the Dependency Inversion Principle, which prescribes the use of application-tailored abstractions. Injecting an IOptions<T> into an application component makes such component more difficult to test, while providing no additional benefits for that component. Application components should instead depend directly on the configuration values they require.

Second, IOptions<T> configuration values are read lazily. Although the configuration file might be read upon application start up, the required configuration object is only created when IOptions<T>.Value is called for the first time. When deserialization fails, because of application misconfiguration for instance, such error will only be appear after the call to IOptions<T>.Value. This can cause misconfigurations to stay undetected for much longer than required. By reading—and verifying—configuration values at application start up, this problem can be prevented. Configuration values can be injected as singletons into the component that requires them.

To make things worse, in case you forget to configure a particular section (by omitting a call to services.Configure<T>) or when you make a typo while retrieving the configuration section (e.g. by supplying the wrong name to Configuration.GetSection(name)), the configuration system will simply supply the application with a default and empty object instead of throwing an exception! This may make sense when building framework or third-party components, but not so much for application development, as it easily leads to fragile applications.

Because you want to verify the configuration at start-up, it makes no sense to delay reading it, and that makes injecting IOptions<T> into your application components sub optimal, to say the least. Depending on IOptions<T> might still be useful when bootstrapping the application, but not as a dependency anywhere else in your application. The IOptions<T> architecture is designed for the framework and its components, and makes most sense in that particular context—not in the context of line-of-business applications.

Once you have a correctly read and verified configuration object, registration of the component that requires the configuration object is as simple as this:

MyMailSettings mailSettings =
config.GetSection("Root:SectionName").Get<MyMailSettings>();

// Verify mailSettings here (if required)

container.Register<IMessageSender>(
() => new MailMessageSender(mailSettings));

关于c# - 如何将 ASP.NET Core 应用程序设置与简单注入(inject)器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42012823/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com