This change makes the allocation of DataTokens and Values on RouteData
lazy, and elides copies when copying an 'empty' RouteData.
In our current architecture this change will eliminiate 2 * (N + 1)
dictionary allocations/copies per request, where N is the number of routes
processed. In a large system with lots of attribute routes, this number
could be very significant.
For a small MVC site (ModelBinding, Validation, Views) with one route, it
still shows a modest reduction of dictionary allocations without adding
much complexity.
This change fixes call sites on the main request path for a simple site
(model binding, validation, views) that allocate boxed list enumerators.
Some cases aren't addressed by this change because the fix is too invasive
or requires changing an important contract to take IList instead of
IEnumerable. Will follow up on those case by case in order of importance.
- #2969
- add `ModelBindingMessages` for configuration and `IBindingMetadataProvider` overrides
- use `interface` to avoid `new` oddities when adding a setter to an `abstract` property
- add `IModelBindingMessages` to `ModelMetadata` for use in rest of the product code
- plumb the various bits through the system
- add integration tests using a custom `IBindingMetadataProvider`s to override messages
nits:
- remove unused resources
- use `AttemptedValue` and not `model` in `SimpleTypeModelBinder`
This change works around two mono issues that are blocking travis. I'd
like to have tests skip instead, but unfortunately that would mean not
running any validation tests on mono so this seems better.
- RuntimeHelpers.GetHashCode will sometimes crash the runtime
- PropertyHelper sometimes returns throws null-ref