asp.net核心 – 如何在Asp.Net Core中注册同一个接口的多个实现?

前端之家收集整理的这篇文章主要介绍了asp.net核心 – 如何在Asp.Net Core中注册同一个接口的多个实现?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有从同一个接口派生的服务
public interface IService
{
}

public class ServiceA : IService
{
}

public class ServiceB : IService
{    
}

public class ServiceC : IService
{    
}

通常,其他诸如Unity的IOC容器允许您通过区分它们的某些Key注册具体的实现.

在Asp.Net Core中如何注册这些服务,并在运行时根据一些关键点解决它们?

我没有看到任何Add Service方法采用通常用于区分具体实现的key或name参数.

public void ConfigureServices(IServiceCollection services)
    {            
         // How do I register services here of the same interface            
    }


    public MyController:Controller
    {
       public void DoSomeThing(string key)
       { 
          // How do get service based on key
       }
    }

工厂模式是唯一的选择吗?

UPDATE1
我已经通过了文章here,显示了如何使用工厂模式来获取服务实例,当我们有多个混合实现.但是还没有完全解决.当我调用_serviceProvider.GetService()方法时,我无法将数据注入到构造函数中.例如考虑这个例子

public class ServiceA : IService
{
     private string _efConnectionString;
     ServiceA(string efconnectionString)
     {
       _efConnecttionString = efConnectionString;
     } 
}

public class ServiceB : IService
{    
   private string _mongoConnectionString;
   public ServiceB(string mongoConnectionString)
   {
      _mongoConnectionString = mongoConnectionString;
   }
}

public class ServiceC : IService
{    
    private string _someOtherConnectionString
    public ServiceC(string someOtherConnectionString)
    {
      _someOtherConnectionString = someOtherConnectionString;
    }
}

_serviceProvider.GetService()如何注入适当的连接字符串?
在Unity或任何其他IOC中,我们可以在类型注册时做到这一点.我可以使用IOption,这将需要我注入所有设置,我不能注入一个特定的连接字符串到服务.

还要注意,我试图避免使用其他容器(包括Unity),因为我必须使用新的容器注册所有其他容器(例如Controllers).

使用工厂模式创建服务实例也是针对DIP,因为工厂增加了客户端被迫依赖于details here的依赖关系

所以我认为默认DI在ASP.NET内核缺少2件事情
1>使用密钥注册实例
2在注册期间将静态数据注入到构造器中

解决方法

它不受Microsoft.Extensions.DependencyInjection的支持.

但是您可以插入另一个依赖注入机制,如StructureMap See it’s Home page,它是GitHub Project.

这不难:

>在project.json中添加一个依赖关系到StructureMap:

"Structuremap.Microsoft.DependencyInjection" : "1.0.1",

>将其注入到配置服务中的ASP.NET管道中,并注册您的类(see docs)

public IServiceProvider ConfigureServices(IServiceCollection services) // returns IServiceProvider !
{
    // Add framework services.
    services.AddMvc();
    services.AddWhatever();

    //using StructureMap;
    var container = new Container();
    container.Configure(config =>
    {
        // Register stuff in container,using the StructureMap APIs...
        config.For<IPet>().Add(new Cat("CatA")).Named("A");
        config.For<IPet>().Add(new Cat("CatB")).Named("B");
        config.For<IPet>().Use("A"); // Optionally set a default
        config.Populate(services);
    });

    return container.GetInstance<IServiceProvider>();
}

>然后,要获取命名实例,您需要请求IContainer

public class HomeController : Controller
{
    public HomeController(IContainer injectedContainer)
    {
        var myPet = injectedContainer.GetInstance<IPet>("B");
        string name = myPet.Name; // Returns "CatB"

而已.

对于要构建的示例,您需要

public interface IPet
    {
        string Name { get; set; }
    }

    public class Cat : IPet
    {
        public Cat(string name)
        {
            Name = name;
        }

        public string Name {get; set; }
    }

猜你在找的.NET Core相关文章