【问题标题】:When do we need IOptions?我们什么时候需要 IOptions?
【发布时间】:2019-07-17 13:08:40
【问题描述】:

我正在 .Net Core 中学习 DI,但我不知道使用 IOptions 的好处。

如果我们可以不用IOptions,为什么还需要它?

IOptions

interface IService
{
    void Print(string str);
}

class Service : IService
{
    readonly ServiceOption options;
    public Service(IOptions<ServiceOption> options) => this.options = options.Value;
    void Print(string str) => Console.WriteLine($"{str} with color : {options.Color}");
}

class ServiceOption
{
    public bool Color { get; set; }
} 

class Program
{
    static void Main()
    {
        using (ServiceProvider sp = RegisterServices())
        {
            //
        }
    }


    static ServiceProvider RegisterServices()
    {
        IServiceCollection isc = new ServiceCollection();

        isc.Configure<ServiceOption>(_ => _.Color = true);
        isc.AddTransient<IService, Service>();
        return isc.BuildServiceProvider();
    }
}

没有IOptions

interface IService
{
    void Print(string str);
}

class Service : IService
{
    readonly ServiceOption options;
    public Service(ServiceOption options) => this.options = options;
    public void Print(string str) => Console.WriteLine($"{str} with color : {options.Color}");
}

class ServiceOption
{
    public bool Color { get; set; }
}

class Program
{
    static void Main()
    {
        using (ServiceProvider sp = RegisterServices())
        {
            //
        }
    }

    static ServiceProvider RegisterServices()
    {
        IServiceCollection isc = new ServiceCollection();

        isc.AddSingleton(_ => new ServiceOption { Color = true });
        isc.AddTransient<IService, Service>();
        return isc.BuildServiceProvider();
    }
}

【问题讨论】:

  • 选项模式增加了一些特性。例如,命名选项、在运行时重新加载选项以及基于委托的管道,允许多个参与者参与如何配置“设置”类。 docs 非常详细地解释了很多。最终,如果您不需要这些功能中的任何一个,您就不需要使用IOptions
  • 我有一个答案here,它深入研究了配置管道,可能有帮助。
  • "我们什么时候需要 IOptions?" => 每当模式适合你想要做什么?您似乎没有进行任何类型的研究,随着 ASP.NET Core 的移动速度,答案可能很快就过时了

标签: c# dependency-injection


【解决方案1】:

在 .Net 核心中,建议您的所有配置都应根据其用例进行强类型化。这将帮助您实现关注点分离。

实际上,您可以在不使用 IOptions 的情况下实现相同的目标,如您所说。 所以,如果我退一步,如果我们看看 .net 核心配置中的所有可用选项:

1.原始配置[path:key]

可以直接访问IConfiguration实例,在accessor部分提供JSON key的路径,返回配置值。

这不是好方法,因为在阅读配置时这里没有强类型。

2。 IOptions 绑定到配置部分

您可以使用 IOptions 实现(您已经知道)。 这更好,因为您可以拥有一个包含所有相关配置的类。 IOptions 接口为您提供了额外的好处。

据我了解,此 IOptions 接口将您的配置与正在读取配置的参与者分离,因此您可以使用 .net 核心框架中的一些附加服务。

有关好处请参考MSDN article for details

您也可以参考twitter conversation at this blog. 在该博客中,Rick 还解释说,他找不到任何实际案例说明这种方法与下面的第三种方法有何不同 - 因为通常配置不是动态的,它们已经完成仅在应用启动前一次。

3. Configuration.Bind() 绑定到配置部分

您可以使用 .Bind 调用将配置部分绑定到 POCO 类。你得到强类型的对象。这里如果有多个参与者使用配置,他们将不会获得 IOptions 接口提供的额外服务。

我知道这并没有完全指出差异。但我相信这会让您更清楚地决定您的偏好。

【讨论】:

    【解决方案2】:

    简短回答:是的,您可以不使用它,直接从ConfigurationManager.AppSettingslike in this answer 访问您的设置。

    稍微长一点的答案:尤其是当您想测试您的(控制台)应用程序时,注入服务和设置可能会很好。

    ASP.NET Core 包含 DI,它将在您的Startup.cs 中设置。 DI 可以在控制台应用程序中使用,但设置它可能会很困难(呃),因为默认应用程序没有管道。我在how to setup DI with IOptions configuration for .NET Core Console Applications写了一个小博客。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 2011-09-20
      • 2014-01-26
      • 2021-12-25
      • 1970-01-01
      相关资源
      最近更新 更多