Паттерн Nservicebus Singleton - подключение к существующим в настоящее время объектам

Я прорабатываю первые шаги по изучению Nservicebus и планирую достаточно крупномасштабное (по крайней мере, для меня) приложение.

Я хочу, чтобы приложение могло масштабироваться на X-машины. В нем будет ряд услуг, таких как:

LogonService, UserManagementService, GameService, RoomService и т. Д.

Клиенты будут общаться с сервером через WCF. Сами сервисы будут общаться друг с другом через NServiceBus и MSMQ. Саша Барбер написал отличную статью о начале работы с NServiceBus и столкнулся с в той же ситуации я собираюсь ударить. Уди и Саша еще раз поговорили об этом здесь.

Мой вопрос: когда служба обрабатывает сообщение, как она узнает об остальной части приложения в этой службе? По словам Саши, «обработчик автоматически» появляется, когда сообщение требует обработки. Итак, когда он создан, как он узнает о других объектах, которые уже запущены и работают. Например, в GameService у него будет список всех запущенных игр. Как бы он получил к этому доступ?

Думаю, я могу придумать два варианта (как указал Саша):

Шаблон посредника Синглтон

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

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

Есть ли лучшее решение этой проблемы?

Спасибо


person Jon    schedule 06.12.2010    source источник


Ответы (2)


Для состояния, которое необходимо хранить в памяти, я бы также использовал шаблон Singleton. В противном случае состояние обычно сохраняется в хранилище данных и читается обработчиком при каждом продолжении сообщения.

public Handle(SomeMessage msg)
{
   var aggregateRoot = writeStore.Get(msg.SomeId);

   aggregate.DoSomeAction(msg.SomeOtherData);

   //if write store does not support dirty tracking
   writeStore.Save(aggregateRoot);
}
person Andreas Öhlund    schedule 06.12.2010
comment
Круто, я тоже так к этому отношусь. Спасибо - person Jon; 07.12.2010

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

При этом синглтоны - это простой способ добиться желаемого. Однако если единственная причина, по которой вы делаете объект синглтоном, - это то, что NServiceBus может получить к нему доступ, я бы предложил найти лучший способ сделать это.

person mike    schedule 09.12.2010
comment
Привет, Mrnye, спасибо за комментарий. Есть ли у вас какие-либо предложения о том, как NServiceBus может получать один и тот же экземпляр объекта каждый раз, когда сообщение получено без синглтона? Причина в том, что у него уже будет состояние и запущенные в данный момент процессы, с которыми сообщение должно будет взаимодействовать. Я не собираюсь напрямую обращаться к базе данных или тому подобному. Еще раз спасибо. - person Jon; 09.12.2010
comment
Как я уже упоминал, вы должны использовать фреймворк для внедрения зависимостей. NServiceBus по умолчанию использует Spring.Net (см. springframework.net). Я не использовал его раньше, поэтому вам придется решить, как регистрировать объекты с помощью spring. Когда у вас это работает, вы просто объявляете общедоступное свойство public IBus { get; set; }, и Spring это увидит и автоматически заполнит его экземпляром класса. Прочтите о Spring и внедрении зависимостей, чтобы узнать больше - person mike; 10.12.2010
comment
Да, я использую Castle вместо Spring, обычно вы регистрируете тип класса, и он создает новый экземпляр этого класса, когда он вам нужен. Мне нужно, чтобы он возвращал единственный экземпляр класса, потому что он уже запущен. Насколько я понимаю, регистрация работающего класса в структуре IOC аналогична одноэлементному шаблону, мне что-то не хватает? - person Jon; 10.12.2010