Reputation: 4977
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
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