Используя эту статью Используя MEF в. NET Core в качестве отправной точки, я пытаюсь загрузить плагин, который ссылается на старую версию моей воображаемой библиотеки MessageQueue, которая отличается от версии, которая приложение основной консоли использует.
Версия 1.0.0 моего «MessageQueue» возвращает значение «Сообщение из v1.0». Версия 1.1.0 моего "MessageQueue" возвращает значение "Сообщение из v1.1".
Мое главное консольное приложение ссылается на v1.1, тогда как мой плагин ссылается на v1.0. Однако, когда я вызываю плагин, сообщение, возвращаемое из его «MessageQueue», является тем же сообщением, которое возвращает «MessageQueue» консольного приложения, а именно «Сообщение из v1.1».
Я ожидаю, что плагин будет использовать свою версию «MessageQueue» и вместо этого вернет «Сообщение из v1.0».
У меня мое решение разбито на 4 проекта:
- ConsoleMEF - приложение основной консоли
- Pluginable - библиотека класса, содержащая интерфейс IMessageSender
- MefPlugin - библиотека класса, содержащая EmailSender, реализующий IMessageSender, и помечена как [Exported]. Ссылка на жесткую сборку сообщений v1.0
- Messages - класс lib, содержащий «MessageQueue» (код проекта - версия 1.1, скомпилированная сборка v1.0 скопирована в путь к плагину)
Код плагина здесь:
[Export(typeof(IMessageSender))] // Socket
public class EmailSender : IMessageSender
{
public void Send(string message)
{
var messages = new MessageQueue();
Console.WriteLine($"App Message Queue From Plugin: {messages.GetMessage()}");
Console.WriteLine($"EMAIL: {message}");
}
}
Вот как я загружаю плагин:
[Import] // Hook
public IMessageSender MessageSender
{
get;
set;
}
void Compose()
{
// pluginPath contains:
// - MefPlugin.dll
// - Pluginable.dll
// - Messages.dll, Version 1.0
var pluginPath = Path.GetFullPath(@"c:\temp\plugins");
var assemblies = Directory
.GetFiles(pluginPath, "*.dll")
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)
.ToList();
var configuration = new ContainerConfiguration()
.WithAssemblies(assemblies);
using var container = configuration.CreateContainer();
MessageSender = container.GetExport<IMessageSender>();
}
Вот как я вызываю плагин:
void Run()
{
Compose();
var messages = new MessageQueue();
// CORRECT: Prints "Message from v1.1"
Console.WriteLine($"App Message Queue From Console: {messages.GetMessage()}");
// MessageSender.Send also calls the following:
//Console.WriteLine($"App Message Queue From Plugin: {messages.GetMessage()}");
// WRONG: Prints "Message from v1.1"
// EXPECTED: "Message from v1.0"
MessageSender.Send("Hello MEF");
}
MessageQueue v1.0 имеет следующий код:
public class MessageQueue
{
public string GetMessage()
{
return "Message from v1.0";
}
}
MessageQueue v1.1 имеет следующий код:
public class MessageQueue
{
public string GetMessage()
{
return "Message from v1.1";
}
}
Раньше я легко делал это, используя AppDomain и BasePath. Но я не могу понять, что делать с AssemblyLoadContext.
Где я ошибаюсь?