Система с плагинами в C # - PullRequest
       28

Система с плагинами в C #

9 голосов
/ 05 февраля 2009

Мне нужно разработать систему для мониторинга информации о датчиках, но в будущем может быть добавлено много датчиков.

Тем не менее, идея состоит в том, чтобы разработать систему, которая будет состоять из каркаса приложения. Датчики (поскольку каждый из них имеет свои характеристики связи и представления данных) будут добавлены в систему в качестве плагинов.

Как бы я написал это на C #? Это случай компонентно-ориентированной разработки? Стоит ли использовать динамические библиотеки?

Ответы [ 7 ]

10 голосов
/ 05 февраля 2009

Существует огромное количество специальных плагинов для C #. Один из них описан в Плагин Архитектура с использованием C # Код проекта ). Общий подход заключается в том, что хост-приложение публикует сборку с интерфейсами. Он перечисляет через папку и находит сборки, которые определяют класс, реализующий его интерфейсы, загружает их и создает экземпляры классов.

На практике вы хотите сделать больше. Лучше всего, если хост-приложение определяет два интерфейса, IHost и IPlugIn. Интерфейс IHost предоставляет сервисы, на которые плагин может подписаться. IPlugIn создается с использованием IHost.

Чтобы загрузить плагин, вы должны сделать больше, чем просто получить плагин. Вы должны перечислить все загружаемые плагины. Построить их каждый. Спросите их, могут ли они бежать. Попросите их экспортировать API в хост. Попросите их импортировать API с хоста. Плагины должны иметь возможность спрашивать о существовании других плагинов.

Таким образом, плагины могут расширять приложение, предлагая больше API.

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

В конце света вы должны предупредить плагины, что они уйдут. Тогда убери их.

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

В качестве дополнительного бонуса вы также должны сделать так, чтобы в папке плагинов вы разрешали ярлыки для плагинов. Это позволяет вам написать ваше приложение и передать его кому-то еще. Они могут создать плагин в своей среде разработки, создать ярлык для него в папке плагинов приложения и не беспокоиться о развертывании после каждой компиляции.

9 голосов
/ 05 февраля 2009

Managed Extensibility Framework (MEF) - это то, что вам нужно здесь. Вы также можете использовать контейнер для внедрения зависимостей , но это немного не то, что вы ожидаете, хотя само по себе вполне жизнеспособное решение.

3 голосов
/ 05 февраля 2009

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

Посмотрите API Reflection, чтобы узнать, как сканировать каталог сборок .NET, и загляните внутрь них.

Каждая сборка должна иметь заводской класс, который должен возвращать список датчиков, которые находятся в этой сборке. Я рекомендую вам сделать это подпрограммой, а не функцией, и передать ей список, который он тоже добавляет. SensorDLL1 добавляет 4 датчика в пустой список, SensorDLL2 добавляет 8 датчиков в список, который теперь имеет 12 датчиков и так далее. Этот подход является наиболее гибким в долгосрочной перспективе.

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

1 голос
/ 05 февраля 2009

Однажды мы сделали систему плагинов в нашем школьном проекте в 2006 году, Socio. Вы можете найти код здесь и здесь .

Основной извлеченный урок состоял в том, что очень просто динамически загружать код в C #. Если у вас просто есть подключаемый модуль DLL и приложение, которое придерживается вашего интерфейса и ссылается на общую DLL, в которой этот интерфейс существует, это просто работает ™.

По сути, это то, что плинтус описал в своем ответе .

1 голос
/ 05 февраля 2009

В зависимости от самих датчиков это звучит так, как будто вам нужно определить единый интерфейс, который будут реализованы всеми датчиками. Ваш основной «каркас приложения» будет тогда работать против интерфейса ISensor и не должен заниматься конкретными реализациями каждого из классов / объектов / компонентов датчика.

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

Вот некоторые ссылки, которые могут помочь:

Шаблон проектирования команд: - http://en.wikipedia.org/wiki/Command_pattern

Шаблон проектирования наблюдателя Шаблон: - http://en.wikipedia.org/wiki/Observer_pattern

Динамически загружаемые сборки: - http://www.divil.co.uk/net/articles/plugins/plugins.asp

Надеюсь, это поможет.

0 голосов
/ 06 ноября 2015

Это очень старый пост, но все же я подумал, что кому-то будет полезно appPress.in, где мы разработали фреймворк с функциональностью плагина. здесь мы позволяем плагину изменять пользовательский интерфейс основного приложения по горизонтали и вертикали, добавлять собственные страницы, подключаться к таким событиям, как Init, OnClick и OnChange.

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