0

我在多租戶環境中使用Web API。每個租戶都有自己的具有相同結構的數據庫。租戶名稱作爲子域包含在URL中:http:// {tenant} .mysite.com/api/doodad/action如何讓Unity通過基於Web API請求的構造函數參數?

我寫了一個消息過濾器(DelegatingHandler)來提取租戶名稱並找到相應的數據庫。我目前正在請求參數中存儲這個值。

幾乎每個控制器操作都需要訪問指向此數據庫的DbContext。我沒有使用存儲庫模式。我在接受數據庫名稱的DbContext上創建了第二個構造函數。

我正在使用Unity在ApiController中注入DbContext的實例。我怎樣才能讓Unity調用DbContext的第二個構造函數來傳遞請求參數中的值?

+1

使用事實方法註冊。這樣你就可以提供明確的工廠方法。 –

回答

0

我沒有試過,但我認爲它應該工作...

您可以創建一個動作過濾器,將在HttpRequestMessage添加到當前分層容器,然後用註冊您的自定義的DbContext類型使用InjectionFactory來提取HttpRequestMessage並獲取數據庫名稱。

下面是一些未經測試的代碼...

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)] 
public class RegisterHttpRequestActionAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var container = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnityContainer)) as IUnityContainer; 
     container.RegisterInstance(actionContext.Request, new HierarchicalLifetimeManager()); 
    } 
} 

和配置...

IUnityContainer rootContainer = new UnityContainer(); 
GlobalConfiguration.Configuration.DependencyResolver = new UnityHierarchicalDependencyResolver(rootContainer); 
GlobalConfiguration.Configuration.Filters.Add(new RegisterHttpRequestActionAttribute()); 

rootContainer.RegisterType<MyDbContext>(new HierarchicalLifetimeManager(), new InjectionFactory(container => 
    new MyDbContext(container.Resolve<HttpRequestMessage>().Properties["TenantDB"] as string))); 

(僅供參考,我引用Unity.AspNet.WebApi NuGet包拿到UnityHierarchicalDependencyResolver)

相關問題