简体   繁体   中英

How can I provide overridable configuration per endpoint in an AspNetCore web api?

I have an Asp.Net Core api middleware for which I want to expose some configuration options via appsettings.json:

public class MyMiddleware: IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        // something like this, except get data from appsettings.json instead of attributes
        var attribute = context.GetEndpoint()?.Metadata.GetMetadata<MyAttribute>();
        if (attribute is not null) {
            // do the things
        }
        await next(context);
    }
}

The attribute pattern that I have has advantages that I would like to keep in that I can place the attribute on the action method, the class containing it or a base class and the middleware utilizes the most specific one. Unfortunately the attributes can only be modified by rebuilding the application and deploying a new version.

Is there a built-in way or otherwise reasonable way to map an options data store to endpoints?

I was thinking something in appsettings.json like this with globbing rules for path traversal similarities:

{
   "ConfigurationRules": [
        {
            "Match": "/foo/**/bar",
            "Option1": "..."
        },
        {
            "Match": "/foo",
            "Option1": "..."
        },
        {
            "Match": "/**",
            "Option1": "..."
        },
   ]     
}

This article explains how to map a custom configuration section to an object that you can use in code. Your middleware would have to accept an IConfiguration object so that the caller can pass it into your setup method inside of ConfigureServices . Something like this:

public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

//...

public void ConfigureServices(IServiceCollection services)
{
    services.AddMyMiddleware(Configuration);
}

Then in your AddMyMiddleware extension method, you can get your configuration section like this:

var rules = Configuration.GetSection("ConfigurationRules");
services.Configure<MyConfigurationRulesClass>(rules);

Now this instance of MyConfigurationRulesClass will be available through dependency injection wherever you need it - eg by adding IOptions<MyConfigurationRulesClass> myConfiguration to the constructor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM