Skip to content

AddRoutingCore(this IServiceCollection services) and RouteOptions updates for CreateSlimBuilder #46428

@mitchdenny

Description

@mitchdenny

Background and Motivation

Modify RouteOptions to not automatically add the RegexInlineRouteConstraint. Instead AddRouting(...) is modified to call a new method called AddRoutingCore(...) which does everything that AddRouting(...) does, but then adds the RegexInlineRouteConstraint back in to RouteOptions.

Proposed API

namespace Microsoft.Extensions.DependencyInjection;

public static class RoutingServiceCollectionExtensions
{
+    public static IServiceCollection AddRoutingCore(this IServiceCollection services);
}

Usage Examples

This usage of CreateSlimBuilder() will result in no regex constraint being available:

var builder = WebApplication.CreateSlimBuilder();
var app = builder.Build();
app.MapGet("/products/{productId:regex(...)", (string productId) => {});
app.Run();

... the above code would run, but when a request is made to /products/abcd1234 it would throw an InvalidOperationException. We could consider adding an analyzer which detects when CreateSlimBuilder(...) is being used and detect a route pattern with a regex constraint and tell people that they need to add it (possibly with a fixer).

If you do want to add the regex route constraint back in, this is what it would look like:

var builder = WebApplication.CreateSlimBuilder();
builder.Services.AddRoutingSlim().Configure<RouteOptions>(options => {
    options.SetParameterPolicy<RegexInlineRouteConstraint>("regex");
});

Alternative Designs

Rather than using SetParameterPolicy<T>(string) we considered adding a specific method called AddRegexConstraint(...) but it is somewhat over specific. We've also considered changes to Regex to reduce the impact it has on binary size by eliminating backtracking (saves around 800kb).

We have not fully explored using regex source generator support (with the exception of the alpha constraint). The regex source generator relies on a Regex being defined as a field and then the source generator substituting the initialization of that field with a method that returns the source generated Regex instance. This won't work with the regex constraint because the string is passed around as a parameter at runtime.

Once the request delegate source generator is further along we might find a way to achieve this and we can revisit.

Risks

Could be somewhat confusing as to why we are excluding just the reg-ex constraint.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions