Asp.net-Mvc
多租戶訪問控制:儲存庫還是服務層?
在基於 Rob Conery 的 MVC Storefront 的多租戶 ASP.NET MVC 應用程序中,我應該過濾儲存庫或服務層中的租戶數據嗎?
- 過濾倉庫中租戶的數據:
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可能會變得有點令人不安的參數。問候。