简体   繁体   English

如何在MEF中的AggregateCatalog或DirectoryCatalog中枚举程序集?

[英]How to enumerate assemblies within AggregateCatalog or DirectoryCatalog in MEF?

I have a MEF (Microsoft Extension Framework) application which loads some assemblies from a folder. 我有一个MEF(Microsoft扩展框架)应用程序,它从一个文件夹加载一些程序集。 I need to enumerate the assemblies that produced any exports for my application. 我需要枚举为我的应用程序生成任何导出的程序集。

One way to do it is to enumerate imports calling GetExportedObject().GetType().Assembly . 一种方法是枚举调用GetExportedObject().GetType().Assembly导入。 But it would be cleaner to do this without instantiation of imports. 但如果没有实例化进口,这样做会更干净。 Is there a way to get loaded assemblies from a catalog or anything else? 有没有办法从目录或其他任何东西获取加载的程序集?

I need assemblies to get their attributes like copyright, version, name and such. 我需要程序集来获取他们的属性,如版权,版本,名称等。 My folder can contain both assemblies with exports and without ones, but I need only assemblies that satisfied any imports in the app. 我的文件夹可以包含带导出和没有导出的程序集,但我只需要满足应用程序中任何导入的程序集。

This is one way of doing it, and is used in Caliburn.Micro: 这是一种方法,用于Caliburn.Micro:

var aggregateCatalog = new AggregateCatalog(...);
var assemblies = aggregateCatalog.Parts
    .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
    .Distinct()
    .ToList();

Here is my current solution that works nicely: 这是我当前的解决方案很好地工作:

  1. Do not use DirectoryCatalog, load assemblies directly and create an AssemblyCatalog from them. 不要使用DirectoryCatalog,直接加载程序集并从中创建AssemblyCatalog。
  2. Use AssemblyCatalog.Parts to find out which assemblies have exports, let the user authorize them. 使用AssemblyCatalog.Parts找出哪些程序集具有导出,让用户授权它们。
  3. Add only authorized AssemblyCatalog's to the AggregateCatalog, which is ised in the composition. 仅将授权的AssemblyCatalog添加到AggregateCatalog中,该目录在组合中。

The AssemblyCatalog has an Assembly property. AssemblyCatalog具有Assembly属性。 The AggregateCatalog does not have a way to get this information directly- there's no guarantee that the inner catalogs even load their parts from an assembly. AggregateCatalog无法直接获取此信息 - 无法保证内部目录甚至可以从程序集中加载其零件。 The DirectoryCatalog doesn't have this capability although it might be possible to add it if there was a good reason. DirectoryCatalog没有此功能,但如果有充分的理由可以添加它。

Why do you want to get the list of assemblies? 为什么要获取程序集列表? You may be better off not using a directory catalag, instead just scan and load the assemblies in a directory yourself, and create an AssemblyCatalog for each one and add it to an AggregateCatalog. 您可能最好不使用目录catalag,而只是自己扫描并加载目录中的程序集,并为每个程序集创建一个AssemblyCatalog并将其添加到AggregateCatalog。

EDIT: MEF doesn't have a way of getting a list of all the exports that were "used" in composition. 编辑:MEF无法获得在合成中“使用”的所有导出列表。 You could probably write your own catalog which would return part definitions that were shells around the default part definitions and kept track of which parts had GetExportedObject called on them. 您可以编写自己的目录,该目录将返回围绕默认零件定义的零件定义,并跟踪哪些零件已在其上调用GetExportedObject。 You can use the APIs in ReflectionModelServices to figure out which type corresponds to a given part definition from the default catalogs. 您可以使用ReflectionModelServices中的API来确定哪个类型对应于默认目录中的给定零件定义。 Note that writing such a catalog would probably not be a simple undertaking. 请注意,编写此类目录可能不是一项简单的任务。

If you have access to source of those assemblies then I have an alternative solution to adding assemblies one by one. 如果您可以访问这些程序集的源代码,那么我可以选择逐个添加程序集。 You can create an interface called IModule and make it a requirement for all of your assemblies to Export that. 您可以创建一个名为IModule的接口,并将其作为导出它的所有程序集的要求。 Then you can ImportAll them into your bootstraper: 然后你可以将它们导入你的bootstraper:

[ImportMany]
public List<IModule> Modules { get; set; }

This list will contain a list of all Module classes through which you can access the assembly: 此列表将包含可通过其访问程序集的所有Module类的列表:

var module1 = Logic.Instance.Modules[0];
var fullename = module1.GetType().Assembly.FullName;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM