У меня интерфейс выглядит следующим образом:
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)).
Для настроенного AutoA автоматически сгенерированного кода из Altova mapforce 2012:
namespace ProjectXYZ
{
public class ProjectXYZ
{
public string process(string name)
{
name = "This is for Project A :: "+name;
return name;
}
}
}
Для настраиваемого ProjectB автоматически сгенерированного кода из altova mapforce2012:
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 в CompositionContainer MEF.Каждый проект компилируется, и местоположение его двоичных файлов (вывод сборки) задается в качестве входных данных для 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.ClassB из другой реализации ProjectXYZ.Реализация и классы
ProjectXYZ различаются для разных реализаций ITransform.Классы в ProjectXYZ автоматически генерируются с помощью некоторых сторонних инструментов, которые мне
нужно использовать напрямую.Поэтому я не могу вносить какие-либо изменения в ProjectXYZ.
Поэтому, когда MEF впервые загружает ProjectA.Transform, он также загружает ProjectXYZ для использования в качестве ссылки для ProjectA.Когда ProjectB.Transform загружается / экспортируется,
, тогда как сборки ProjectXYZ уже находятся в памяти MEF, он использует ссылку на сборки ProjectXYZ, доступную из "C: \ ProjectDemo \ ProjectA.Transform \ Bin \ Debug«.Таким образом, когда выполняется ProjectB.Transform, он ищет сборки ProjectXYZ из "C: \ ProjectDemo \ ProjectB.Transform \ Bin \ Debug" , которые он не получает, поскольку MEF загрузил ссылку на сборки ProjectXYZ, доступную в "C: \ ProjectDemo \ ProjectA.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