如何使用Simple Injector使用ASP.NET Core App设置

Eri*_*ric 6 c# simple-injector asp.net-core

我是ASP.NET Core的新手,需要一些指导.我试图找出一个简单的场景,使用ASP.NET Core中的应用程序设置,同时也使用Simple Injector.

我第一次设立了我的强烈型配置设置解释这里由Rick施特拉尔.这非常有效.

  public class MySettings
  {
    public string ApplicationName { get; set; }
  }
Run Code Online (Sandbox Code Playgroud)

appsetting.json

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "MySettings": {
    "ApplicationName": "Test Service"
  }
}
Run Code Online (Sandbox Code Playgroud)

Startup.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));


  }
Run Code Online (Sandbox Code Playgroud)

在我们的其他项目中,正在使用Simple Injector进行DI.添加Simple Injector包并按照说明进行配置后,我看到我的IOptions配置中断了.

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

Ste*_*ven 6

简单注入器的 ASP.NET Core 集成指南声明如下:

\n
\n

.NET Core 包含一个基于IOptions<T>抽象的新配置模型。我们建议不要将IOptions<T>依赖项注入到应用程序组件中。相反,让组件直接依赖于配置对象并将这些对象注册为实例(使用RegisterInstance)。这确保了在应用程序启动期间读取配置值,并允许在该时间点验证它们,从而使应用程序能够快速失败。

\n

让应用程序组件依赖IOptions<T>有一些不幸的缺点。首先,它导致应用程序代码对框架抽象产生不必要的依赖。这违反了依赖倒置原则,该原则规定使用应用程序定制的抽象。将 注入IOptions<T>到应用程序组件中会使此类组件更难以测试,同时不会为该组件提供任何额外的好处。应用程序组件应该直接依赖于它们所需的配置值。

\n

其次,IOptions<T>配置值的读取是惰性的。尽管配置文件可能会在应用程序启动时读取,但仅在IOptions<T>.Value第一次调用时才会创建所需的配置对象。当反序列化失败时,例如由于应用程序配置错误,此类错误只会在调用IOptions<T>.Value. 这可能会导致错误配置在比所需时间更长的时间内未被检测到。通过在应用程序启动时读取\xe2\x80\x94并验证\xe2\x80\x94配置值,可以防止此问题。配置值可以作为单例注入到需要它们的组件中。

\n

更糟糕的是,如果您忘记配置特定部分(通过省略对 的调用services.Configure<T>)或者在检索配置部分时出现拼写错误(例如,通过向 提供错误的名称Configuration.GetSection(name)),配置系统将简单地提供应用程序使用默认的空对象而不是抛出异常!这在构建框架或第三方组件时可能有意义,但对于应用程序开发则没有多大意义,因为它很容易导致应用程序脆弱。

\n

因为您想在启动时验证配置,所以延迟读取它是没有意义的,IOptions<T>至少可以说,这使得注入应用程序组件不是最佳选择。在引导应用程序时,依赖IOptions<T>可能仍然有用,但不能作为应用程序中其他任何地方的依赖项。该IOptions<T>体系结构是针对框架及其组件而设计的,并且在特定上下文\xe2\x80\x94 中最有意义,而不是在业务线应用程序的上下文中。

\n

一旦正确读取并验证了配置对象,注册需要配置对象的组件就非常简单:

\n
MyMailSettings mailSettings =\n    config.GetSection("Root:SectionName").Get<MyMailSettings>();\n\n// Verify mailSettings here (if required)\n\ncontainer.Register<IMessageSender>(\n    () => new MailMessageSender(mailSettings));\n
Run Code Online (Sandbox Code Playgroud)\n
\n