В многопользовательском ASP.NET приложение MVC на основе Витрины Rob Conery MVC я должен фильтровать данные арендатора в репозитории или уровне служб?
public interface IJobRepository
{
IQueryable<Job> GetJobs(short tenantId);
}
public interface IJobService
{
IList<Job> GetJobs(short tenantId);
}
Мое инстинктивное чувство говорит, чтобы сделать это на уровне служб (опция 2), но можно было утверждать, что у каждого арендатора должно в сущности быть их собственное "виртуальное хранилище", (опция 1), где эта ответственность лежит на репозитории.
Я попробовал предложенную идею отфильтровать в репозитории, но проблема состоит в том, что мое приложение обеспечивает контекст арендатора (через субдомен) и только взаимодействует с уровнем служб. Передача контекста полностью к слою репозитория является миссией.
Так вместо этого я решил отфильтровать свои данные на уровне служб. Я чувствую, что репозиторий должен представить все данные, физически доступные в репозитории с соответствующими фильтрами для получения определенных для арендатора данных, чтобы использоваться уровнем служб.
Я закончил тем, что отказался от этого подхода из-за ненужных сложностей. См. мой ответ ниже.
Обновление: Отказ от многопользовательского подхода стоил мне сотен часов технического долга. Спустя четыре года я жалею, что не потратил время на то, чтобы сначала реализовать подход с чистыми арендаторами. Не повторяйте мою ошибку!
В итоге я удалил весь многопользовательский код в пользу использования отдельных приложений и баз данных для каждого арендатора. В моем случае у меня немного арендаторов, которые не часто меняются, поэтому я могу сделать следующее.
Все мои контроллеры, провайдеры членства, провайдеры ролей, сервисы и репозитории тяготели к дублированию кода .WithTenantID(...)
повсюду, что заставило меня понять, что мне не нужна одна таблица Users
для доступа к данным, специфичным для одного арендатора 99% времени, поэтому использование отдельных приложений просто имеет больше смысла и делает все намного проще.
Спасибо за ваши ответы - они помогли мне понять, что мне нужен редизайн.
@FreshCode, мы делаем это в репозитории, и мы не передаем арендатора в качестве параметра. Мы используем следующий подход:
public IQueryable<Job> GetJobs()
{
return _db.Jobs.Where(j=>j.TenantId == Context.TenantId);
}
Контекст - это зависимость, которая есть у репозитория и которая создается в BeginRequest, где вы определяете арендатора, например, на основе url.
Я думаю, что таким образом все довольно прозрачно и можно избежать параметра tenantId
, который может немного мешать.
С уважением.