我正在構建一個多租戶MVC應用程序,其中有一個應用程序池和單個數據庫。我有一個租戶表,我的每個模型都有一個TenantId標識。使服務層可訪問的對象不作爲參數在MVC4中傳遞應用程序
每個租戶都有一個字符串「Url」,用於標識用於訪問該租戶數據的完整URL。在一個點,我需要向租客傳遞到服務層來執行業務邏輯
HttpRequest request = HttpContext.Current.Request;
Uri requestUrl = request.Url;
_tenant = _tenantService.GetTenantByUrl(requestUrl);
現在,我:
我可以從我的BaseController具有以下(粗略估計)訪問此。我可以做到這一點的一種方法是跨所有服務(〜200個方法)遍歷每一種方法並添加一個Tenant參數。我不得不觸摸每個呼叫到服務層,並且每個服務層方法。這會起作用,但它很繁瑣,並且混淆了代碼。
例如,我的一個方法之前:
public void DeleteUserById(int userId)
{
using (var db = CreateContext())
{
var user = db.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
後(如果我通過在租戶):
public void DeleteUserById(Tenant tenant, int userId)
{
using (var db = CreateContext())
{
var user = tenant.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
我試圖實現(通過設置租戶我BaseController,上升一層):
public void DeleteUserById(int userId)
{
using (var db = CreateContext())
{
var user = _tenant.Users.FirstOrDefault(u => u.UserId.Equals(userId));
InternalDeleteUser(db, user);
}
}
有什麼辦法,我可以用我的BaseService(所有其他服務繼承來回回m this)還是其他一些模式來定義控制器中的租戶,並讓服務方法撿起它,而不將它作爲參數傳遞給每個?這樣我只需要觸摸基本控制器(或甚至可能是global.asax),而不需要其他任何東西。
簡單地說:如何通過從MVC控制器定義一個對象,而無需將其直接傳遞給服務,讓所有服務都可以訪問對象?
你進行某種形式的用戶認證的?我覺得將TenantId與當前用戶聯繫起來很自然。請參閱[此堆棧溢出問題](http://stackoverflow.com/questions/1064271/asp-net-mvc-set-custom-iidentity-or-iprincipal)以瞭解如何將自定義字段添加到當前身份/主體目的。然後你可以像服務層代碼那樣訪問TenantId:'((MyCustomPrincipal)HttpContext.Current.User).TenantId'。 –
@EiríkurFannarTorfason我有自定義成員資格設置和用戶目前正與租戶配對,但是並不是所有的查詢涉及用戶,所以我不認爲這種做法是可行的。 – SB2055
好吧,總是有'Session'對象。 –