C# 在运行时检测MEF程序集
我有一个包含许多.dll的目录,其中一些是MEF插件,我正在使用C# 在运行时检测MEF程序集,c#,mef,C#,Mef,我有一个包含许多.dll的目录,其中一些是MEF插件,我正在使用DirectoryCatalog加载这些插件-例如: var catalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); 这会将执行目录的主机上的所有程序集加载到目录中。但是,我只希望构建MEF组件(即可组合零件)的目录 有没有办法检测MEF部件?那些没有MEF部件的部件对DirectoryCata
DirectoryCatalog
加载这些插件-例如:
var catalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
这会将执行目录的主机上的所有程序集加载到目录中。但是,我只希望构建MEF组件(即可组合零件)的目录
有没有办法检测MEF部件?那些没有MEF部件的部件对DirectoryCatalog.parts没有任何影响,因此MEF已经为您进行了检测 如果您觉得扫描所有部件的MEF零件对性能的影响太大,则可以使用以下方式对DLL名称进行筛选:
var catalog = new DirectoryCatalog(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"*.plugins.dll");
这里有一个类,您应该能够直接访问它并使用它来修复ReflectionTypeLoadException问题
using System;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Your.Namespace
{
public class SafeDirectoryCatalog : AggregateCatalog
{
public SafeDirectoryCatalog(string folderLocation)
{
var di = new DirectoryInfo(folderLocation);
if (!di.Exists) throw new Exception("Folder not exists: " + di.FullName);
var dlls = di.GetFileSystemInfos("*.dll");
foreach (var fi in dlls)
{
try
{
var ac = new AssemblyCatalog(Assembly.LoadFile(fi.FullName));
var parts = ac.Parts.ToArray(); // throws ReflectionTypeLoadException
this.Catalogs.Add(ac);
}
catch (ReflectionTypeLoadException ex)
{
//Swallow this exception
}
}
}
}
}
为什么不把MEF程序集放在一个单独的文件夹中呢?可以,但不是一个理想的解决方案…特别是当插件有依赖的DLL,它们应该与运行locationWell的插件在同一个目录中时,我使用的插件附带的所有软件都将它们存储在“插件”或类似的子文件夹中。所以我不认为这是一个坏的选择。嗯……我喜欢你的解决方案,但仍然不理想。为了解决您的第一个问题,当您最终从程序集构建一个
合成容器时,它将对任何非mef程序集抛出一个异常……因此目录
的检测功能不适用于purpose@aateeque:这不是预期的行为。你有什么例外?是的,你是对的,我道歉CompositionContainer
构造很好…当后续尝试GetExports
即获取容器中每个程序集中的导出类型时,问题就会出现。这有意义吗?@aateeque:这仍然不应该导致异常,至少不仅仅是因为目录目录包含没有MEF零件的部件。尽管第一次调用时,GetExports
将导致枚举所有程序集中的类型,如果您有不可加载的类型,这可能会导致ReflectionTypeLoadException
。但这并不是MEF特有的问题。它通常只是意味着在构建文件夹中有一个失效的程序集,该程序集引用了不再存在的类型。这就是为什么我问您会遇到什么样的异常。当我执行GetExports()
时,我会遇到ReflectionTypeLoadException
,干杯!这有助于:)示例用法:var catalog=new safedirectorycalog(AppDomain.CurrentDomain.BaseDirectory);var容器=新的合成容器(目录);container.SatisfyImportsOnce(MyMEFCatalog.Instance);