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

前端之家收集整理的这篇文章主要介绍了asp.net核心 – 如何在Asp.Net Core中注册同一个接口的多个实现?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有从同一个接口派生的服务
  1. public interface IService
  2. {
  3. }
  4.  
  5. public class ServiceA : IService
  6. {
  7. }
  8.  
  9. public class ServiceB : IService
  10. {
  11. }
  12.  
  13. public class ServiceC : IService
  14. {
  15. }

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

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

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

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // How do I register services here of the same interface
  4. }
  5.  
  6.  
  7. public MyController:Controller
  8. {
  9. public void DoSomeThing(string key)
  10. {
  11. // How do get service based on key
  12. }
  13. }

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

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

  1. public class ServiceA : IService
  2. {
  3. private string _efConnectionString;
  4. ServiceA(string efconnectionString)
  5. {
  6. _efConnecttionString = efConnectionString;
  7. }
  8. }
  9.  
  10. public class ServiceB : IService
  11. {
  12. private string _mongoConnectionString;
  13. public ServiceB(string mongoConnectionString)
  14. {
  15. _mongoConnectionString = mongoConnectionString;
  16. }
  17. }
  18.  
  19. public class ServiceC : IService
  20. {
  21. private string _someOtherConnectionString
  22. public ServiceC(string someOtherConnectionString)
  23. {
  24. _someOtherConnectionString = someOtherConnectionString;
  25. }
  26. }

_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:

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

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

  1. public IServiceProvider ConfigureServices(IServiceCollection services) // returns IServiceProvider !
  2. {
  3. // Add framework services.
  4. services.AddMvc();
  5. services.AddWhatever();
  6.  
  7. //using StructureMap;
  8. var container = new Container();
  9. container.Configure(config =>
  10. {
  11. // Register stuff in container,using the StructureMap APIs...
  12. config.For<IPet>().Add(new Cat("CatA")).Named("A");
  13. config.For<IPet>().Add(new Cat("CatB")).Named("B");
  14. config.For<IPet>().Use("A"); // Optionally set a default
  15. config.Populate(services);
  16. });
  17.  
  18. return container.GetInstance<IServiceProvider>();
  19. }

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

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

而已.

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

  1. public interface IPet
  2. {
  3. string Name { get; set; }
  4. }
  5.  
  6. public class Cat : IPet
  7. {
  8. public Cat(string name)
  9. {
  10. Name = name;
  11. }
  12.  
  13. public string Name {get; set; }
  14. }

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