我有一个 MEF(Microsoft 扩展框架)应用程序,它从文件夹中加载一些程序集。我需要枚举为我的应用程序生成任何导出的程序集。
一种方法是枚举导入调用GetExportedObject().GetType().Assembly
。但是在没有导入实例的情况下这样做会更干净。有没有办法从目录或其他任何东西中获取加载的程序集?
我需要程序集来获取它们的属性,如版权、版本、名称等。我的文件夹可以包含带导出和不带导出的程序集,但我只需要满足应用程序中任何导入的程序集。
这是一种方法,在 Caliburn.Micro 中使用:
var aggregateCatalog = new AggregateCatalog(...);
var assemblies = aggregateCatalog.Parts
.Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
.Distinct()
.ToList();
AssemblyCatalog 有一个 Assembly 属性。AggregateCatalog 无法直接获取此信息 - 无法保证内部目录甚至从装配中加载其零件。DirectoryCatalog 没有此功能,但如果有充分的理由可以添加它。
为什么要获取程序集列表?您最好不要使用目录目录,而是自己扫描并加载目录中的程序集,然后为每个程序集创建一个 AssemblyCatalog 并将其添加到 AggregateCatalog。
编辑:MEF 没有办法获取在合成中“使用”的所有导出列表。您可能会编写自己的目录,该目录将返回作为默认部件定义外壳的部件定义,并跟踪哪些部件调用了 GetExportedObject。您可以使用 ReflectionModelServices 中的 API 来确定哪种类型对应于默认目录中的给定部件定义。请注意,编写这样的目录可能不是一项简单的工作。
这是我当前运行良好的解决方案:
如果您可以访问这些程序集的源代码,那么我可以使用另一种解决方案来逐个添加程序集。您可以创建一个名为 IModule 的接口,并将其作为所有程序集导出的要求。然后你可以将它们全部导入你的引导程序:
[ImportMany]
public List<IModule> Modules { get; set; }
此列表将包含所有 Module 类的列表,您可以通过这些类访问程序集:
var module1 = Logic.Instance.Modules[0];
var fullename = module1.GetType().Assembly.FullName;