我们什么时候需要 IOptions?

Mon*_*mer 9 c# dependency-injection

我正在 .Net Core 中学习 DI,但我不知道使用 .Net Core 的好处 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

没有 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Man*_*ari 7

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

实际上,您可以在不使用 IOptions 的情况下实现相同的目的。所以,如果我回过头来看看 .net 核心配置中的所有可用选项:

1. 原始配置[path:key]

您可以直接访问 IConfiguration 实例并在访问器部分提供 JSON 密钥的路径,并且将返回配置值。

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

2. IOptions 绑定到 Config Section

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

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

有关好处的详细信息,请参阅MSDN 文章

您还可以参考此博客上的twitter 对话。 在该博客中,Rick 还解释说,他找不到任何关于这种方法与下面的第 3 种方法有何不同的实际案例 - 因为通常配置不是动态的,并且它们仅在应用程序启动之前完成一次。

3. Configuration.Bind() 绑定到一个配置节

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

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

  • 我不明白这如何回答这个问题。您将选项“绑定”到 POCO,并且仍然将其注入到您的服务中;这正是他的“没有 IOptions”示例。这个答案没有说明使用 IOptions 相对于直接使用 POCO 的优势。 (2认同)