MEF依赖注入实例
什么是MEF
先来看msdn上面的解释:MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库。 应用程序开发人员可利用该库发现并使用扩展,而无需进行配置。 扩展开发人员还可以利用该库轻松地封装代码,避免生成脆弱的硬依赖项。 通过 MEF,不仅可以在应用程序内重用扩展,还可以在应用程序之间重用扩展。
也有人把MEF解释为“依赖注入”的一种方式,那么什么是“依赖注入”?如果这样解释,感觉越陷越深......根据博主的理解,了解MEF只需要抓住以下几个关键点:
(1)字面意思,可扩展的framework,或者叫可扩展的库。也就是说,使用MEF是为了提高程序的可扩展性。MEF会根据指定的导入导出自动去发现匹配的扩展,不需要进行复杂的程序配置。
(2)在设计层面上来说,为什么要使用MEF?为了“松耦合”!我们知道,程序设计有几个原则,“高内聚,低耦合”就是其中一个。使用MEF可以帮助我们减少内库之间的耦合。
实现MEF的注入工作
第一步:发现部件---这种方式是通过读取当前程序下的dll文件中的部件
第二步:为第一步中获取到的部件创建一个CompositionContainer实例
第三步:实现IDependencyResolver接口
第四步:注册到DependencyResolver
1.在Global.asax文件下的Application_Start方法执行的文件,里面有一个自定义的MefDependencySolver
DirectoryCatalog catalog = new DirectoryCatalog(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath); MefDependencySolver solver = new MefDependencySolver(catalog); DependencyResolver.SetResolver(solver);
2.定义创建了CompositionContainer对象实例,并继承接口IDependencyResolver实现方法,并最终完成注册到DependencyResolver。
1 public class MefDependencySolver : IDependencyResolver 2 { 3 private readonly ComposablePartCatalog _catalog; 4 private const string MefContainerKey = "MefContainerKey"; 5 6 public MefDependencySolver(ComposablePartCatalog catalog) 7 { 8 _catalog = catalog; 9 } 10 11 public CompositionContainer Container 12 { 13 get 14 { 15 if (!HttpContext.Current.Items.Contains(MefContainerKey)) 16 { 17 HttpContext.Current.Items.Add(MefContainerKey, new CompositionContainer(_catalog)); 18 } 19 CompositionContainer container = (CompositionContainer)HttpContext.Current.Items[MefContainerKey]; 20 HttpContext.Current.Application["Container"] = container; 21 return container; 22 } 23 } 24 25 #region IDependencyResolver Members 26 27 public object GetService(Type serviceType) 28 { 29 string contractName = AttributedModelServices.GetContractName(serviceType); 30 return Container.GetExportedValueOrDefault<object>(contractName); 31 } 32 33 public IEnumerable<object> GetServices(Type serviceType) 34 { 35 return Container.GetExportedValues<object>(serviceType.FullName); 36 } 37 38 #endregion 39 }
3.实现IDependencyResolver接口 [Export]导出, [Import]导入,同时在对应service上添加注入
[Export] public class BaseController : Controller { #region /// <summary> /// 登录 /// </summary> [Import] protected ILoginSiteService LoginSiteService { get; set; } /// <summary> /// 站点 /// </summary> [Import] protected IWebsiteSiteService WebsiteSiteService { get; set; } [Import] protected IWebAreaSiteService WebAreaSiteService { set; get; } } }
[Export(typeof (IAttachmentSiteService))] public class AttachmentSiteService : AttachmentService, IAttachmentSiteService { [Import] private IConversionLogService LogService { set; get; } [Import] private IContentFileMappingService MappingService { set; get; } }
4.在controller头上加上 [Export],后面具体调用实现即可
WebSiteModel webSite = WebsiteSiteService.GetWebSiteById(id.Value);