Replaces a bunch of dictionary operations with indexing into an array by
doing some caching. Also eliminating an enumerator allocation by changing
from IReadOnlyDictionary to RouteValueDictionary.
This is consistent with other constraint types in routing, and avoids a
naming conflict with MVC.
This is a change **away** from the names used in System.Web and
System.Web.Http.Routing, but it seems worth doing for consistency and
clarity.
Constraint code ported from WebAPI2. Tests are new.
Also a bunch of misc cleanup for constraints.
- Move IRouteConstraint to abstractions
- Fix namespace of a constraint
- Some general style cleanup
- use RouteValueDictionary in the public API
Adds IRouterHandler, an abstraction for endpoints in the routing system
that can't chain (example: delegates). The idea is that some kinds of
routes aren't really friendly to chaining. If you don't support chaining,
then accept IRouteHandler and work with that rather than IRouter.
There's one implementation of IRouteHandler, RouteHandler. It implements
both IRouter and IRouteHandler.
Adds RouteBase as a base class for routes based on our template syntax and
defaults/constraints/data-tokens. Updated a lot of signatures to be
get/set virtual and mutable to facilitate or bigger variety of usage
scenarios.
Renamed TemplateRoute to just Route, now inherits from RouteBase.
Adds IRoutingFeature for middleware scenarios where you don't have access
to the route context.
Also adds some basic extension methods for accessing route values.
This change optimizes allocations by RouteValueDictionary based on usage.
First, implement a struct Enumerator, and expose the concrete RVD type
from all extensibility points. We wanted to try and decouple this code
from RVD originally and use IDictionary everywhere. After doing that we've
found that it allocates an unacceptable number of enumerators.
Secondly, optimize copies of RVD for the case where you're copying an RVC
to another (common case). When doing this we can copy the count to get the
right capacity, and copy the entries without allocating an enumerator.
Lastly, optimize RVD for the case where it's a wrapper around a poco
object. We 'upgrade' to a writable full dictionary if you try to write to
it, or call one of a number of APIs that are uncommonly used. We could
produce optimized versions of things like `Keys` and `CopyTo` if necessary
in the future.
This change removes the call to string.Split and a few substrings, and
replaces it with a tokenizer API. The tokenizer isn't really optimized
right now for compute - it should probably be an iterator- but it's a
significant improvement on what we're doing.
- Removed existing logger scopes as we want to minimize the number of scopes being created.
- Cleaned up tests related to removal of scopes.
- Added new log statements.
- Removed old logger structure base implementation and related tests. Added new tests also.