使用MEF延迟加载DLL

我正在用MEF做我的第一个项目,我很难理解如何使用延迟加载。 我的代码是 –

public static class MefLoader { private static CompositionContainer Container; [ImportMany(typeof(IControlModule), AllowRecomposition = true)] private static IEnumerable<Lazy> DllList { get; set; } static MefLoader() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(".")); Container = new CompositionContainer(catalog); } 

我理解大多数如何使用MEF,除了我没有看到如何初始化DllList对象。 我想使用延迟加载,因为在最终系统中,我们有很多选项,任何时候都只会使用大约10%。

首先,您尝试将对象导入静态属性。 MEF不支持这一点:MEF组成对象 ,而不是 。 如果要初始化静态属性,则必须手动执行此操作:

 DllList = container.GetExports(); 

现在关于延迟加载: DirectoryCatalog为目录中的每个程序集创建一个AssemblyCatalog 。 一旦调用AssemblyCatalog ,MEF中的AssemblyCatalog实现将枚举程序集中的所有类型,这将从容器中拉出导出时发生。 这意味着即使在MEF确定它包含实际需要的部件之前,也会加载该组件。

为了真正延迟加载程序集,需要在某处缓存有关哪些部件在这些程序集中可用的信息。 MEF目前没有开箱即用的内置缓存机制。 但是, 在codeplex中的MEF源代码中包含的示例中有一个ComposablePartCatalogAssemblyCache实现。

Lazy唯一能做的就是推迟调用部件构造函数的那一刻。 这可以加快速度,但不会推迟加载程序集。

关于MEF的好处是(默认情况下) 没有初始化对象; MEF将匹配任何与您的导入匹配的声明[导出],然后MEF将为您输入。 如果您的依赖项本身具有依赖项,MEF将继续沿着链继续,直到您的整个图形得到解决。

使用Lazy(而不是T)只意味着实例化将被延迟,直到您访问该依赖项。 如果您正在调试,并且您没有看到何时初始化该依赖项,则需要访问Value属性以启动实例化。

MEF和大多数其他IoC容器之间存在一些重大差异(因为MEF仅关注可扩展性/组合),但它类似于IoC容器在注册类型后将在解析某些内容时实例化依赖关系的方式。

如果您对如何更改某些实例化行为感到好奇,那么有关创建策略的一些细节: http : //mef.codeplex.com/wikipage?title = Items%20Lifetime

这是一个非常古老的问题,但对于寻找解决方案的任何人来说,我最近实现了一个LazyAssemblyCatalog ,它允许延迟加载插件程序集,同时仍然可以在不加载这些程序集的情况下使插件元数据可用。 它的概念与@Wim在他的回答中提到的CachedAssemblyCatalog非常相似。 我希望这会对任何人有所帮助。