Хорошо,
это более общий вопрос "уродливых критиков в углу". Я планирую начать проект по WCF и PRISM. Я некоторое время играю с PRISM, и должен сказать, мне это нравится. Прочная основа для приложений с хорошими возможностями для роста.
Теперь я хочу включить WCF и создать распределенное приложение с одной частью на сервере и двумя на клиентах. Это может быть даже одна и та же машина, или нет, в зависимости от сценария.
Теперь моя идея - принять концепцию события из PRISM и расширить ее по каналу с помощью WCF и обратных вызовов, как описано здесь Пример обратного вызова WCF AlarmClock.
Я создал маленькую картинку, чтобы проиллюстрировать идею (в основном для меня), возможно, это делает вещи более ясными:
Серая стрелка означает "использование lib". WCF-Event-Base означает нормальные события PRISM, где метод публикации называется "по проводке".
Есть несколько вопросов, которые приходят на ум:
- Существуют ли какие-либо существующие примеры для таких вещей?
- Каким будет лучший способ "поднять" события по проводке?
- Любые возможные проблемы с этим понятием (уродливые твари, упомянутые ранее)
Что касается второго вопроса, в настоящее время я думаю о повышении событий с использованием строки (типа конкретного события, которое я хочу поднять) и полезной нагрузки в качестве аргумента. Что-то вроде public void RaiseEvent(string eventType, object eventPayload){}
Полезная нагрузка должна быть сериализована, возможно, я даже включил hashcheck. (Значение, если я поднимаю, например, событие с изображением в качестве аргумента 10 раз, я только переношу изображение один раз, а затем используя хэш, чтобы сервер использовал буфер при публикации)...
Хорошо, я думаю, вы поняли. Эта "вещь" должна вести себя как гигантское одиночное приложение, используя WCF_EventAggregator вместо обычного PRISM IEventAggregato r. (ничего себе, при написании я просто получил идею "просто" расширить IEventAggregator, подумать об этом)...
Почему я пишу это? Ну, для обратной связи в основном, и для сортировки моих мыслей. Поэтому комментарии приветствуются, возможно, что-то, о чем я должен быть осторожен?
Крис
[редактирует]
Распределение клиентов
Должно быть число клиентов undefined, сервер не должен знать клиентов. Сам сервер может быть клиентом для себя, создавая строго типизированные события PRISM в других частях исходного кода.
Основное различие между "клиентом" и "сервером" - это фактическая реализация соединителя WCF_PRISM, см. следующую главу...
Повышение клиентских событий (функция PRISM)
В PRISM для повышения простых событий вам даже не нужна ссылка на интерфейс службы. IEventAggregator может быть получен путем инъекции зависимостей, предоставляя экземпляр желаемого события (например, WeatherChangedEvent). Это событие может быть вызвано просто вызовом eventInstance.Publish(23), потому что событие реализовано как public class WeatherChangedEvent : CompositePresentationEvent<int>
Разъем WCF - PRISM
Так же просто, как и поднятие событий, подписывается на события. Каждый модуль может подчиняться событиям, используя тот же метод, получая ссылку и используя Подписка для присоединения к этому событию.
Вот где "волшебство" должно произойти. Клиенты будут включать в себя модуль призмы, ответственный за подключение событий PRISM к "сообщениям сообщений wcf". В основном это будет означать все доступные события в решении (все они все определены в модуле инфраструктуры) и отправит сообщение WCF в случае возникновения события.
Разница между SERVER и CLIENT заключается в реализации этого модуля. Должно быть небольшое различие из-за двух вещей.
- Настройки настройки WCF
- Поток событий для предотвращения бесконечного цикла
Поток событий будет (пример)
- Клиент получает ссылку на WeatherChangedEvent
- wChanged.Publish(27) → нормальное событие PRISM
- Модуль WCF_PRISM подписывается на событие и
- отправить это событие на сервер
- Сервер внутри получает экземпляр WeatherChangedEvent и публикует
- Сервер обращается ко всем клиентам, повышающим их WeatherChangedEvent
Открытые точки
Очевидным моментом является предотвращение цикла. Если сервер поднимет событие во ВСЕХ клиентах, клиенты вернутся на сервер, снова запустив это событие и т.д. Таким образом, должна быть разница между вызванным локальным событием (это означает, что мне нужно отправить это сервер) и "событие, вызванное сервером", что означает, что мне не нужно отправлять его на сервер.
Кроме того, если клиент инициировал это событие, его не нужно вызывать сервером, потому что событие уже поднято (в самом клиенте, точка 2).
Все это особое поведение будет инкапсулировано в модуль повышения уровня WCF, невидимый для остальной части приложения. Мне нужно подумать о том, "как узнать, уже ли опубликовано событие", возможно, GUID или что-то в этом роде было бы хорошей идеей.
И теперь второй большой вопрос, на что я был нацелен, когда рассказывал о "струнах" раньше. Я не хочу писать новое определение интерфейса службы каждый раз, когда добавляю событие. Большинство событий в PRISM определяются одной строкой, особенно во время разработки. Я не хочу обновлять WCF_Event_Raising_Module каждый раз, когда добавляю событие.
Я думал о отправке событий непосредственно при вызове WCF, например. используя функцию с сигнатурой типа:
public void RaiseEvent(EventBase e, object[] args)
Проблема в том, что я не знаю, могу ли я легко сериализовать события PRISM. Все они происходят из EventBase, но я должен проверить это... По этой причине у меня возникла идея использовать тип (как строку), потому что я знаю, что сервер разделяет инфраструктурный модуль и может получить свой собственный экземпляр события (нет необходимости отправлять его по кабелю, только arg)
Пока я здесь, я буду держать вопрос открытым для получения дополнительной информации. Главное новое "понимание", которое я только что получил: подумайте о проблеме рекурсии /infite loop.
Btw. если кто-то полностью смущен всем этим разговором о событиях, попробуйте PRISM. Вам понравится, даже если вы используете только DI и события (RegionManager, например, не мой любимый)
Крис
[END EDIT 1]