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

2023-11-27

我有从同一接口派生的服务。

public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { } 
public class ServiceC : IService { }

通常,其他 IoC 容器如Unity允许您注册一些具体的实现Key这使他们与众不同。

在 ASP.NET Core 中,如何注册这些服务并在运行时根据某个密钥解析它们?

我没有看到任何Add服务方法key or name参数,通常用于区分具体实现。

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


    public MyController:Controller
    {
       public void DoSomething(string key)
       { 
          // How do I resolve the service by 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;
    }
}

How can _serviceProvider.GetService()注入适当的连接字符串? 在 Unity 或任何其他 IoC 库中,我们可以在类型注册时执行此操作。我可以用IOption但是,这需要我注入所有设置。我无法将特定的连接字符串注入到服务中。

另请注意,我试图避免使用其他容器(包括 Unity),因为这样我还必须使用新容器注册其他所有内容(例如控制器)。

此外,使用工厂模式创建服务实例也不符合 DIP,因为它会增加客户端的依赖项数量详细信息在这里.

所以,我认为 ASP.NET Core 中的默认 DI 缺少两件事:

  1. 使用密钥注册实例的能力
  2. 能够在注册期间将静态数据注入构造函数

我使用了一个简单的解决方法Func当我发现自己处于这种情况时。

首先声明一个共享委托:

public delegate IService ServiceResolver(string key);

然后在你的Startup.cs,设置多个具体注册和这些类型的手动映射:

services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();

services.AddTransient<ServiceResolver>(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(); // or maybe return null, up to you
    }
});

并从通过 DI 注册的任何类中使用它:

public class Consumer
{
    private readonly IService _aService;

    public Consumer(ServiceResolver serviceAccessor)
    {
        _aService = serviceAccessor("A");
    }

    public void UseServiceA()
    {
        _aService.DoTheThing();
    }
}

请记住,在这个例子中,解析的关键是一个字符串,为了简单起见,并且因为 OP 特别要求这种情况。

但是您可以使用任何自定义解析类型作为键,因为您通常不希望巨大的 n-case 开关破坏您的代码。取决于您的应用程序的扩展方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Asp.Net Core中注册同一接口的多个实现? 的相关文章

  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • 在 VS2017 下使用 Conan 和 CMake 项目进行依赖管理

    我正在尝试使用 CMake 与 VS2017 集成为 C 设置一个开发环境 以便在 Linux x64 下进行编译 为了更好地管理依赖关系 我选择使用 Conan 但我对这个软件还很陌生 我想知道让 VS2017 识别项目依赖关系的最佳方法
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 选择列表逻辑应位于 ASP.NET MVC、视图、模型或控制器中的什么位置?

    我觉得我的问题与这个问题很接近 但我想对这样的代码应该放在哪里进行更一般的讨论 Asp Net MVC SelectList 重构问题 https stackoverflow com questions 2149855 asp net mv
  • 如何创建用于 QML 的通用对象模型?

    我想知道是否有任何宏或方法如何将 Qt 模型注册为 QObject 的属性 例如 我有AnimalModel http doc qt io qt 5 qtquick modelviewsdata cppmodels html qabstra
  • 如何在 C++ 中将 CString 转换为 double?

    我如何转换CString to a double在 C 中 Unicode 支持也很好 Thanks A CString可以转换为LPCTSTR 这基本上是一个const char const wchar t 在 Unicode 版本中 知
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 默认析构函数做了多少事情

    C 类中的默认析构函数是否会自动删除代码中未显式分配的成员 例如 class C public C int arr 100 int main void C myC new C delete myC return 0 删除 myC 会自动释放
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • 如何随着分辨率的变化自动调整大小和调整表单控件

    我注意到某些应用程序会更改控件的位置以尽可能适应当前的分辨率 例如 如果窗口最大化 则控件的设置方式应使整个 GUI 看起来平衡 是否可以使用 C 在 Visual studio 2010 中制作或实现此功能 Use Dock http m
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • 帮助了解像素化算法背后的理论吗?

    假设我有一张想要 像素化 的图像 我想要这个由 100 x 100 方格网格表示的清晰图像 因此 如果原始照片为 500 px X 500 px 则每个正方形为 5 px X 5 px 因此 每个正方形都有一个与它交换的 5 px X 5
  • Angular ReactiveForms:生成复选框值数组?

    给定绑定到相同复选框的列表formControlName 如何生成绑定到的复选框值数组formControl 而不是简单地true false Example
  • TinyMCE 处于只读模式时启用按钮

    我有一个 TinyMCE 4 x 实例 其中文本应处于只读模式 但我仍然有一些想要启用的按钮 例如 一个按钮可以提供我选择的文本部分的字符计数 但是当我打开 TinyMCE 的只读模式时 所有按钮都被禁用 我可以只启用我的按钮 同时仍保留只
  • (半)自动生成函数的 argparsers

    tldnr 给定一个函数 有没有办法根据其签名自动创建 ArgumentParser 我有很多想要向命令行公开的函数 基本上 一个模块 def copy foo bar baz def move from to def unlink par
  • 我应该将日期时间作为长整型(刻度)存储在数据库中吗?

    通过将 DateTime 值保存为long反而 使用 null DateTime 值时似乎总是会出现问题 无论是存储还是检索 null DateTimes 无效 DateTimes 等总是令人痛苦 是否建议简单地与long数据类型 因为您始
  • Jax 向量化:vmap 和/或 numpy.vectorize?

    之间有什么区别jax numpy vectorizeand jax vmap 这是一个小片段集 import jax import jax numpy as jnp def f x return jnp exp x jnp sin x gf
  • 如何转换 CSS 显示 + 不透明度属性

    我的 CSS3 动画有问题 child opacity 0 display none webkit transition opacity 0 5s ease in out moz transition opacity 0 5s ease i
  • 如何绕过警告“右值用作左值”?

    我在用着本教程 但是当我从中编译代码时 D3DXMatrixLookAtLH matView D3DXVECTOR3 0 0f 10 0f 0 0f warning C4238 D3DXVECTOR3 0 0f 0 0f 0 0f warn
  • 如何将WPF页面添加到tabcontrol?

    I have this main wpf window 和这个 WPF 页面 我需要将此页面添加到主窗口中的选项卡控件 这是我的 OnRender 方法 protected override void OnRender DrawingCon
  • Laravel Eloquent 与 DB Facade:何时使用哪个? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我在之间做了一些性能测试Laravel DB 门面查询生成器 and Laravel 的 Eloquent ORM 对于许多 SQL 语句 SELECT UPDATE DELET
  • 如何减小产品包大小?

    我有一个简单的应用程序 初始化为angular cli 它显示了与 3 个路由相关的一些页面 我有 3 个组件 在此页面之一上我使用lodash和 Angular 2 HTTP 模块来获取一些数据 使用 RxJSObservables ma
  • 对当前使用的成员进行联盟测试

    工会是否有控制结构来测试当前正在使用哪个成员 或者是否有 我问这个问题是因为程序中存在未定义的行为从来都不是一件好事 不 现成的机制不存在 你必须自己处理这个问题 通常的方法是包装union in a struct struct MyUni
  • 如何在反应中使超链接外部?

    我是新来反应并在组件中有此链接 a href https example com faq html FAQ a 我要服务器faq html外界反应 问题是 React 将链接视为内部链接并给出 404 我见过一个相似的建议使用的问题
  • iframe 内的图像样式

    我通过设置 iframe 的 src 属性在 iframe 中有一个图像 iframe 具有固定的高度和宽度 我希望该图像的宽度填充 iframe 但其高度将与宽度保持成比例 以便用户能够向下滚动 iframe 以查看图像的其余部分 我该怎
  • matplotlib 轴上的不同精度

    我的老师说 在图表中我必须将轴标记为0 0 25 0 5 not 0 00 0 25 0 50 我知道如何标记它0 00 0 25 0 50 plt yticks np arange 1 5 1 5 25 但是 我不知道如何以不同的精度绘制
  • Delphi 中检测磁盘活动

    我正在使用Delphi 2007 我正在将文件复制到远程驱动器 复印结束后 我关闭 待机机器 可能会发生某些文件没有从缓冲区复制到磁盘的情况 并且远程磁盘断开连接 因此备份未完成 我需要检测该磁盘上的磁盘活动 以便能够正确地在计算机上执行关
  • Zend Framework 中的数据库事务:它们是隔离的吗?

    使用 Zend Framework 我需要 1 从 MySQL 数据库读取一条记录 以及 2 立即写回该记录以表明它已被读取 我不希望其他进程或查询能够在步骤 1 和 2 之间读取或写入同一记录 我正在考虑使用事务来完成这些步骤 如果我使用
  • 在 ejabberd 上使用 Smack 创建新用户会抛出 XMPP 异常:禁止(403)

    您好 我正在研究 ejabberd 我对这项技术还很陌生 我正在尝试使用以下代码在我的 ejabberd 服务器上添加用户 try conf setSASLAuthenticationEnabled true connection conn
  • ios - 动态编辑 3d touch 快捷方式列表

    我想在我的游戏中添加 继续 快捷方式 但是 当用户完全完成我的游戏时 我希望将其删除或替换为另一个快捷方式 这可能吗 我知道 3d touch 是由 ios 系统处理的 但也许还有一些选择 创建快捷方式有两种方法 动态和静态 静态被添加到
  • 如何在Asp.Net Core中注册同一接口的多个实现?

    我有从同一接口派生的服务 public interface IService public class ServiceA IService public class ServiceB IService public class Servic