【发布时间】:2013-11-19 14:07:30
【问题描述】:
提前感谢您查看此问题!
我正在使用 MEF 在项目中加载一些程序集。一切都很好,直到我们更改了包含接口的文件的名称。
为了更清楚,我先总结一下事情发生的场景,然后事情发生的场景,然后在没有发生的情况下具体展示异常和导致异常的代码。
工作场景如下:
我们有一个名为 IPlugin 的接口,它在名为 Common-1-0.dll 的程序集中定义。
我们有一些针对 Common-1-0.dll 编译的插件程序集。
加载插件的应用程序是针对 Common-1-0.dll 编译的。
这是不工作的场景:
我们有一个名为 IPlugin,它在名为 Common-1-1.dll 的程序集中定义。接口从 Common-1-0.dll 没有变化。
我们有一些针对 Common-1-0.dll 编译的插件程序集。
加载插件的应用程序是针对 Common-1-1.dll 编译的。
现在的问题:
当我在第二个场景中运行下面的代码时,我得到一个 CompositionException(如下面的代码所示)。这似乎是因为插件是针对 Common-1-0.dll 编译的,而尝试进行组合的应用程序是针对 Common-1-1.dll 编译的。两个文件之间的代码没有任何变化,只是名称。
所以我们希望能够加载针对任何程序集构建的插件,只要该程序集导出正确的接口,但我不确定我是否可以使用 MEF 做到这一点。这就是我想知道这个问题的结果。
代码:
private void LoadPlugins(string directory, string searchPattern = "", bool recursive = false)
{
Trace.Agent.Status("Loading plugin(s) from {0}{1}{2}", directory, Path.DirectorySeparatorChar, searchPattern);
try
{
var directoryCatalog = string.IsNullOrEmpty(searchPattern)
? new DirectoryCatalog(directory)
: new DirectoryCatalog(directory, searchPattern);
_container = new CompositionContainer(new AggregateCatalog(directoryCatalog));
_container.ComposeParts(this);
}
catch (CompositionException exc)
{
Trace.Agent.Exception(exc);
}
if (recursive)
{
foreach (string dir in Directory.GetDirectories(directory))
{
LoadPlugins(Path.Combine(directory, dir), recursive:true);
}
}
}
组合异常:
导出 'TestPlugin.TestPlugin (ContractName="Common.IPlugin")' 不能分配给类型 'Common.IPlugin'。
【问题讨论】:
-
您是否尝试使用程序集绑定重定向?
-
这个我不熟悉,没试过,但我会研究一下。
-
如果程序集的名称实际上不同,您认为程序集绑定重定向会起作用吗?用它指定一个通用名称并让它使用更新版本看起来相当容易,但是有一个例子,当你看到'common-1-0.dll'时说使用'common-1-1.dll '?
-
它不查找 dll 的名称,它会查找
publicKeyToken。您必须签署您的程序集并使用相同的密钥编译程序集的两个版本,以便 publicKeyToken 不会更改。这样,您可以定义从版本 0.0.0.0-1.1.0.0 到 1.1.0.0 的重定向,这意味着一切都应该使用新版本。 -
好吧抱歉,当然两个 dll 的程序集名称必须相同。因此,如果您对这些程序集(以版本为后缀)确实有不同的名称,那么您就是...