问题描述
在ASP.NET Core应用程序开发中,依赖注入(Dependency Injection,简称DI)是经常被使用到的一种解耦方式,而DI是基于接口及其对应的实现的。在同一个接口只有一个实现类的情况下,我们通常可以通过ASP.NET Core的Startup.cs
中的ConfigureServices
使用类似services.AddScoped<IMyDependency, MyDependency>();
来注入,然后在需要使用服务的类中调用接口即可。
但如果一个接口有多个实现类,这时又应该如何注入这个接口的多个实现,并且又该如何分别调用这个实现类呢?
比如当前有接口:
public interface IService{}
分别有如下的三个实现类:
public class ServiceA : IService { }
public class ServiceB : IService { }
public class ServiceC : IService { }
方案一
使用Func
委托实现依赖注入,如下:
services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();
services.AddTransient<Func<string, IService>>(serviceProvider => key =>
{
switch(key)
{
case "A":
return serviceProvider.GetService<ServiceA>();
case "B":
return serviceProvider.GetService<ServiceB>();
case "C":
return serviceProvider.GetService<ServiceC>();
default:
throw new KeyNotFoundException();
}
});
调用示例:
public class Consumer
{
private readonly Func<string, IService> _serviceAccessor;
public Consumer(Func<string, IService> serviceAccessor)
{
_serviceAccessor = serviceAccesor;
}
public void UseServiceA()
{
//调用上面注册的服务关键字(A,B,C)为调用相应的实现类
_serviceAccessor("A").DoIServiceOperation();
}
}
方案二
另外一种方案是使用命名空间Microsoft.Extensions.DependencyInjection
是的扩展方法GetServices()
,注册服务如下:
services.AddSingleton<IService, ServiceA>();
services.AddSingleton<IService, ServiceB>();
services.AddSingleton<IService, ServiceC>();
然后在需要使用服务的地方使用IServiceProvider
的GetServices()
方法,如下:
var services = serviceProvider.GetServices<IService>();
var serviceB = services.First(o => o.GetType() == typeof(ServiceB));
如果IService
接口中定义了一个Name
的属性,我们还可依据Name
属性的值来获取不同的接口实现服务,如下:
var serviceZ = services.First(o => o.Name.Equals("Z"));
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册