C# получить ссылки без сборок - PullRequest
0 голосов
/ 17 февраля 2020

Проблема

Я работаю над проектом с системой, подобной плагину. Структура проекта определяется следующим образом:

- Solution
    - Project A (Cli)
    - Project B (Core logic)
    - Project C (Plugin)

Project A - это стартовый проект, Project B содержит основные логи c, а Project C - это плагин, который реализует интерфейс в * 1009. *. Project A имеет ссылку только на Project B, а Project C имеет ссылку только на Project B.

Для визуализации:
visualization

Поскольку я не ссылаюсь на Project C из Project B (и не создаю экземпляр класса напрямую), код, подобный AppDomain.CurrentDomain.GetAssemblies() (внутри Project B), не делает , а не возвращает Project C.

Однако, как только я это сделаю (из Project B): var MyImplementation = new MyImplementation(), AppDomain.CurrentDomain.GetAssemblies() возвращает сборку, так как она известна и загружена во время выполнения, когда я создал экземпляр класса MyImplementation явно из кода.

Вопрос

Из Project B я хочу получить все сборки, которые реализуют указанный c интерфейс, из Project B и создать их экземпляр.

Итак, как мне загрузить эти (казалось бы) неизвестные сборки во время выполнения?

1 Ответ

1 голос
/ 17 февраля 2020

Я не думаю, что можно узнать, содержит ли сборка класс, реализующий ваш интерфейс, без его загрузки.

Что вы можете сделать, это предоставить каталог, куда вы поместите все свои сборки плагинов.

Таким образом, вы можете загрузить свои плагины в свой домен приложений следующим образом:

public static Assembly[] MyPlugins { get; private set; }

public static void LoadAssemblies()
{
   MyPlugins = Directory.GetFiles(lookingDirectory, "*.dll")
                .Select(assemblyPath =>
                {
                    AssemblyName an = AssemblyName.GetAssemblyName(assemblyPath);
                    return Assembly.Load(an);
                })
                .ToArray();
}

И затем вы можете найти все типы, которые реализуют ваш интерфейс следующим образом:

MyPlugins.SelectMany(assembly => assembly.GetTypes())
    .Where(type => typeof(IYourInterface).IsAssignableFrom(type))
    .Select(type => (IYourInterface)Activator.CreateInstance(type))

И затем Вы можете выполнить итерацию для каждой реализации вашего интерфейса, например, для вызова общего метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...