改削MusicBook的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.Composition; namespace MEFDemo { [Export("MusicBook",typeof(IBookService))] public class MusicBook : IBookService { public string BookName { get; set; } public string GetBookName() { return "MusicBook"; } } }
注意,标红的是窜自新的处所,其他处所的代码没有变,上一次我们使用的是Export的要领是[Export(typeof(IBookService))],此次前面多了一个参数,没错,这个就是一个契约名,名字可以随便起,而且可以反复,但是如果名字乱起,,和其他DLL中的反复,到时候会导致措施呈现很多Bug,最好凭据必然的规范去起名字。
这里有了契约名以后,导入(Import)时就要指定的契约名,否则将无法找到MusicBook,Export还有一个要领是[Export("Name")],这个要领只指定了契约名,没有指定导出类型,那么默认的导出类型是object类型,在导入时导出到的东西就要为object类型,否则将匹配不到阿谁组件。
到此刻,我们只写了一个接口和一个实现类,导出的也是一个类,下面我们多添加几个类来看看会怎么样,为了便利大家测试,我把实现接口的类写在一个文件里面,新加几个类后,的MusicBook类文件代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.Composition; namespace MEFDemo { [Export("MusicBook",typeof(IBookService))] public class MusicBook : IBookService { public string BookName { get; set; } public string GetBookName() { return "MusicBook"; } } [Export("MusicBook", typeof(IBookService))] public class MathBook : IBookService { public string BookName { get; set; } public string GetBookName() { return "MathBook"; } } [Export("MusicBook", typeof(IBookService))] public class HistoryBook : IBookService { public string BookName { get; set; } public string GetBookName() { return "HistoryBook"; } } }
这里添加两个类,HistoryBook和MathBook,都担任自IBookService接口,注意他们的契约名都不异,都为MusicBook,后面再详细的说这个问题,改削后的program的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; namespace MEFDemo { class Program { [ImportMany("MusicBook")] public IEnumerable<IBookService> Services { get; set; } static void Main(string[] args) { Program pro = new Program(); pro.Compose(); if (pro.Services != null) { foreach (var s in pro.Services) { Console.WriteLine(s.GetBookName()); } } Console.Read(); } private void Compose() { var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); CompositionContainer container = new CompositionContainer(catalog); container.ComposeParts(this); } } }
这里需要注意的是标红的两行代码,[ImportMany("MusicBook")]还有下面的声明酿成了IEnumerable<>,因为要导出多个实例,所以要用到调集,下面给与foreach遍历输出,运行的功效如下图:
一共三个,都输出了,对吧!是不是很好用啊,哈哈~~
固然,如果想全部输出,可以向第一篇文章中那样,导入和导出时都不写契约名,就会全部导出。那么写契约名有什么好处呢?
下面我们用代码说明问题,改削实现类的契约名如下: