如何编写允许您在不创建选项实例的情况下设置选项的扩展方法

How to write an extension method that allows you to set options without creating the options instance

我真的很喜欢这种模式,我可以通过选项 class 配置服务而不必创建它,但是我找不到如何编写允许我使用的扩展方法的示例用于注册 DbContext 的相同模式,例如下面的模式。

services.AddDbContext<MyDbContext>(options => options.EnableDetailedErrors());

我可以看到方法签名使用了一个动作方法,但我似乎无法在 GitHub 中找到扩展 class for ASP.NET Core 告诉我如何编写使用该类型的选项生成器模式的扩展方法。

例如,拿下面的服务代码。我将如何编写扩展方法以便我可以在服务注册期间配置选项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMyService(options => options.SomeSetting = true);
}

public interface IMyService
{
    void DoSomething();
}

public class MyService : IMyService
{
    private readonly MyServiceOptions _options;
    public MyService(IOptions<MyServiceOptions> options)
    {
        _options = options.Value;
    }
    public void DoSomething()
    {
        Console.WriteLine(_options.SomeSetting);
    }
}    
public static class MyServiceExtensions
{
    // How would I write this extension method so that I could configure it with options overload
    public static IServiceCollection AddMyService(this IServiceCollection services, Action<MyServiceOptions> configure)
    {
        services.AddSingleton<IMyService, MyService>();
        return services;
    }
}

ASP.NET Core provides this mechanism with the IConfigureOptions interface. You implement this interface in a configuration class and use it to configure the IOptions object in any way you need.

就这么简单:

   public class MyServiceConfiguration : IConfigureOptions<MyServiceOptions>
   {
       private MyServiceOptions _options;
       public MyServiceConfiguration(IOptions<MyServiceOptions> options)
       {
           _options = options.Value;
       }

       public void Configure(MyServiceOptions options)
       {
           options.SomeSetting = _options.SomeSetting;
           options.SomeOtherSetting = _options.SomeOtherSetting;
       }
   }

All that remains is to register this implementation in the DI container.:

    public void ConfigureServices(IServiceCollection services)
    {
       services.Configure<MyServiceOptions>(options => options.SomeOtherSetting = true);
       services.AddSingleton<IMyService, MyService>();
    }

使用此配置,当将 IOptions 注入您的服务时,MyServiceOptions 对象将由 ConfigureMyServiceOptions class.

配置

Be careful! The ConfigureMyServiceOptions object is registered as a singleton, so it will capture any injected services of scoped or transient lifetimes.