我们什么时候需要IOptions?

时间:2019-02-23 17:13:50

标签: c# dependency-injection

我正在.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();
    }
}

2 个答案:

答案 0 :(得分:1)

在.Net核心中,建议根据您的用例强烈键入所有配置。这将帮助您实现关注点分离。

实际上,无需使用IOptions就可以实现相同的目的。 因此,如果我退后一步,并且看看.net核心配置中的所有可用选项,则:

1。原始配置[path:key]

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

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

2。 IOptions绑定到Config节

您可以使用IOptions实现(您已经知道)。 这样做会更好,因为您可以使用一个具有所有相关配置的类。 IOptions界面为您提供了其他好处。

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

有关好处,请参阅MSDN article for details

您还可以参考该博客中的twitter conversation at this blog.,Rick还解释说,他找不到这种方法与下面的第3种方法有什么不同的实际案例-因为通常情况下配置不是动态的,因此它们在应用程序启动之前只能完成一次。

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

您可以使用.Bind调用将配置节绑定到POCO类。您将获得强类型对象。在这里,如果多个参与者正在使用配置,则他们将无法获得IOptions接口提供的其他服务。

我知道这并不能完全指出差异。但是我相信,这将在决定您的偏好时带来更多的清晰度。

答案 1 :(得分:1)

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

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

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