StructureMap.Microsoft.DependencyInjection icon indicating copy to clipboard operation
StructureMap.Microsoft.DependencyInjection copied to clipboard

Resolving MvcRouteHandler

Open dazinator opened this issue 7 years ago • 4 comments

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?

dazinator avatar Apr 29 '18 16:04 dazinator

Hmm. That's weird. I thought we would only pick constructors we could satisfy. Why is IActionContextAccessor used, but not registered is another question.

khellang avatar Apr 29 '18 17:04 khellang

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.

dazinator avatar May 21 '18 15:05 dazinator

I'll have a go at creating a replication test to see if this is some issue with AspNetConstructorSelector and child containers.

dazinator avatar May 21 '18 17:05 dazinator

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?

dazinator avatar Jul 27 '19 10:07 dazinator