【问题标题】:How do I use ASP.NET Core App Settings with Simple Injector如何将 ASP.NET Core 应用程序设置与 Simple Injector 一起使用
【发布时间】:2017-02-02 21:43:13
【问题描述】:

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

我首先按照 Rick Strahl 的 here 解释设置了我的强类型配置设置。这很好用。

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

appsetting.json

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

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


  }

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

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

【问题讨论】:

  • 这里描述了使用 IOptions 的最佳实践:github.com/simpleinjector/SimpleInjector/issues/…
  • 我去看看。
  • @Steven 看过那篇文章后,似乎完全放弃 IOptions 是共识。然后只需将您的 POCO 注册为您的 DI 容器中的单例。这就是你的意思吗?
  • 绝对没有任何理由任何应用程序组件依赖IOption&lt;T&gt;。您绝对应该将配置对象直接注入到您的类中。

标签: c# asp.net-core simple-injector


【解决方案1】:

ASP.NET Core integration guide for Simple Injector 声明如下:

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

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

其次,IOptions&lt;T&gt; 配置值被懒惰地读取。虽然可能会在应用程序启动时读取配置文件,但仅在第一次调用IOptions&lt;T&gt;.Value 时才会创建所需的配置对象。当反序列化失败时,例如由于应用程序配置错误,此类错误只会在调用IOptions&lt;T&gt;.Value 后出现。这可能会导致配置错误的时间比要求的时间长得多。通过在应用程序启动时读取并验证配置值,可以防止此问题。配置值可以作为单例注入到需要它们的组件中。

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

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

一旦你有一个正确读取和验证的配置对象,注册需要配置对象的组件就这么简单:

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

// Verify mailSettings here (if required)

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

【讨论】:

  • 虽然它有点回答了这个问题,但解决方案还不够:.net core 建议使用IOptions,因此我想这样编写我的服务以使其更加“面向未来” '。在同一个解决方案中同时使用 .NET Core 和 .NET Framework 让我想通过正确的方式在 .NET Core 中注册它。
【解决方案2】:

我是ExistAll.SimpleConfig 的作者。 SimpleConfig 正是 DI 环境中配置/设置所需要的。

看看是不是你需要的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-08
    • 2018-10-27
    • 2014-08-22
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多