如何将MEF与ASP.NET MVC 4和ASP.NET Web API集成
在同一个项目中,如何将Managed Extensibility Framework(MEF)与ASP.NET MVC 4和ASP.NET Web API集成?
考虑一个示例应用程序,带有一个MVC控制器HomeController
和一个Web API控制器ContactController
。 两者都有一个IContactRepository
类型的属性,它们依赖于MEF来解决。 问题是如何将MEF插入MVC和Web API,以便通过MEF创建实例。
HomeController的:
/// <summary>
/// Home controller. Instruct MEF to create one instance of this class per importer,
/// since this is what MVC expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
[Import]
private IContactRepository _contactRepository = null;
public ActionResult Index()
{
return View(_contactRepository.GetAllContacts());
}
}
的ContactController:
/// <summary>
/// Contact API controller. Instruct MEF to create one instance of this class per importer,
/// since this is what Web API expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ContactController : ApiController
{
[Import]
private IContactRepository _contactRepo = null;
public Contact[] Get()
{
return _contactRepo.GetAllContacts();
}
}
IContactRepository和ContactRepository:
public interface IContactRepository
{
Contact[] GetAllContacts();
}
[Export(typeof(IContactRepository))]
public class ContactRepository : IContactRepository
{
public Contact[] GetAllContacts()
{
return new Contact[] {
new Contact { Id = 1, Name = "Glenn Beck"},
new Contact { Id = 2, Name = "Bill O'Riley"}
};
}
}
联系:
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
}
解决方案是实现System.Web.Mvc.IDependencyResolver和System.Web.Http.Dependencies.IDependencyResolver,并分别在您的Application_Start
方法中向ASP.NET MVC和ASP.NET Web API注册您的实现。
在这个例子中,我们将创建一个MefConfig
类,它实现了一个从Application_Start
调用的方法RegisterMef
,以安装我们的依赖解析器。 MefDependencyResolver
类实现了System.Web.Mvc.IDependencyResolver
和System.Web.Http.Dependencies.IDependencyResolver
并且同样处理了MVC和Web API的依赖关系解析任务。
Application_Start,把它放在你的Global.asax.cs中:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
[...]
MefConfig.RegisterMef();
}
}
MefDependencyResolver和MefConfig:
/// <summary>
/// Resolve dependencies for MVC / Web API using MEF.
/// </summary>
public class MefDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly CompositionContainer _container;
public MefDependencyResolver(CompositionContainer container)
{
_container = container;
}
public IDependencyScope BeginScope()
{
return this;
}
/// <summary>
/// Called to request a service implementation.
///
/// Here we call upon MEF to instantiate implementations of dependencies.
/// </summary>
/// <param name="serviceType">Type of service requested.</param>
/// <returns>Service implementation or null.</returns>
public object GetService(Type serviceType)
{
if (serviceType == null)
throw new ArgumentNullException("serviceType");
var name = AttributedModelServices.GetContractName(serviceType);
var export = _container.GetExportedValueOrDefault<object>(name);
return export;
}
/// <summary>
/// Called to request service implementations.
///
/// Here we call upon MEF to instantiate implementations of dependencies.
/// </summary>
/// <param name="serviceType">Type of service requested.</param>
/// <returns>Service implementations.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
if (serviceType == null)
throw new ArgumentNullException("serviceType");
var exports = _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
return exports;
}
public void Dispose()
{
}
}
public static class MefConfig
{
public static void RegisterMef()
{
var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(asmCatalog);
var resolver = new MefDependencyResolver(container);
// Install MEF dependency resolver for MVC
DependencyResolver.SetResolver(resolver);
// Install MEF dependency resolver for Web API
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
}
你可以看看这个http://kennytordeur.blogspot.be/2012/08/mef-in-aspnet-mvc-4-and-webapi.html。 它解释了如何在Asp.net MVC 4 / Web Api项目中使用MEF。 还有一个基于这个代码的Nuget包。 这样你就可以非常方便快速地进行测试。
@ aknuds1答案是迄今为止我看到的将MEF集成到DependencyResolver中最好的答案。 我能够很容易地将它扩展到MEF2中使用基于约定的组合。 MefConfig类是所有需要改变,然后不是太多。
/// <summary>
/// Responsible for configuring MEF for the application.
/// </summary>
public static class MefConfig
{
/// <summary>
/// Registers MEF conventions and exports.
/// </summary>
public static void RegisterMef()
{
// Register MVC/API conventions
var registrationBuilder = new RegistrationBuilder();
registrationBuilder.ForTypesDerivedFrom<Controller>().SetCreationPolicy(CreationPolicy.NonShared).Export();
registrationBuilder.ForTypesDerivedFrom<ApiController>().SetCreationPolicy(CreationPolicy.NonShared).Export();
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), registrationBuilder);
var aggregateCatalog = new AggregateCatalog(assemblyCatalog);
var container = new CompositionContainer(aggregateCatalog);
var resolver = new MefDependencyResolver(container);
// Install MEF dependency resolver for MVC
DependencyResolver.SetResolver(resolver);
// Install MEF dependency resolver for Web API
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
}
链接地址: http://www.djcxy.com/p/20385.html
上一篇: How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API