// Compute the precedence for generating a url // e.g.: /api/template == 5.5 // /api/template/{id} == 5.53 // /api/{id:int} == 5.4 // /api/template/{id:int} == 5.54 public static decimal ComputeOutbound(RouteTemplate template) { ValidateSegementLength(template.Segments.Count); // Each precedence digit corresponds to one decimal place. For example, 3 segments with precedences 2, 1, // and 4 results in a combined precedence of 2.14 (decimal). var precedence = 0m; for (var i = 0; i < template.Segments.Count; i++) { var segment = template.Segments[i]; var digit = ComputeOutboundPrecedenceDigit(segment); Debug.Assert(digit >= 0 && digit < 10); precedence += decimal.Divide(digit, (decimal)Math.Pow(10, i)); } return(precedence); }
public TemplateMatcher( RouteTemplate template, RouteValueDictionary defaults) { if (template == null) { throw new ArgumentNullException(nameof(template)); } Template = template; Defaults = defaults ?? new RouteValueDictionary(); // Perf: cache the default value for each parameter (other than complex segments). _hasDefaultValue = new bool[Template.Segments.Count]; _defaultValues = new object[Template.Segments.Count]; for (var i = 0; i < Template.Segments.Count; i++) { var segment = Template.Segments[i]; if (!segment.IsSimple) { continue; } var part = segment.Parts[0]; if (!part.IsParameter) { continue; } if (Defaults.TryGetValue(part.Name, out var value)) { _hasDefaultValue[i] = true; _defaultValues[i] = value; } } var routePattern = Template.ToRoutePattern(); _routePatternMatcher = new RoutePatternMatcher(routePattern, Defaults); }