Make the default route constraints linkable (#24727)

- Added a helper that gives the linker the ability to preserve the constructors of these types
This commit is contained in:
David Fowler 2020-08-09 20:23:54 -07:00 committed by GitHub
parent 983e7ed635
commit fa0cb71186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 27 deletions

View File

@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
@ -86,6 +87,7 @@ namespace Microsoft.AspNetCore.Routing
}
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", Justification = "This type comes from the ConstraintMap.")]
private static IParameterPolicy CreateParameterPolicy(IServiceProvider serviceProvider, Type parameterPolicyType, string argumentString)
{
ConstructorInfo activationConstructor = null;

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Routing.Constraints;
namespace Microsoft.AspNetCore.Routing
@ -82,38 +83,45 @@ namespace Microsoft.AspNetCore.Routing
private static IDictionary<string, Type> GetDefaultConstraintMap()
{
return new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
{
// Type-specific constraints
{ "int", typeof(IntRouteConstraint) },
{ "bool", typeof(BoolRouteConstraint) },
{ "datetime", typeof(DateTimeRouteConstraint) },
{ "decimal", typeof(DecimalRouteConstraint) },
{ "double", typeof(DoubleRouteConstraint) },
{ "float", typeof(FloatRouteConstraint) },
{ "guid", typeof(GuidRouteConstraint) },
{ "long", typeof(LongRouteConstraint) },
var defaults = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
// Length constraints
{ "minlength", typeof(MinLengthRouteConstraint) },
{ "maxlength", typeof(MaxLengthRouteConstraint) },
{ "length", typeof(LengthRouteConstraint) },
// Type-specific constraints
AddConstraint<IntRouteConstraint>(defaults, "int");
AddConstraint<BoolRouteConstraint>(defaults, "bool");
AddConstraint<DateTimeRouteConstraint>(defaults, "datetime");
AddConstraint<DecimalRouteConstraint>(defaults, "decimal");
AddConstraint<DoubleRouteConstraint>(defaults, "double");
AddConstraint<FloatRouteConstraint>(defaults, "float");
AddConstraint<GuidRouteConstraint>(defaults, "guid");
AddConstraint<LongRouteConstraint>(defaults, "long");
// Min/Max value constraints
{ "min", typeof(MinRouteConstraint) },
{ "max", typeof(MaxRouteConstraint) },
{ "range", typeof(RangeRouteConstraint) },
// Length constraints
AddConstraint<MinLengthRouteConstraint>(defaults, "minlength");
AddConstraint<MaxLengthRouteConstraint>(defaults, "maxlength");
AddConstraint<LengthRouteConstraint>(defaults, "length");
// Regex-based constraints
{ "alpha", typeof(AlphaRouteConstraint) },
{ "regex", typeof(RegexInlineRouteConstraint) },
// Min/Max value constraints
AddConstraint<MinRouteConstraint>(defaults, "min");
AddConstraint<MaxRouteConstraint>(defaults, "max");
AddConstraint<RangeRouteConstraint>(defaults, "range");
{"required", typeof(RequiredRouteConstraint) },
// Regex-based constraints
AddConstraint<AlphaRouteConstraint>(defaults, "alpha");
AddConstraint<RegexInlineRouteConstraint>(defaults, "regex");
// Files
{ "file", typeof(FileNameRouteConstraint) },
{ "nonfile", typeof(NonFileNameRouteConstraint) },
};
AddConstraint<RequiredRouteConstraint>(defaults, "required");
// Files
AddConstraint<FileNameRouteConstraint>(defaults, "file");
AddConstraint<NonFileNameRouteConstraint>(defaults, "nonfile");
return defaults;
}
// This API could be exposed on RouteOptions
private static void AddConstraint<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]TConstraint>(Dictionary<string, Type> constraintMap, string text) where TConstraint : IRouteConstraint
{
constraintMap[text] = typeof(TConstraint);
}
}
}