我与MEF实验发现并创建了一个测试程序来调用实现某个给定的接口“插件”,它遵循新的DLL:调用刷新()在DirectoryCatalog抛出ChangeRejectedException如果目录
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProbeContract
{
public interface IProbe
{
int DoProbe(string what);
List<string> GetCapabilities();
}
}
我创建了一个样例控制台程序,它从它自己的程序集中加载“插件”,并且如果发现的话,从一个指令中加载其他DLL。该程序工作确定插件目录是否为空(仅调用“本机”插件),或者它具有兼容的DLL开始。但是...如果在循环迭代之间添加新的DLL,则DirectoryCatalog的Refresh()方法抛出ChangeRejectedException,这将如此解释:
构图保持不变。 更改因以下错误 而被拒绝:组合错误 产生了单个组合错误。 根本原因如下。 查看CompositionException.Errors 属性获取更详细的 信息。
1)的出口通过更改 非recomposable进口 防止 'MEFTest.Program.ProberSet (ContractName = “ProbeContract.IProbe”)' 上部分 'MEFTest.Program'。
程序如下,后面跟着我尝试添加的DLL代码。我究竟做错了什么?
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProbeContract;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFTest
{
class Program
{
[ImportMany]
IEnumerable<IProbe> ProberSet { get; set; }
CompositionContainer exportContainer;
DirectoryCatalog pluginCatalog;
AggregateCatalog catalog;
private void Run()
{
catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
string myExecName = Assembly.GetExecutingAssembly().Location;
string myPath = Path.GetDirectoryName(myExecName);
pluginCatalog = new DirectoryCatalog(myPath + "/Plugins");
catalog.Catalogs.Add(pluginCatalog);
exportContainer = new CompositionContainer(catalog);
CompositionBatch compBatch = new CompositionBatch();
compBatch.AddPart(this);
compBatch.AddPart(catalog);
exportContainer.Compose(compBatch);
for (; ;)
{
Console.Write("Press any key to run all probes: ");
Console.ReadKey(true);
Console.WriteLine();
pluginCatalog.Refresh();
foreach (var Prober in ProberSet)
{
Prober.DoProbe("gizmo");
}
}
}
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
}
}
该插件。另外两个插件都差不多,唯一的区别是他们居住在同一个程序为主要程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using ProbeContract;
namespace OtherProbes
{
[Export(typeof(IProbe))]
public class SpankyNewProber : IProbe
{
public int DoProbe(string what)
{
Console.WriteLine("I'm Spanky and New and I'm probing [{0}]", what);
return 0;
}
public List<string> GetCapabilities()
{
List<string> retVal = new List<string>();
retVal.Add("spanky");
retVal.Add("new");
return retVal;
}
}
}