StructureMap.Microsoft.DependencyInjection
StructureMap.Microsoft.DependencyInjection copied to clipboard
Resolving MvcRouteHandler
I have an asp.net core 2.0 application.
In startup I am calling services.AddMvc();
This registers MvcRouteHandler as a singleton.
MvcRouteHandler has two constructors. The greediest one takes an IActionContextAccessor which AFAIK is not ever registered.
When I call app.UseMvc() - it tries to resolve MvcRouteHandler. I then see this exception:
StructureMap.StructureMapConfigurationException: 'No default Instance is registered and cannot be automatically determined for type 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor'
There is no configuration specified for Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor
1.) new MvcRouteHandler(Default of IActionInvokerFactory, Default of IActionSelector, Default of DiagnosticSource, Default of ILoggerFactory, Default of IActionContextAccessor) 2.) Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler 3.) Instance of Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler 4.) Container.GetInstance(Microsoft.AspNetCore.Mvc.Internal.MvcRouteHandler)
What would be the best way to proceed?
Hmm. That's weird. I thought we would only pick constructors we could satisfy. Why is IActionContextAccessor used, but not registered is another question.
Have investigated a bit more.
When I AddMvc() at the root container level, and then the root container is asked to resolve MvcRouteHandler - the AspNetConstructorSelector inspects the constructors of MvcRouteHandler and finds that it CanSatisfy the shortest one. Everything works.
However, if I don't configure the root container, and instead create and configure a child container, calling AddMvc() instead at the child container level, then when the child container is asked to resolve MvcRouteHandler the AspNetConstructorSelector finds that it can't satisfy either constructor. It's like it is not seeing the registered services anymore.
This is a bit of a complicated scenario, but this is as far as I have got so far.
I'll have a go at creating a replication test to see if this is some issue with AspNetConstructorSelector and child containers.
I have a sneaking suspicion this may be because the root container is populated from an IServiceCollection passed in from the WebHostBuilder already primed with 60+ services by default. When creating the Child Container and populating it from a new ServiceCollection, that new ServiceCollection isn't primed in the same way - I.e it doesn't have the 60+ services from the WebHost - although they are registered in the parent container, perhaps this causes AspNetConstructirSelector to think it cant satisfy the services registered in the child container because it doesn't check whether they are registered in the parent?