2013-04-05 66 views
2

是否有可能在ASP.NET MVC 3中有多個依賴關係解析器(類似於ModelBinders和Providers的情況)?是否有可能在ASP.NET MVC 3中有多個依賴解析器?

+1

爲什麼你需要不止一個? – MikeSW 2013-04-05 21:04:47

+0

我想有一個全局的,其他的控制器工廠,其他的元數據提供者,另一個是驗證提供者。我的猜測是,爲每個任務分配一個依賴關係解析器可能會更高效一些,而不是隻有一個人管理項目中的依賴關係。 – 2013-04-05 21:13:15

回答

6

有一種情況,我可以想到有多個「容器」或「分解器」是有用的,這是多租戶。藉助多租戶,您可以在同一個Web應用程序中運行多個客戶(組織,擁有自己的一組用戶),並根據登錄,請求信息或域信息動態切換。

Still,DependencyResolver.Current is -as Darin指出 - 靜態,所以沒有什麼可以(或應該這樣做)。但是,您可以將多個容器隱藏在一個抽象中,並根據某些條件返回實現。這可能是這樣的:

public class MultiTenantDependencyResolver 
    : IDependencyResolver 
{ 
    Func<int> tenantIdSelector,; 
    IDictionary<int, IDependencyResolver> tenantResolvers; 

    public MultiTenantDependencyResolver(
     Func<int> tenantIdSelector, 
     IDictionary<int, IDependencyResolver> tenantResolvers) 
    { 
     this.tenantIdSelector = tenantIdSelector; 
     this.tenantResolvers= tenantResolvers; 
    } 

    private IDependencyResolver CurrentResolver 
    { 
     get { return this.tenantResolvers[tenantIdSelector()]; } 
    } 

    public object GetService(Type serviceType) 
    { 
     return this.CurrentResolver.GetService(serviceType); 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return this.CurrentResolver.GetAllInstances(serviceType); 
    } 
} 

下面的代碼片段顯示了這個MultiTenantDependencyResolver用法:

var tenantResolvers = new Dictionary<int, IDependencyResolver> 
{ 
    { Tenants.AbcId, BuildResolver(RegisterForTenantAbc) }, 
    { Tenants.KlmId, BuildResolver(RegisterForTenantKlm) }, 
    { Tenants.XyzId, BuildResolver(RegisterForTenantXyz) }, 
}; 

var multiTenantResolver = new MultiTenantResolver(
    () => GetTenantIdFromUrl(), tenantResolvers); 

DependencyResolver.SetResolver(multiTenantResolver); 


private static int GetTenantIdFromUrl() 
{ 
    // TODO: return tenant id 
} 

private static IDependencyResolver BuildResolver(
    Action<IKernel> tenantSpecificRegistrations) 
{ 
    var kernel = new Kernel(); 

    // TODO: Tenant agnostic registrations. For instance 
    kernel.Bind<ITimeProvider>().To<SystemTimeProvider>(); 

    tenantSpecificRegistrations(kernel); 

    return new NinjectDependencyResolver(kernel); 
} 

private static void RegisterForTenantAbc(IKernel kernel) 
{ 
    // TODO: regisrations for ABC tenant. For instance 
    kernel.Bind<ILogger>().To<AbcTenantLogger>(); 
} 
+0

非常感謝,我喜歡你提出的方法。此外,它可以非常透明地爲每種情況獲得適當的解析器。 – 2013-04-05 22:05:34

+0

所以如果你有100k租戶(想想github),你將有100k依賴解析器?!我現在正在開發一個多租戶應用程序,一個解析器就足夠了。多於一個是沒有意義的。順便說一句,GetTenantId方法應該是一個http模塊,而不是一個靜態方法 – MikeSW 2013-04-06 08:23:02

+0

不,不! Tenant!=用戶。多租戶應用通常會爲多達十幾個租戶提供服務。你只有在你必須以編程的方式區分各個元素時纔會這樣做。 Havin 100k內核對內存和性能來說是非常糟糕的。 – Steven 2013-04-06 08:39:09

2

是否有可能在ASP.NET中有多個依賴關係解析器 MVC 3(類似於ModelBinders和Providers的情況)?

不,這是不可能的。 DependencyResolver.Current是一個靜態屬性,只能分配一個解析器。這就是說,在一個應用程序中有多個依賴關係解析器幾乎沒有任何意義。這個想法是,所有的依賴項都是由一個依賴注入框架(如Unity,Ninject或StructureMap)來管理的。然後,您將擁有一個自定義的依賴關係解析器,它包裝了您選擇的DI框架,ASP.NET MVC將使用它來在執行管道的各種對象中注入依賴關係。

您在您的問題中將其與模型活頁夾進行比較,但這種比較是不公平的,因爲模型活頁夾與它旨在綁定的特定類型相關。基本上你可以有多個視圖模型的自定義模型綁定器。

在你的問題中,你似乎也提到了一些供應商,但不幸的是你沒有特別注意,所以對此評論有點難。

+0

是的,你說得對,我認爲與模型粘合劑和提供者進行比較是不公平的。 – 2013-04-05 21:20:14

相關問題