用 MEF 拒绝坏的 DLL
Rejecting bad DLL's with MEF
我正在尝试使用插件和 MEF 设计一个可扩展的 GUI 应用程序。
现在大部分事情似乎都在按计划进行。然而,在某些情况下,我会有一个不符合我设计的契约的错误 DLL。我希望能够告诉 MEF 忽略错误的 DLL 并将其他所有内容保留在该目录中。有什么办法可以做到这一点(最好不要删除坏的 DLL)?
我读了一些书,注意到调用 dirCatalog.Parts.ToArray()
会帮助我捕捉到 ReflectionTypeLoadException
,它是在较早添加错误 DLL 时抛出的,这样我就有时间处理它(在将其添加到容器之前)。虽然这对调试目的有一点帮助,但我不想因为一个错误的 DLL 而使我的程序崩溃并且不加载整个目录。
这是我想出的一些(未完成的)代码。
private void appendToCatalog(DirectoryInfo rootDirInfo)
{
if (rootDirInfo.Exists)
{
DirectoryCatalog dirCatalog = new DirectoryCatalog(rootDirInfo.FullName, Constants.Strings.PLUGIN_EXTENSION);
try
{
// detect a problem with the catalog
dirCatalog.Parts.ToArray();
}
catch (ReflectionTypeLoadException ex)
{
// try to remove bad plugins
filterBadPlugins(dirCatalog);
}
catalog.Catalogs.Add(dirCatalog);
}
}
private void filterBadPlugins(DirectoryCatalog dirCatalog)
{
foreach (var part in dirCatalog.Parts)
{
// This should narrow down the problem to a single part
Type t = part.GetType();
// need to remove the part here somehow
}
}
最终,这是我的解决方案。这并不理想,但似乎可行。我将过滤方法与附加方法连接起来。
private void appendToCatalog(DirectoryTreeNode node)
{
DirectoryInfo info = node.Info;
FileInfo[] dlls = info.GetFiles("*.dll");
foreach (FileInfo fileInfo in dlls)
{
try
{
var ac = new AssemblyCatalog(Assembly.LoadFile(fileInfo.FullName));
ac.Parts.ToArray(); // throws exception if DLL is bad
catalog.Catalogs.Add(ac);
}
catch
{
// some error handling of your choice
}
}
}
我正在尝试使用插件和 MEF 设计一个可扩展的 GUI 应用程序。
现在大部分事情似乎都在按计划进行。然而,在某些情况下,我会有一个不符合我设计的契约的错误 DLL。我希望能够告诉 MEF 忽略错误的 DLL 并将其他所有内容保留在该目录中。有什么办法可以做到这一点(最好不要删除坏的 DLL)?
我读了一些书,注意到调用 dirCatalog.Parts.ToArray()
会帮助我捕捉到 ReflectionTypeLoadException
,它是在较早添加错误 DLL 时抛出的,这样我就有时间处理它(在将其添加到容器之前)。虽然这对调试目的有一点帮助,但我不想因为一个错误的 DLL 而使我的程序崩溃并且不加载整个目录。
这是我想出的一些(未完成的)代码。
private void appendToCatalog(DirectoryInfo rootDirInfo)
{
if (rootDirInfo.Exists)
{
DirectoryCatalog dirCatalog = new DirectoryCatalog(rootDirInfo.FullName, Constants.Strings.PLUGIN_EXTENSION);
try
{
// detect a problem with the catalog
dirCatalog.Parts.ToArray();
}
catch (ReflectionTypeLoadException ex)
{
// try to remove bad plugins
filterBadPlugins(dirCatalog);
}
catalog.Catalogs.Add(dirCatalog);
}
}
private void filterBadPlugins(DirectoryCatalog dirCatalog)
{
foreach (var part in dirCatalog.Parts)
{
// This should narrow down the problem to a single part
Type t = part.GetType();
// need to remove the part here somehow
}
}
最终,这是我的解决方案。这并不理想,但似乎可行。我将过滤方法与附加方法连接起来。
private void appendToCatalog(DirectoryTreeNode node)
{
DirectoryInfo info = node.Info;
FileInfo[] dlls = info.GetFiles("*.dll");
foreach (FileInfo fileInfo in dlls)
{
try
{
var ac = new AssemblyCatalog(Assembly.LoadFile(fileInfo.FullName));
ac.Parts.ToArray(); // throws exception if DLL is bad
catalog.Catalogs.Add(ac);
}
catch
{
// some error handling of your choice
}
}
}