Архитектура: как обслуживать несколько COM-интерфейсов, которые получают доступ к общему ресурсу - PullRequest
2 голосов
/ 30 августа 2011

У меня архитектурный вопрос.У меня есть проект, который концептуально что-то вроде этого: Architecture schematic

Это кажется довольно простым, но есть морщины.Некоторый фон в виде частично вымышленного примера.Это драйвер ASCOM , который управляет некоторыми двигателями, датчиками и некоторыми выключателями питания.Аппаратное устройство может вращать купол обсерватории и сообщать о его положении, открывать и закрывать затвор и включать и выключать питание различных приборов наблюдения (телескоп, камера, фокусировщик и т. Д.).

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

«Уровень представления» состоит из нескольких COM-интерфейсов.Один интерфейс (IDome) имеет дело с управлением куполом и затвором, другой (IPower) имеет дело с управлением питанием различных устройств.Это стандарт, и его нельзя изменить.

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

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

В настоящее время все эти «уровни»содержится в одной сборке .NET, и я бы предпочел сохранить ее, если это возможно.

Какие шаблоны хороши для этой ситуации?Любые предложения приветствуются.

Ответы [ 3 ]

1 голос
/ 30 августа 2011

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

0 голосов
/ 30 августа 2011

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

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

В качестве альтернативы вы могли бы иметь две логические части для прокси, одна из которых принимала входные данные, а другая - сообщала текущие значения, чтобы несколько подписчиков (UI) могли быть в курсе того, где находится HAL. Подход, основанный на событиях, будет хорошо работать здесь, также взгляните на шаблоны публикации / подписки. Для единого контроля взгляните на схемы блокировки.

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

0 голосов
/ 30 августа 2011

Вы можете использовать DCOM . Идея состоит в том, чтобы зарегистрировать ваши CLSID как серверы вне процесса (опционально, используя COM + ). Когда ваши клиенты создают экземпляры этих CLSID, все они будут созданы в «суррогатном процессе», и Windows будет прозрачно распределять вызовы между клиентскими процессами и этим суррогатным процессом.

Обратите внимание, что для этого у вас должна быть ' proxy / stub DLL ' для вашего интерфейса. Если вы скомпилируете файл IDL, содержащий определения вашего интерфейса, он создаст код C для такой прокси / заглушки DLL. Затем вы должны зарегистрировать эту DLL-библиотеку для внепроцессного взаимодействия для правильной работы с вашими пользовательскими интерфейсами.

Кроме того, вы можете применить ту же модель активации вне процесса на уровне HAL, то есть создать интерфейс COM для HAL, зарегистрировать CLSID HAL в качестве сервера вне процесса и получить свой внутренний компоненты связываются через DCOM. Преимущество этого заключается в том, что вы будете иметь контроль над интерфейсом CLSID и сможете зарегистрировать свою собственную DLL-библиотеку прокси / заглушки, не столкнувшись, возможно, с DLL-библиотекой прокси / заглушки другого поставщика.

...