MEF框架学习之旅(十)重组

重新组合是 MEF 的一项功能,此功能允许部件在系统中出现新的匹配导出时自动更新其导入。重新组合在某些方案中十分有用,AllowRecomposition=true参数就表示运行在有新的部件被装配成功后进行部件集的重组。

例如从远程服务器下载部件时。SalesOrderManager 可以进行更改,以便在其启动时,可启动多个可选视图的下载。这些视图显示时,会出现在视图工厂中。为了使 ViewFactory 可重新组合,我们在 Views 属性的 ImportMany 特性上将 AllowRecomposition 属性设置为 true,如下所示:

代码段

[Export]
public class ViewFactory
{
[ImportMany(AllowRecomposition=true)]
IEnumerable<Lazy<IView, IViewMetadata>> Views { get; set; }

public IEnumerable<View>GetViews(ViewTypesviewType) 
{
return Views.Where(v=>v.Metadata.ViewType.Equals(viewType)).Select(v=>v.Value); } }

 

进行重新组合时,Views 集合将立刻替换为包含一组更新过的视图的新集合。

启用重新组合后,应用程序可从服务器下载其他程序集并将这些程序集添加到容器。可通过 MEF 的目录执行此操作。MEF 提供了多个目录,其中有两个目录可重新组合。DirectoryCatalog(您已看到过)是可通过调用其 Refresh 方法来重新组合的目录。另一个可重新组合的目录是 AggregateCatalog,这是目录的目录。您可使用 Catalogs 集合属性向该目录添加目录,这会启动重新组合。我将使用的最后一个目录是 AssemblyCatalog,该目录接受一个它随后将在其之上构建目录的程序集。 2 演示一个示例,说明如何结合使用这些目录进行动态下载。

图 2 使用 MEF 目录进行动态下载

代码段

void App_Startup(object sender, StartupEventArgs e)
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(newDirectoryCatalog((@"\.")));
var container = new CompositionContainer(catalog);
container.Composeparts(this);
base.MainWindow = MainWindow;
this.DownloadAssemblies(catalog);
}
 
private void DownloadAssemblies(AggregateCatalog catalog)
{
//asynchronously downloads assemblies and calls AddAssemblies
}
 
private void AddAssemblies(Assembly[] assemblies, AggregateCatalog catalog)
{
var assemblyCatalogs = new AggregateCatalog();
foreach(Assembly assembly in assemblies)
assemblyCatalogs.Catalogs.Add(new AssemblyCatalog(assembly));
catalog.Catalogs.Add(assemblyCatalogs);
}

2 中的容器是使用 AggregateCatalog 创建的。该容器随后将 DirectoryCatalog 添加到其中,以在 bin 文件夹中获取本地部件。聚合目录会传递到 DownloadAssemblies 方法,该方法异步下载程序集,然后调用 AddAssemblies。该方法会创建新的 AggregateCatalog,向该目录为每个下载程序集添加 AssemblyCatalogs。然后,AddAssemblies 添加包含主要聚合的程序集的 AggregateCatalog。它之所以采用这种方式进行添加,是为了一次性完成重新组合,而不是反复进行(在直接添加程序集目录时会出现这种情况)。

进行重新组合时,集合会立即更新。结果因集合属性类型而异。如果属性类型是 IEnumerable<T>,则它将替换为新实例。如果它是继承自 List<T> 或 ICollection 的具体集合,则 MEF 将对每一项依次调用 Clear 和 Add。无论是哪一种情况,都意味着在使用重新组合时必须考虑线程安全。重新组合不仅与添加有关,也与删除有关。如果从容器中移除目录,则也会移除这些部件。

相关阅读:

MEF框架学习之旅(十一)调试

MEF框架学习之旅(十)重组

MEF框架学习之旅(九)部件生命周期及组装通知

MEF框架学习之旅(八)避免发现

MEF框架学习之旅(七)部件的创建规则(策略)

MEF框架学习之旅(六)元数据和元数据视图

MEF框架学习之旅(五)导入导出(下)

MEF框架学习之旅(四)导入导出(上)

MEF框架学习之旅(三)组合

MEF框架学习之旅(二)契约

MEF框架学习之旅(一)概念

posted @ 2013-06-10 09:57  一个人在北京  阅读(1280)  评论(0编辑  收藏  举报