在.NET Core中处理一个接口多个不同实现的依赖注入问题

前言

近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了。博客也就停了一下下。

在.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的另一个重载方法。

  1. 先将实现类注册一下

  2. 然后再注册一下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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322193.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3085,jzoj3234-[USACO13OPEN]阴和阳【点分治】

正题 题目链接:https://www.luogu.org/problemnew/show/P3085 题目大意 一棵树只有−1-1−1和111的边权&#xff0c;询问有多少条路径可以找到一个分界点使得分出的两条路径长度为000。 解题思路 询问路径显然点分治一波。 然后考虑分界点的两种情况 分界点在当前扫描到的…

Nacos(十)之Kubernetes Nacos

转载自 Kubernetes Nacos 本项目包含一个可构建的Nacos Docker Image&#xff0c;旨在利用StatefulSets在Kubernetes上部署Nacos 快速开始 Clone 项目 git clone https://github.com/nacos-group/nacos-k8s.git简单例子如果你使用简单方式快速启动,请注意这是没有使用持久化…

.net core连接MongoDB

前两天在学习MongoDB相关的知识&#xff0c;做了个小Demo&#xff0c;做的是省份下面有多少所学校&#xff0c;嗯&#xff0c;做的比较粗暴。。。连接MongoDB首先要通过Nuget添加一个MongoDB的包&#xff0c;下载此包安装完毕后开始写代码了&#xff0c;创建一个省份实体&#…

P4139-上帝与集合的正确用法【欧拉定理】

正题 题目链接:https://www.luogu.org/problemnew/show/P4139 题目大意 求2222222...%p2^{2^{2^{2^{2^{2^{2^{...}}}}}}}\%p2222222...%p 解题思路 欧拉定理 ab{ab%φ(p)φ(p)(b>φ(p))ab%φ(p)(b≤φ(p))a^b\left\{\begin{matrix}a^{b\%\varphi(p)\varphi(p)}(b>\var…

Nacos(十一)之NacosSync 介绍

转载自 NacosSync 介绍 介绍 NacosSync是一个支持多种注册中心的同步组件,基于Spring boot开发框架,数据层采用Spring Data JPA,遵循了标准的JPA访问规范,支持多种数据源存储,默认使用Hibernate实现,更加方便的支持表的自动创建更新使用了高效的事件异步驱动模型, 支持多种自…

Ocelot 集成Butterfly 实现分布式跟踪

微服务&#xff0c;通常都是用复杂的、大规模分布式集群来实现的。微服务构建在不同的软件模块上&#xff0c;这些软件模块&#xff0c;有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器&#xff0c;横跨多个不同的数据中心。因此&#xff0…

jzoj1213-棋盘上的士兵【状压dp】

正题 题目大意 一个骑士会攻击对角线的位置&#xff0c;然后n∗nn*nn∗n的棋盘上放mmm个骑士求方案数。 解题思路 我们将棋盘翻转以两个对角线为中间&#xff0c;这样骑士就变成了横着打和竖着打。 设fi,s,jf_{i,s,j}fi,s,j​表示第iii条对角线&#xff0c;不能放置骑士的位置…

Nacos(十二)之Java SDK

转载自 Java SDK 概述部分 Maven 坐标 <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>${version}</version> </dependency>配置管理 获取配置 描述 用于服务启动…

聊聊AspectCore动态代理中的拦截器(一)

前言在上一篇文章使用AspectCore动态代理中&#xff0c;简单说明了AspectCore.DynamicProxy的使用方式&#xff0c;由于介绍的比较浅显&#xff0c;也有不少同学留言询问拦截器的配置&#xff0c;那么在这篇文章中&#xff0c;我们来详细看一下AspectCore中的拦截器使用。两种配…

P5135-painting【组合数学】

正题 题目链接:https://www.luogu.org/problemnew/show/P5135 题目大意 n∗mn*mn∗m的矩阵每列恰好有一个黑格子&#xff0c;询问两个中一个 每列黑格子所在行数不下降每列黑格子所在行数单调上升 的方案数 解题思路 显然询问1答案就是Cnm−1mC_{nm-1}^mCnm−1m​(插板法) …

你可能不知道的.Net Core Configuration

执行原理1. 配置读取顺序&#xff1a;与代码先后顺序一致。public Startup(IHostingEnvironment env){var builder new ConfigurationBuilder().SetBasePath(env.ContentRootPath).AddJsonFile("appsettings.json", false, true).AddJsonFile("cussettings.jso…

Dubbo(一)之简介

转载自 Dubbo 2.7入门 一、背景 本文介绍了网站应用的演进 随着互联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的垂直应用架构已无法应对&#xff0c;分布式服务架构以及流动计算架构势在必行&#xff0c;亟需一个治理系统确保架构有条不紊的演进。 单一…

P1600-天天爱跑步【LCA,桶,树上差分】

正题 题目链接:https://www.luogu.org/problemnew/show/P1600 题目大意 一棵nnn个点的树&#xff0c;通过每条边需要时间为1。有mmm个玩家从SiS_iSi​跑到TiT_iTi​&#xff08;不停留&#xff0c;跑完之后马上消失&#xff09;。然后对于第iii个点求第wiw_iwi​刻停留在改点…

Dubbo(二)之SpringBoot nacos集成

一、框架 使用springboot启动&#xff0c;注册中心现在naocs。 nacos安装 二、样例项目 &#xff08;1&#xff09;maven设置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId> <…

ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

在上文中&#xff0c;我们讨论了事件处理器中对象生命周期的问题&#xff0c;在进入新的讨论之前&#xff0c;首先让我们总结一下&#xff0c;我们已经实现了哪些内容。下面的类图描述了我们已经实现的组件及其之间的关系&#xff0c;貌似系统已经变得越来越复杂了。其中绿色的…

P5024-保卫王国【动态dp,最小覆盖集】

正题 题目链接:https://www.luogu.org/problem/P5024 题目大意 一棵树&#xff0c;每次有要求 axby:a\ x\ b\ y:a x b y:表示aaa点是否必选和bbb点是否必选 然后每次求最小覆盖集。 解题思路 最小覆盖集全集-最大独立集 所以我们每次必选不选就用infinfinf或−inf-inf−inf…

Dubbo(三)之Spring zookeeper集成

转载自 Dubbo快速开始 Dubbo 采用全 Spring 配置方式&#xff0c;透明化接入应用&#xff0c;对应用没有任何 API 侵入&#xff0c;只需用 Spring 加载 Dubbo 的配置即可&#xff0c;Dubbo 基于 Spring 的 Schema 扩展 进行加载。 如果不想使用 Spring 配置&#xff0c;可以…

浅谈开发模式及架构发展

一、传统开发模式传统的开发模式基本一般是重服务端的开发方式&#xff0c;大部分工作都在服务端执行&#xff0c;然后返回到客户端&#xff08;通常是HTML&#xff09;。以Asp.net MVC为例&#xff0c;如下图&#xff1a;#1 根据请求的路由定位到对应的Controller的对应的Acti…

P1613-跑路【Floyd,倍增】

正题 题目链接:https://www.luogu.org/problem/P1613 题目大意 询问111到nnn的路径&#xff0c;每次可以走2n2^n2n条边&#xff0c;求最少次数(可以重复)。 解题思路 定义geti,j,tget_{i,j,t}geti,j,t​表示iii到jjj是否有2t2^t2t的路径。 然后geti,j,tgeti,k,t−1&amp;…

Dubbo(四)之xml配置方式

转载自 Dubbo xml配置方式 以 XML 配置的方式来配置你的 Dubbo 应用 有关 XML 的详细配置项&#xff0c;请参见&#xff1a;配置参考手册。如果不想使用 Spring 配置&#xff0c;而希望通过 API 的方式进行调用&#xff0c;请参见&#xff1a;API配置。想知道如何使用配置&a…