我有一个界面如下:
namespace Contract
{
[InheritedExport(typeof(ITransform))]
public interface ITransform
{
string process(string name);
}
}
现在,我有两个课程:
using Contract;
namespace ProjectA
{
public class ProjectA:ITransform
{
public string process(string name)
{
ProjectXYZ.ProjectXYZ obj = new ProjectXYZ.ProjectXYZ();
return obj.process("Project A calling");
}
}
}
和
using Contract;
namespace ProjectB
{
public class Datawarehouse:ITransform
{
public string process(string name)
{
ProjectXYZ.ProjectXYZ obj = new ProjectXYZ.ProjectXYZ();
return obj.process("Project B calling");
}
}
}
我有另一个项目 ProjectXYZ(由第三方工具自动生成(Altova Mapforce 2012 SP1))。
对于来自 altova mapforce 2012 的 ProjectA 自定义自动生成代码:
namespace ProjectXYZ
{
public class ProjectXYZ
{
public string process(string name)
{
name = "This is for Project A :: "+name;
return name;
}
}
}
对于来自 altova mapforce 2012 的 ProjectB 自定义自动生成代码:
namespace ProjectXYZ
{
public class ProjectXYZ
{
public string process(string name)
{
string n = "This is for Project B ::"+Result();
return n;
}
public string Result()
{
int op1 = 1;
int op2 = op1+3;
return op2.ToString();
}
}
}
第三方自动生成的代码不会被导出,但它的二进制文件我用作 ProjectA.Transform 和 ProjectB.Transform 的参考。所以我使用 [DirectoryCatalog] 将 ProjectA.Transform 和 ProjectB.Transform 的所有二进制文件加载到 MEF 的 CompositionContainer 中。每个项目都被编译,它们的二进制文件(构建输出)位置作为 DirectoryCatalog 的输入给出
进一步组成。
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
namespace AppConsole
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
public void Run() {
List<string> extensionPath = new List<string>();
//Change the extension Path
extensionPath.Add(@"E:\MEF\MEFForProjectA\ProjectA\bin\Debug");
extensionPath.Add(@"E:\MEF\MEFForProjectB\ProjectB\bin\Debug");
foreach (var extension in extensionPath)
{
ITransform transform = GetExtension(extension);
Console.WriteLine("Extension Loaded :{0}", transform.process(extension));
}
Console.ReadLine();
}
private ITransform GetExtension(string extensionPath)
{
IEnumerable<ITransform> extensions = null;
try
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(extensionPath));
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(catalog);
extensions = container.GetExportedValues<ITransform>();
return extensions.FirstOrDefault();
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return extensions.FirstOrDefault();
}
}
}
ProjectA.Transform 使用 ProjectXYZ.ClassA,而 ProjectB.Transform 使用 ProjectXYZ 的另一个实现中的 ProjectXYZ.ClassB。实现和类
ProjectXYZ 因 ITransform 的不同实现而异。ProjectXYZ 中的类是通过一些第三方工具自动生成的,我
需要直接使用。因此,我无法对 ProjectXYZ 进行任何更改。
因此,当 MEF 第一次加载 ProjectA.Transform 时,它还会加载 ProjectXYZ 以用作 ProjectA 的参考。当 ProjectB.Transform 正在加载/导出时,
然后由于 ProjectXYZ 程序集已经在 MEF 内存中,它使用从"C:\ProjectDemo\ProjectA.Transform\Bin\Debug"获得的 ProjectXYZ 程序集引用。因此,当 ProjectB.Transform 正在执行时,它会从 "C:\ProjectDemo\ProjectB.Transform\Bin\Debug"中搜索 ProjectXYZ 程序集,因为 MEF 已加载"C:\ProjectDemo\项目A.Transform\Bin\Debug"。
如何解决这个问题。MEF 正确加载部件,但它没有以所需的方式加载支持 dll 的引用。我也试过
PartCreationPolicy 属性,但结果相同。
Expected Result :
Extension Loaded :This is for Project A :: Project A calling
Extension Loaded :This is for Project B :: 4
Actual Result:
Extension Loaded :This is for Project A :: Project A calling
Extension Loaded :This is for Project A :: Project B calling