2016-07-06 47 views
1

我有兩個MVC控制器。如何解決不同控制器中的不同服務?

兩個控制器都依賴於IFileContainer接口。

在一個控制器中,我想解析FsFileContainer,而在第二個控制器中我想解析FtpFileContainer

註冊:

serviceCollection.AddTransient<IFileContainer, FsFileContainer>(); 
    serviceCollection.AddTransient<IFileContainer, FtpFileContainer>(); 

如何在這種情況下,解決集裝箱?

+2

請注入這些

// It defines no new methods or properties, just inherits it and acts as marker public interface IFsFileContainer : IFileContainer {} public interface IFtpFileContainer : IFileContainer {} public class FsFileContainer : IFsFileContainer { ... } 

,不使用MVC6標籤了。它適用於基於舊webstack(MVC5)的ASP.NET MVC的未來版本。 ASP.NET Core是一個基於.NET Core的全新且不兼容的可移植版本。使用[tag:asp.net-core-mvc]和/或[tag:asp.net-core]標籤代替,您的問題更有可能由可以幫助您解決問題的人員找到。其次,不要再使用dnx,它不再被開發。新版本僅適用於https://www.microsoft.com/net/core#windows中的dotnet-cli工具鏈。儘快升級到1.0 RTM – Tseng

回答

2

最簡單的方法是使用工廠,因爲ASP.NET Core IoC容器不支持命名依賴性或使用支持它的第三方IoC容器。

public class FileContainerFactory : IFileContainerFactory 
{ 
    private readonly IServiceProvider provider; 
    public class FileContainerFactory(IServiceProvider provider) 
    { 
     this.provider = provider; 
    } 

    public IFileContainer CreateFileSystemContainer() 
    { 
     // resolve it via built in IoC 
     return provider.GetService<FsFileContainer>(); 
    } 

    public IFileContainer CreateFtpContainer() 
    { 
     // resolve it via built in IoC 
     return provider.GetService<FtpFileContainer>(); 
    } 
} 

然後將IFileContainerFactory注入您的控制器。

另一種方法是用一個標記接口來標記你的接口和寄存器/在Startup.cs

services.AddTransient<IFsFileContainer, IFileContainer>(); 
services.AddTransient<IFtpFileContainer, IFileContainer>(); 
+1

我不會推薦第一個選項。使用某種服務定位器模式並不是很好。看到這裏:http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/ –

+1

@JamieR:工廠模式不是服務定位器,其中的提供者是由IoC框架注入(而不是注入容器插入到你的服務中,或者有一個靜態類來解析),因此它不會像服務定位器那樣隱藏依賴關係。該接口可以被模擬爲單元測試,並且是實例化需要運行時參數的對象的最常見方式。另外不要忘記,大多數工廠實現不屬於業務/域層,它屬於應用層,應用服務可以知道IoC容器。域和基礎架構不應該 – Tseng

+1

你引用Mark Seemann,因爲他是抽象工廠模式的倡導者,這很有趣。 http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657。第三種選擇當然是使用門面模式並提供兩個實例作爲屬性或使用策略模式。如果沒有更多的信息,就很難提出具體的策略,因爲我們不知道OP是否控制了它們是否是第三方實現的實現,那麼可能很難執行標記接口,因爲這需要第三方更新實施 – Tseng

相關問題