Абстрактные базовые классы и домены приложений - PullRequest
1 голос
/ 06 декабря 2009

Я прошу прощения, если мое предстоящее объяснение не имеет достаточного смысла; Я известен за это, хотя я пытаюсь сделать иначе.

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

Что меня убивает, так это использование абстрактных базовых классов. Существует функциональность, которая будет общей для всех реализаций некоторых интерфейсов, поэтому абстрактные базовые классы имеют смысл. Если абстрактная база находится в сборке службы, то независимо от того, какие плагины, которые подклассируют ее, их сборки перетаскиваются в домен приложения службы. Однако в абстрактной базе есть внутренние члены (свойства с внутренними установщиками и общедоступными получателями), которые использует служба, поэтому она должна быть в той же сборке, что и служба, чтобы это было возможно.

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

Ответы [ 3 ]

0 голосов
/ 06 декабря 2009

Если проблема, которую вы пытаетесь избежать, - это утечка сборки плагина в ваш сервисный домен приложения, то у вас не будет этой проблемы, есть ли у вас внутренние участники или нет. Вам просто нужно, чтобы сервисная сборка была доступна внутри домена плагина (а не наоборот), и вам, вероятно, придется определять общий тип в сервисной сборке, а не отдельную сборку (если вам действительно нужны "внутренние компоненты другая сборка).

Представьте, что у вас есть абстрактный базовый класс PluginBase, определенный в ServiceLib.dll. Тогда вы могли бы иметь такой код в своем основном домене службы:

// Create a new AppDomain for the plugin
AppDomain pluginDomain = AppDomain.CreateDomain("PluginDomain", null, new AppDomainSetup());

// Instantiate the plugin type (in the new AppDomain)
// Note: assumes that PluginBase is MarshalByRefObject
PluginBase plugin = (PluginBase)domain.CreateInstanceAndUnwrap("PluginLib", "PluginLib.PluginImp");

// Set any internal stuff now
plugin.InternalDetails = "...";
0 голосов
/ 13 декабря 2009

(для моего и, возможно, дальнейшего использования)

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

Как только прокси-объект объекта, созданного плагином, был доступен в других доменах приложений, то есть в этом базовом классе, определяемом службой, который использует службу внутренним способом (например, поиск в коллекции), он работает с копией объект службы в домене приложения плагина, а не синглтон, который я пытаюсь предоставить.

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

Мне очень нравится учиться, но я не ценю удары по голове.

0 голосов
/ 06 декабря 2009

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

...