Ed Sinek
Ed Sinek

Reputation: 4977

Unity ResolutionFailedException for System.Web.Mvc Types

My WebApp is a combination of WebForms pages and MVC 4 pages.

Using Unity, I am getting the following exception.

Exception Type:

Microsoft.Practices.Unity.ResolutionFailedException, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

Message:

Resolution of the dependency failed, type = "System.Web.Mvc.ModelMetadataProvider", name = "(none)".  Exception occurred while: while resolving.  Exception is: InvalidOperationException - The type ModelMetadataProvider does not have an accessible constructor.  At the time of the exception, the container was:
Resolving System.Web.Mvc.ModelMetadataProvider,(none)

with an Inner Exception of:

Message:

The type ModelMetadataProvider does not have an accessible constructor.

Stack Trace:

at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObje ct(IBuilderContext context)  
at BuildUp_System.Web.Mvc.ModelMetadataProvider(IBuilderContext )  
at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)  
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)  
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)  
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)  

I consistently get the same resolution exception for the following types:

System.Web.Mvc.ITempDataProvide  
System.Web.Mvc.Async.IAsyncActionInvoker  
System.Web.Mvc.IActionInvoker  
System.Web.Mvc.ModelMetadataProvider  
System.Web.Mvc.IViewPageActivator

In Application_Start, I am setting up the IoC with:

DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfigurator.GetContainer()));

...where GetContainer returns all the registered types and UnityDependencyResolver is-a IDependencyResolver

Any ideas what is causing the issue?

Thanks,
--Ed

Upvotes: 2

Views: 2325

Answers (1)

Lucian
Lucian

Reputation: 78

I am not sure how the container instance returned by UnityConfigurator.GetContainer() behaves exactly, but I assume it tries to resolve by itself alone the ModelMetadataProvider when needed. This ModelMetadataProvider has some dependencies that your container does not know that only the initial MVC resolver can resolve. By 'initial MVC resolver' I mean the result of DependencyResolver.Current before you call DependencyResolver.SetResolver(...). So, you need to implement a proxy over your own container and use as fallback the initial MVC resolver.

A quick example of how the proxy's implementation should look like:

public class MvcDependencyResolver:System.Web.Mvc.IDependencyResolver
{
    private readonly IDependencyResolver _resolver;

    private readonly System.Web.Mvc.IDependencyResolver _fallbackResolver;

    public MvcDependencyResolver(IDependencyResolver resolver, System.Web.Mvc.IDependencyResolver fallbackResolver)
    {
        this._resolver = resolver;
        this._fallbackResolver = fallbackResolver;
    }

    public object GetService(Type serviceType)
    {
        if ((this._resolver.IsRegistered(serviceType)) || (serviceType.IsClass))
        {
            try
            {
                return this._resolver.GetService(serviceType);
            }
            catch (ResolutionFailedException)
            {
            }
        }
        return this._fallbackResolver.GetService(serviceType);
    }

And then, in Application_Start() you overwrite the MVC resolver with a instance of this proxy, like this:

var bootstrapper = new Bootstrapper();
var resolver = bootstrapper.Run();
DependencyResolver.SetResolver(new MvcDependencyResolver(resolver, DependencyResolver.Current));

Upvotes: 2

Related Questions