2016-07-06 24 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

相关问题