Я просто делаю первые шаги на территории MEF и хотел сделать это, используя .net core 2.1.
Использование VS 2017 (версия 15.8.8) Я создал небольшое консольное приложение (.NET Core) с интерфейсом
interface IMessageSender
{
void Send(string message);
}
и реализация (в том же проекте)
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine("EmailSender : " + message);
}
}
Наконец, у меня есть небольшой метод compose, выполненный из моего Main (string [] args)
[Import]
private void Compose()
{
var assembly_A = new[] { typeof(Program).GetTypeInfo().Assembly };
var config_A = new ContainerConfiguration().WithAssembly(assembly_A[0]);
var container_A = config_A.CreateContainer();
var msg_A = container_A.GetExport<IMessageSender>();
msg_A.Send("Hello");
}
Работает как положено
Однако, если я добавлю новую библиотеку классов в свое решение и перенесу свою реализацию Send (string) во вновь добавленный проект, все не получится.
namespace AnotherMefExtensionProjectNamespace
{
[Export(typeof(IMessageSender))]
public class EmailSenderExtended : IMessageSender
{
public void Send(string message)
{
Console.WriteLine("EmailSenderExtended : " + message);
}
}
}
Новый метод Compose
[Import]
public IMessageSender MessageSender { get; set; }
private void Compose()
{
var assembly_B = new[] { typeof(EmailSenderExtended).GetTypeInfo().Assembly };
var config_B = new ContainerConfiguration().WithAssembly(assembly_B[0]);
var container_B = config_B.CreateContainer();
var msg_B = container_B.GetExport<IMessageSender>();
msg_B.Send("Hello");
}
Я пытался сравнить разные конфиги и контейнеры (_A против _B в примерах), но не могу понять, в чем отличие. Я даже пытался расширить класс ContainerConfiguration для загрузки из указанной сборки, и он работает до тех пор, пока данный файл содержит метод Main, но не работает, если я использую свою «расширенную» библиотеку базовых классов .NET.
public static ContainerConfiguration WithChosenAssembly(this ContainerConfiguration configuration, string pathAndFile)
{
var context = AssemblyLoadContext.Default.LoadFromAssemblyPath(pathAndFile);
var ass_list = new List<Assembly>() { context };
configuration = configuration.WithAssemblies(ass_list, null);
return configuration;
}
У меня сложилось впечатление, что вы расширяете свое основное приложение, разрабатывая библиотеку классов, которая в основном реализует указанные интерфейсы.
Кажется, я сейчас не могу этого сделать, но, очевидно, я неправильно понял что-то очень простое.
Если кто-то захочет поставить меня на правильный путь или дать альтернативную идею для разработки плагинов для ядра .net, я был бы очень признателен.
С уважением
Magnus