Как сделать приложение осведомленным о плагине без отдельной DLL для интерфейса плагина? - PullRequest
3 голосов
/ 01 июня 2011

Традиционная процедура разработки архитектуры плагинов заключается в создании отдельной библиотеки DLL, содержащей только общий интерфейс, который будут реализованы всеми плагинами, и зависимости от этого как основного приложения, так и плагинов.Пытаюсь сделать точно так же, но без отдельного интерфейса dll.Один очевидный способ - заставить все плагины зависеть от основного приложения, но вряд ли это симпатичное решение.

Можете ли вы придумать более красивое решение?В идеале, не было бы dll, связывающего интерфейс;если это невозможно, было бы неплохо, если бы пользователю, который не намеревался запускать плагины, вообще не нужно было загружать dll плагина.Кстати, только те, кто запускает плагины, нуждаются в интерфейсе DLL.

Ответы [ 3 ]

3 голосов
/ 01 июня 2011

Вы можете использовать MEF и импортировать System.Object реализации с метаданными (строками) вместо реального интерфейса или определенных типов.

При этом хост-процессу будет сложно использовать плагины без известного интерфейса. Потребовалась бы некоторая форма использования через отражение, что будет очень, очень уродливо.

Лично я бы просто включил простую DLL с интерфейсами, которые могут стоять отдельно. Приложение может связывать его с дистрибутивами, и плагины могут его использовать. Преимущества этого значительно перевешивают дополнительные «затраты» на обслуживание небольшой сборки, где есть только интерфейсы.

2 голосов
/ 01 июня 2011

Вы можете загрузить сборку и получить доступ к ее типам через Reflection. Здесь есть несколько примеров: http://www.csharp -examples.net / mirror-examples / , и я извлек некоторые из наиболее интересных:

Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
Type calcType = testAssembly.GetType("Test.Calculator");
object calcInstance = Activator.CreateInstance(calcType);

// Get property value
PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

....

// invoke public instance method: public void Clear()
calcType.InvokeMember("Clear",
     BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
     null, calcInstance, null);

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

Теперь, это не очень хороший способ реализовать архитектуру плагинов, потому что вы теряете много времени проверки во время компиляции при написании плагинов, и, вообще говоря, лучше воспользоваться возможностью развертывания дополнительной DLL.

1 голос
/ 01 июня 2011

Один из способов сделать это - через Reflection.Вам нужно будет проверить загруженную (подключаемую) сборку, чтобы извлечь информацию о методе и вызвать Invoke.

Еще один способ сделать это в .NET 4 - через dynamic.Ключевое слово dynamic позволяет обойти проверку типов во время компиляции, чтобы вы могли вызывать любой метод, который вам нужен, и он будет связан во время выполнения.

Оба параметра влияют на производительность, поэтому вы, вероятно, не захотите делать это.это если у вас будет много болтовни между хостом и плагинами.

...