MEF依赖注入实例

Posted 水中的空气

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
View Code

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     }
View Code

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; }
}
}
View Code
技术分享图片
 [Export(typeof (IAttachmentSiteService))]
    public class AttachmentSiteService : AttachmentService, IAttachmentSiteService
    {
        [Import]
        private IConversionLogService LogService { set; get; }

        [Import]
        private IContentFileMappingService MappingService { set; get; }
}
View Code

4.在controller头上加上  [Export],后面具体调用实现即可

技术分享图片
            WebSiteModel webSite = WebsiteSiteService.GetWebSiteById(id.Value);
View Code
哈哈,以上就完成了实现,就是这么简单,不过个人不喜欢这个依赖注入,对性能有一定的影响哦
 

以上是关于MEF依赖注入实例的主要内容,如果未能解决你的问题,请参考以下文章

.Net框架搭建之2SQL Server MEF依赖注入 MVC Repository框架

如何注入在 Windsor 注册的 MEF [ImportingConstructor] 依赖项?

MEF依赖注入无法在在构造函数中使用的解决办法

MEF学习总结---Primitive层

MEF学习总结---Container层

Android 片段和依赖注入