Может ли кто-нибудь наконец объяснить мне, какова лучшая стратегия для реализации прозрачной и плавной поддержки мультитенантной функциональности в модели домена с питанием от NHibernate?
Я ищу способ, как сохранить логику домена как можно более изолированной от многопользовательских вещей, таких как фильтрация по TenantID и т. д.





У Айенде есть несколько хороших сообщений в блоге о создании мультитенантных приложений. Как NHibernate будет использоваться для этого, будет зависеть от типа мультитенантности, которую вы собираетесь использовать.
Хм ... в этом случае я не уверен, но я знаю, что сеанс NHibernate позволяет вам устанавливать фильтры, но я не уверен, как именно они работают. Я считаю, что они позволяют запускать запросы и загружать объекты, не добавляя фильтр в сами запросы. Это МОЖЕТ быть тем, что вы хотите.
Самый простой подход - использовать разные базы данных для каждого клиента.
Реализация мультитенантности таким образом позволяет вам эффективно писать приложение с одним клиентом и беспокоиться о мультитенанте только в точке, где вы создаете / извлекаете сеанс.
Я еще не углублялся в детали (мне нужно сделать что-то подобное через несколько месяцев), но я думаю, что самый простой способ управлять, к какой базе данных подключен сеанс, - это использовать настраиваемую реализацию ISessionFactory, которая может определить, какое соединение для использования (на основе внешнего аспекта, такого как хост-часть URL-адреса запроса).
Я видел по крайней мере один пост в сети, где обсуждали это, но в настоящее время я не могу найти ссылку.
Если вы используете Castle Windsor, обратите внимание на средство интеграции NHibernate. Это поддерживает концепцию нескольких (именованных) фабрик сеансов, что позволит вам иметь фабрику сеансов для каждого клиента. Средство интеграции предоставляет интерфейс ISessionManager, который позволяет открывать сеанс в именованной фабрике сеансов (а также предоставляет семантику сеанса для каждого запроса для веб-приложений). Все, что требует доступа к сеансу, может просто принимать параметр конструктора ISession, и вы можете создать фабрику, которая принимает ISessionManager в качестве параметра конструктора. Затем фабрика может открыть сеанс в соответствующей именованной фабрике сеансов, проверив запрос, чтобы определить, какую именованную фабрику сеансов следует использовать.
Я также недавно копался в этом для своего следующего проекта. Вы можете реализовать собственный IConnectionProvider и зарегистрировать его в конфигурации с помощью «connection.provider».
Я предлагаю вам унаследовать от DriverConnectionProvider и переопределить ConnectionString, а не реализовывать полностью настраиваемый.
Это может быть что-то вроде этого:
public class ContextualConnectionProvider : DriverConnectionProvider
{
protected override string ConnectionString
{
get
{
return GetCurrentTenantDatabaseConnectionStringInternally();
}
}
public override void Configure(IDictionary<string, string> settings)
{
ConfigureDriver(settings);
}
}
Надеюсь это поможет.
Есть множество способов сделать это, но проблемы мульти-tenancy лежат глубже, чем просто модель данных. Я ненавижу подключать продукт, но попробуйте SaaSGrid от моей компании, в которой я работаю, Apprenda. Мы облачная операционная система, которая позволяет вам писать приложения SOA с одним клиентом (не стесняйтесь использовать NHibernate для доступа к данным), которые автоматически вводят мультитенантность в вашем приложении. Когда вы публикуете свое приложение, вы можете делать такие вещи, как выбирать модель данных (изолированную базу данных или общую), и SaaSGrid будет развертываться соответствующим образом, и ваше приложение будет работать без каких-либо изменений кода - просто напишите код, как если бы он был для одного клиента!
Использование подхода с общей схемой требует, чтобы вы перехватывали и украшали все ваши запросы дополнительной информацией, чтобы ограничить результаты.
NHibernate предоставляет для этого перехватчики, а прослушиватели событий также доступны из NHibernate 2.0 Aplpha 1.
См. http://elegantcode.com/2008/05/15/implementing-nhibernate-interceptors/ и http://www.codinginstinct.com/2008/04/nhibernate-20-events-and-listeners.html для обсуждения этих вопросов.
Также обратите внимание на компонент Rhino Security Айенде, поскольку он проделывает большую работу по изменению запросов с дополнительными ограничениями на основе дескрипторов безопасности. Вы можете просмотреть источник на https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/security
Я писал о подходе для многопользовательской среды здесь, этот подход не идеален для всех ситуаций, однако он позволяет вам в значительной степени забыть о проблемах с несколькими арендаторами без использования сторонних продуктов.
ссылка кажется мёртвой, url не особо помогает найти её где-нибудь ещё
Что ж, я говорю о простом подходе к общей базе данных / схеме: в большинстве таблиц есть специальный столбец, идентифицирующий клиента. Но на уровне модели предметной области я бы не хотел видеть ни одно из этих свойств.