Asp.net-Mvc

多租戶訪問控制:儲存庫還是服務層?

  • March 3, 2014

在基於 Rob Conery 的 MVC Storefront 的多租戶 ASP.NET MVC 應用程序中,我應該過濾儲存庫服務層中的租戶數據嗎?

  1. 過濾倉庫中租戶的數據:

public interface IJobRepository
{
   IQueryable<Job> GetJobs(short tenantId);
}

2.讓服務按租戶過濾儲存庫數據:

public interface IJobService
{
   IList<Job> GetJobs(short tenantId);
}

我的直覺是在服務層(選項 2)中執行此操作,但可以說每個租戶本質上都應該擁有自己的“虛擬儲存庫”(選項 1),而這個責任在於儲存庫。

  • 哪種方法最優雅:選項 1、選項 2 還是有更好的方法?

更新:

我嘗試了在儲存庫中過濾的建議想法,但問題是我的應用程序提供了租戶上下文(通過子域)並且只與服務層互動。將上下文一直傳遞到儲存庫層是一項任務。

因此,我選擇在服務層過濾我的數據。我認為儲存庫應該代表儲存庫中物理可用的所有數據,並使用適當的過濾器來檢索特定於租戶的數據,以供服務層使用。

最終更新:

由於不必要的複雜性,我最終放棄了這種方法。請看下面我的回答。

**更新:**不採用多租戶方法使我花費了數百小時的技術債務。四年後,我希望我能花時間首先實施清潔租戶方法。不要犯同樣的錯誤!


舊的,過時的答案:

我最終剝離了所有多租戶程式碼,轉而為每個租戶使用單獨的應用程序和數據庫。就我而言,我很少有不經常更換的租戶,所以我可以做到這一點。

我所有的控制器、成員資格提供者、角色提供者、服務和儲存庫都傾向於到處重複.WithTenantID(...)程式碼,這讓我意識到我真的不需要一張Users表來訪問 99% 的時間特定於一個租戶的數據,因此使用單獨的應用程序更有意義,並使一切變得如此簡單。

感謝您的回答 - 他們讓我意識到我需要重新設計。

@FreshCode,我們在儲存庫中進行,我們不將租戶作為參數傳遞。我們使用以下方法:

public IQueryable<Job> GetJobs()
{
   return _db.Jobs.Where(j=>j.TenantId == Context.TenantId);
}

上下文是儲存庫具有的依賴項,它是在 BeginRequest 中創建的,例如,您可以在其中根據 url 確定租戶。我認為這種方式非常透明,您可以避免tenantId可能會變得有點令人不安的參數。

問候。

引用自:https://stackoverflow.com/questions/2745373