在.NET Core中处理一个接口多个不同实现的依赖注入问题
2018-02-04 00:00
597 查看
前言
近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了。博客也就停了一下下。在.NET Core中处理依赖注入问题时,往往是定义好了一个操作规范的接口,会有N多个基于不同技术的实现,根据实际情况在项目中去使用某一个实现。但是偶尔会出现这样的情况,在某一个地方,需要同时使用到两种或两种以上的实现,这个时候我们要怎么处理呢?借助Autofac等第三方组件时,是可以很容易的实现,但是在写一些基础类库时会避免直接引用太多依赖组件。所以这里是只用微软自带的DI(Microsoft.Extensions.DependencyInjection)去处理。例子引入
现在有一个接口和两个实现类。public interface IDemoService{ string Get(); } public class DemoServiceA : IDemoService{ public string Get() { return "Service A"; } } public class DemoServiceB : IDemoService{ public string Get() { return "Service B"; } }常规的方法,我们先在Startup中的ConfigureServices方法中添加我们的service。
public void ConfigureServices(IServiceCollection services){ services.AddSingleton<IDemoService, DemoServiceA>(); services.AddSingleton<IDemoService, DemoServiceB>(); services.AddMvc(); }然后在控制器中使用
private IDemoService _serviceA; private IDemoService _serviceB; public ValuesController(IDemoService serviceA, IDemoService serviceB){ _serviceA = serviceA; _serviceB = serviceB; } // GET api/values [HttpGet] public string Get(){ return $"{_serviceA.Get()}-{_serviceB.Get()}"; }我们的预期结果是:
Service A-Service B,可是上面代码的实际结果却并不像我们想的那么简单!!
可以看到这里输出的都是
Service B,连
Service A的影子都没有看到。其实,从代码都可以看出来,它只能拿到其中一个Service的实现类!那么我们要息怎样处理才能达到我们想要的效果呢?其实思路比较简单,上面导致不能拿到对应实现类,本质上来讲应该说是它区分不了那个才是想要的!我们想个办法让它能区分就好了。
处理方法
给我们的Service起个别名!先是Startup中的ConfigureServices方法。public void ConfigureServices(IServiceCollection services){ services.AddSingleton<DemoServiceA>(); services.AddSingleton<DemoServiceB>(); services.AddSingleton(factory => { Func<string, IDemoService> accesor = key => { if (key.Equals("ServiceA")) { return factory.GetService<DemoServiceA>(); } else if (key.Equals("ServiceB")) { return factory.GetService<DemoServiceB>(); } else { throw new ArgumentException($"Not Support key : {key}"); } }; return accesor; }); services.AddMvc(); }这里并没有直接向上面那样一次性指定接口和对应的实现类,而是用了AddSingleton的另一个重载方法。先将实现类注册一下
然后再注册一下
Func<string, IDemoService>
先来说说这个
Func<string, IDemoService>里面的string和IDemoService都分别代表什么。string 毫无疑问就是我们上面说到的别名
IDemoService 这个就是我们要用的Service
核心在于,factory参数是IServiceProvider类型的!所以我们可以根据这个factory去找到我们前面注册的实现类。这样解释一下,是不是就清晰了呢?然后再来看看在控制器上面怎么用。
private IDemoService _serviceA; private IDemoService _serviceB; private readonly Func<string, IDemoService> _serviceAccessor; public ValuesController(Func<string, IDemoService> serviceAccessor){ this._serviceAccessor = serviceAccessor; _serviceA = _serviceAccessor("ServiceA"); _serviceB = _serviceAccessor("ServiceB"); } // GET api/values [HttpGet] public string Get(){ return $"{_serviceA.Get()}-{_serviceB.Get()}"; }最后看看结果是不是和我们的预期一样。
结果与预期一致。
总结
一对一,或许是最好的方法,也是最为理想的,这样能避开很多不必要的问题。但是现实中总会出现特殊情况,面对这些特殊情况,我们也是需要能够重容的面对。原文地址:http://www.cnblogs.com/catcher1994/p/handle-multi-implementations-with-same-interface-in-dotnet-core.html.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com相关文章推荐
- 在.NET Core中处理一个接口多个不同实现的依赖注入问题
- .Net Core 通过依赖注入和动态加载程序集实现宿主程序和接口实现类库完全解构
- spring中,一个接口两个实现类,注入问题
- Asp.net中处理一个站点不同Web应用共享Session的问题
- 山寨AjaxPro,解决分布式问题,实现主流接口,保留原版的API方法,唯一的不同是稍微修改下webconfig
- 关于依赖反转(基于接口编程)和依赖注入的一个小问题的领悟
- net2003转到net2005碰到的一个问题:不会实现接口成员“System.Web.IHttpHandler.IsReusable”
- 今天的问题:一个简单的例子,请帮我解开“接口实现Java‘隐藏实现细目’”的迷惑。
- Spring接口动态注入不同的实现类
- 使用spring的aop实现拦截action后出现依赖注入为空的问题
- 【单接口与多个实现类的注入处理】
- 实现System.IComparable接口的一个问题
- 通过hidden隐藏域和URL参数(在一个处理页面实现不同的处理内容)
- MVC3使用Unity实现依赖注入接口与于实现类自动注册
- Asp.net中处理一个站点不同Web应用共享Session的问题
- orange's一个操作系统的实现实验遇到的问题及处理方法
- 利用VC和ADO接口编写一个dll模块实现对数据库数据的处理
- 用Entities Framework实现代码优先和依赖注入所遇到的问题总结
- Web Services实现不同软件间的接口问题
- Asp.net中处理一个站点不同Web应用共享Session的问题