Reputation: 349
I am new to MEF and played around with MVC and it's working alright. However, when I tried with Web API, external api controllers weren't resolved. Here's my code for the DependencyResolver:
public class MefDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver, IDependencyResolver
{
private readonly CompositionContainer _container;
public MefDependencyResolver(CompositionContainer container)
{
this._container = container;
}
public object GetService(Type serviceType)
{
string name = AttributedModelServices.GetContractName(serviceType);
var service = this._container.GetExportedValueOrDefault<object>(name);
return service;
}
public IEnumerable<object> GetServices(Type serviceType)
{
string name = AttributedModelServices.GetContractName(serviceType);
try
{
var service = this._container.GetExportedValues<object>(name);
return service;
}
catch
{
return new object[] { };
}
}
public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{}
}
and here's how it was used:
var _resolver = new MefDependencyResolver(_container);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = _resolver;
and here's the external api controller:
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
but when I visit my site:
http://localhost:65232/api/values
I got this error:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:65232/api/values'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'values'.
</MessageDetail>
</Error>
the same container works with my MVC Controller but can't seem to make it work with API controllers.
Am I missing anything?
Upvotes: 0
Views: 1052
Reputation: 10323
There are two interfaces involved here, both with the same name IDependencyResolver
hence the confusion. One is for MVC, and one is for Web API.
I solved it like this. I have:
public class WebApiDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
...
}
and
public class MvcDependencyResolver : WebApiDependencyResolver, System.Web.Mvc.IDependencyResolver
{
public MvcDependencyResolver(CompositionContainer container)
: base(container)
{
}
}
The MvcDependencyResolver
inherits from the WebApiDependencyResolver
to avoid code duplication.
Then you need to register the resolver with MVC and Web API. So somewhere in your startup code you should have something like this:
var resolver = new MvcDependencyResolver(Container);
System.Web.Mvc.DependencyResolver.SetResolver(resolver); // install MEF dependency resolver for MVC
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = resolver; // install MEF dependency resolver for Web API
Having said all this, I personally wouldn't go with MEF for controller resolution as it introduces a memory leak because MEF keeps references to IDisposable
types and ApiController
is IDisposable
.
Upvotes: 2