2011-01-26 4 views
0

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

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

Мой вопрос в том, когда программа первоначально проверяет файлы dll, следует ли мне указывать ссылку на каждый объект dll для будущего использования, или я должен каждый раз запрашивать файлы dll и создавать объект по мере необходимости?

, если это первый, что является лучшим способом сохранить список неопределенного количества объектов, которые происходят из общего интерфейса, а затем знать, к какому из них следует обращаться, когда это необходимо?

Спасибо.

+0

Я бы сказал, что при необходимости сохраните и создайте при необходимости :). –

ответ

2

Используя первый, который вы могли бы просто создать

List<IYourCommonInterface> pluginDlls

, а затем просто

pluginDlls.Add(dllReference);

Редактировать

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

Dictionary<SomeIDField, IYourCommonInterface> pluginDlls

pluginDlls.Add(dllRefrence);

+0

(1+) Возможно, словарь ... таким образом у вас есть легкое средство для идентификации/доступа к каждому ресурсу – used2could

+0

@ used2could хорошее предложение – msarchet

0

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

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

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

+0

Фактически, при загрузке программы программа запрашивает DLL и отображает их идентификатор/имя для пользователя. Затем пользователь может выбрать один и некоторые внешние данные, а затем dll знает, что делать с этими данными. –

+0

Итак, в какой-то момент вам нужно создать экземпляр класса, который определен в DLL, но который реализует общий интерфейс плагина, который вы определили в своем главном приложении. Существуют различные способы сделать это. При загрузке, например, DLL могла зарегистрировать себя с каким-то реестром в главном приложении. Или вы можете искать имя класса для конкретного экземпляра, используя отражение, получая имя из библиотеки DLL. Для некоторых примеров см. Http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/c3da5226-fc87-4fff-be60-4cc5af4d6c07. –

+0

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

1

Большинство приложений выполняет проверку на загрузку.

Я бы не сохранил список интерфейсов. Если вы их сохраните, вы столкнетесь с возможностью того, что сборки либо исчезнут, либо каким-то образом обновлены. В этот момент вам нужно «обновить» их в любом случае.

1

После того, как вы загрузили сборку и получили экземпляр System.Reflection.Assembly для отражения (используя Assembly.Load(), Assembly.LoadFrom(), Assembly.LoadFile() и т. Д.), Сборка загружен. Цитирую MSDN on the subject:

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

Так что, если вы хотите, чтобы выгрузить DLL, до тех пор, пока вы на самом деле нужно их, вы будете иметь, чтобы создать новый домен приложения, а затем выгрузить это. Его проще просто загрузить и сделать с ним. Вы можете сохранить ссылку assemply, если хотите, но если вы снова вызове Assembly.Load(), она фактически не загрузит сборку: она просто получит ссылку на ранее загруженную сборку.

Смежные вопросы