C#进阶系列
第四章 【C#进阶系列】【MEF框架(四)】
第三章 【C#进阶系列】【MEF框架(三)】
第二章 【C#进阶系列】【MEF框架(二)】
第一章 【C#进阶系列】【MEF框架(一)】
前言
在(一)已经对MEF作了基本的介绍,这里针对MEF的延迟加载、元数据作介绍。
一、延迟加载
Lazy<T, TMetadata> 是由 MEF 提供来保存对导出的间接引用的类型。 除了导出对象本身,你还可以获取导出元数据或描述导出对象的信息。
每个Lazy<T, TMetadata> 都包含一个代表实际操作的 IOperation 对象和一个代表元数据的 IOperationData 对象。
延迟加载在导出部件处的设置没什么变化,保持原有的设置即可。
在导入的时候,需要使用.NET提供的Lazy类来完成。
通过Lazy封装的对象即自动提供了延迟加载的机制。访问对象的方式也略微有所改变,当然不能直接通过属性(pro.Services_MathBook.GetBookName())进行访问,而是需要通过Lazy.Value(pro.Services_MathBook.Value.GetBookName())来访问,此属性值包含的即使延迟加载的对象。
另外Lazy.IsValueCreated属性提供了判断对象是否加载的功能,如果为true则表示对象已加载,否则为未加载。
namespace MEF_P1
{
public interface IBookService
{
string BookName {
get; set; }
string GetBookName();
}
[Export("ContractName_MathBook", typeof(IBookService))]
public class MathBook : IBookService
{
public string BookName {
get; set; }
public string GetBookName()
{
return "MathBook";
}
}
[Export("ContractName_ChineseBook", typeof(IBookService))]
public class ChineseBook : IBookService
{
public string BookName {
get; set; }
public string GetBookName()
{
return "ChineseBook";
}
}
class Program
{
[Import("ContractName_MathBook", typeof(IBookService))]
public Lazy<IBookService> Services_MathBook {
get; set; }
[Import("ContractName_ChineseBook", typeof(IBookService))]
public Lazy<IBookService> Services_ChineseBook {
get; set; }
static void Main(string[] args)
{
Program pro = new Program();
pro.Compose();
if (pro.Services_MathBook != null)
{
Console.WriteLine(pro.Services_MathBook.Value.GetBookName());
}
if (pro.Services_ChineseBook != null)
{
Console.WriteLine(pro.Services_ChineseBook.Value.GetBookName());
}
Console.Read();
}
private void Compose()
{
//创建一个程序集目录,用于从一个程序集获取所有的组件定义
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
//创建容器
CompositionContainer container = new CompositionContainer(catalog);
//组合部件:如果该类有Import,就会自动去寻找Export
container.ComposeParts(this);
}
}
}
总结
依赖倒置原则:高层模板不应该依赖于底层模板,两者应该依赖于抽象,而抽象不应该依赖于细节。