C# 在运行时检测MEF程序集

C# 在运行时检测MEF程序集,c#,mef,C#,Mef,我有一个包含许多.dll的目录,其中一些是MEF插件,我正在使用DirectoryCatalog加载这些插件-例如: var catalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); 这会将执行目录的主机上的所有程序集加载到目录中。但是,我只希望构建MEF组件(即可组合零件)的目录 有没有办法检测MEF部件?那些没有MEF部件的部件对DirectoryCata

我有一个包含许多.dll的目录,其中一些是MEF插件,我正在使用
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);