Мы успешно интегрировали нашу стратегию мультиарендности с MassTransit благодаря некоторой помощи Криса Паттерсона. Однако мы спотыкаемся о том, чтобы наши (Автоматонимные) саги были мультитенантными. У меня есть кое-что, что работает, но мне это совсем не нравится. Мы используем стратегию базы данных «схема для каждого клиента», но готовы использовать ее для саги, если это самый простой способ ее решения.
У нас есть идентификатор клиента в заголовке всех сообщений. Мы соскребаем его с IConsumeContext<>
входящих сообщений и помещаем обратно в IPublishContext<>
исходящих сообщений. Это прекрасно работает с ISagaRepository<>.GetSaga(...)
, потому что один из его параметров - IConsumeContext<>
. Проблема в том, что когда мы вызываем другие ISagaRepository<>
методы, у них нет IConsumeContext<>
, и у нас нет способа фильтрации по арендатору в репозитории. Если мы будем придерживаться нашей текущей стратегии базы данных, мы знаем клиента, поэтому мы знаем, какую схему использовать. Если мы перейдем к централизованным таблицам арендаторов, мы должны включить арендатора в фильтрацию, потому что объект, с которым он коррелируется, не обязательно уникален для всех арендаторов.
PropertySagaLocator<,>
кажется ключевым моментом, исходя из моего текущего понимания. В его Find(IConsumeContext<>)
методе у нас есть доступный нам контекст клиента, но он не передается в репозиторий саги.
В моей текущей попытке заставить это работать, я создал локатор саги о свойствах для мультитенантности, который работает со специализированным репозиторием саги о арендаторах и дает ему контекст клиента, необходимый для использования его метода .Where(...)
надлежащим образом. Но вот где это становится уродливым. Конкретный класс PropertySagaLocator<,>
создается Automatonymous, и поэтому, чтобы поменять его, я должен начать с края Automatonymous, с одного из методов расширения .StateMachineSaga(...)
, и полностью заменить конкретные классы вплоть до точки, в которой он интегрируется. с MassTransit, используя PropertySagaLocator<,>
, поскольку это цепочка конкретных классов, инстанцирующих друг друга на всем пути вниз. Мне неудобно делать такой глубокий разрез через Automatonymous, но мне кажется, что независимо от того, возьмем ли мы стратегию «схема на каждого арендатора» или переключим ее, мы застряли с необходимостью интеграции на этом же этапе.
Другой аспект этого заключается в том, что нам нужно указывать идентификатор клиента в исходящих сообщениях, когда используется нотация .Publish(...)
Automatonymous. В настоящее время я делаю это с помощью шаблона декоратора на ServiceBus
, и в настоящее время я внедряю декорированную служебную шину для конкретного клиента, когда шина копируется из контекста потребления в состояние экземпляра, т. Е. В мои переопределения метода приемника сообщений саги GetHandlers()
.
Есть ли у кого-нибудь опыт интеграции автоматических саг с мультитенантностью? То, что мы делаем сейчас, кажется инвазивным, и мы хотели бы найти более естественный шов.