.NET Core DI,为包注册默认实现

2023-12-20

如何使用 .NET Core 的 IoC 容器注册默认实现,并提供一种覆盖现有实现的方法?

例如,我可能想创建一个包,为某些服务提供默认实现。

namesapce Package 
{
    public interface ISomeService { }

    public class Default : ISomeService { }
}

然后在同一个包内使用该服务。

namesapce Package 
{
    public class Service 
    {
        Service(ISomeService service) { }
    }
}

如何注册ISomeService默认实现?

稍后,当在某些项目中使用此包并希望用另一个包覆盖现有实现时,应将默认值替换为覆盖。

namespace Project 
{
    public class Override : ISomeService { }
}

如果您的包包含一个配置类IServiceCollection,比如这样:

public class MyPackageInstaller
{
    public void Install(IServiceCollection services)
    {
        // Your package registers its services
    }
}

那么这也可以是您允许消费者进行可选更改的点。例如,您可以定义一个这样的类,它允许使用者指定某些服务的实现:

public class MyPackageRegistrationOptions
{
    public ServiceDescriptor FooServiceDescriptor { get; private set; }

    public void AddFooService(ServiceDescriptor fooDescriptor)
    {
        if (fooDescriptor.ServiceType != typeof(IFooService))
        {
            throw new ArgumentException("fooDescriptor must register type IFooService.");
        }
        FooServiceDescriptor = fooDescriptor;
    }
}

现在,您的安装程序可以采用这些选项,并注册消费者指定的实现或其自己的默认实现。

public class MyPackageInstaller
{
    private readonly MyPackageRegistrationOptions _options;

    public MyPackageInstaller(MyPackageRegistrationOptions options = null)
    {
        _options = options;
    }
    public void Install(IServiceCollection services)
    {
        if (_options?.FooServiceDescriptor != null)
            services.Add(_options.FooServiceDescriptor);
        else 
             // here's your default implementation
            services.AddSingleton<FooService>();
    }
}

Usage:

var services = new ServiceCollection();
var options = new MyPackageRegistrationOptions();
options.AddFooService(ServiceDescriptor.Singleton<IFooService, AlternateFooService>());
var installer = new MyPackageInstaller(options);
installer.Install(services);

乍一看,获得相同结果的方法似乎更长。好处是它可以让您更清楚哪些服务应该或不应该被覆盖。这样,感觉更像是在使用故意暴露的配置选项,而不是在探究包的内部结构。

而不是允许消费者添加ServiceDescriptor您可以允许他们仅指定一种服务类型,并且您的配置决定它如何注册(单例、瞬态等)

当库依赖于配置值(例如必须由使用者提供的连接字符串)时,这也是一种有用的模式。您可以将它们设置为构建选项的必需参数,然后将它们设置为构建安装程序所需的选项,或者仅将它们设置为安装程序中的必需参数。现在,如果没有所需的配置值,就无法安装该软件包。

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

.NET Core DI,为包注册默认实现 的相关文章

随机推荐

  • Apache 错误:AH00526 参数文件中无效的互斥目录:${APACHE_LOCK_DIR}(Apache2 Ubuntu VPS 服务器))

    每当我跑步时sudo apache2 S在我的服务器上它抛出以下错误 Sun Mar 04 16 17 22 303217 2018 core warn pid 31405 AH00111 Config variable APACHE LO
  • Sql Server:选择性 XML 索引未得到有效使用

    我正在探索提高应用程序性能的方法 但我只能在有限程度上影响数据库级别 SQL Server 版本是 2012 SP2 有问题的表和视图结构是 我不能真正影响这个 注意 xml 文档总共可能有几百个元素 CREATE TABLE Orders
  • 默认 Android 时区列表

    我想知道我是否可以获得 android 版本 2 3 3 时区选择列表的默认代码 String ids TimeZone getAvailableIDs for int i 0 i
  • 在Python中加载图像进行处理的最快方法

    我想以 numpy 数组的形式在我的 8gb 内存中加载超过 10000 个图像 到目前为止 我已经尝试过 cv2 imread keras preprocessing image load image pil imageio scipy
  • 变量 - 海王星上的 Gremlin

    我位于 Gremlin 控制台并连接到 AWS Neptune 数据库 g V hasLabel Risk toList 提供了预期的结果 但是当我尝试将结果分配给变量时 risks g V hasLabel Risk toList 我收到
  • 在 Django/South 中,如何在数据迁移期间从不同的应用程序创建模型的实例

    我需要执行模型的数据迁移Answer in app Question 在该脚本中存在依赖关系 因此我需要创建模型的实例Chapter在应用程序中Journal 所以 我将其编码如下 def forwards self orm for ans
  • 将 ComboBoxColumn 绑定到 WPF DataGrid 中 DataGrid 的 ItemsSource 的集合

    请帮助我弄清楚如何在 WPF 的 DataGrid 中使用 ComboBoxColumn 我正在尝试创建一个设备列表 其中每个设备在 日志 字段中都有动态状态列表
  • AngularJS ui-router 登录验证

    我是 AngularJS 的新手 我对如何在以下场景中使用 Angular ui router 感到有点困惑 我正在构建一个由两部分组成的网络应用程序 第一部分是带有登录和注册视图的主页 第二部分是仪表板 成功登录后 我创建了一个index
  • 设计数据仓库、事实表和维度表的逻辑模型

    你好 我是数据仓库的新手 作业要求我实现逻辑设计 物理和实现 你会如何在数据仓库中对此进行建模 我希望设计一个数据仓库来给出与棒球联盟相关的统计数据的答案 对于玩家 进攻中 击球手击球次数 得分是多少 安打次数 双打和三打数 打了多少个本垒
  • 提取模式后的字符串

    我想提取 client id 和 id 之后的数字 并将每行中的 client id 和 id 配对 例如 对于以下日志行 User client id 03 results RelatedUser id 204 weight 10 Rel
  • 没有名为 fcntl 的模块

    我正在尝试使用 IronPython 2 7 在 NET 4 0 上使用 IronPython 执行此方法 我使用的是 Windows 7 import os import re import nltk import urllib impo
  • 如何在 JavaScript 中检查 JSON 字符串是否有值?

    有什么方法可以检查 json 字符串是否具有值 字符或字符串 这是示例 firstName John lastName Smith age 25 address streetAddress 21 2nd Street city New Yo
  • WPF 某些图像在加载时会旋转

    我是 WPF 新手 找不到解决方法 我有一个在 XAML 中定义的基本图像控件 我正在将位图图像动态加载到此控件 问题是 当加载图像控件时 某些位图在图像控件中翻转 并且我想以其默认方向加载所有图像 这是我的 XAML
  • Pyspark 与 Elasticsearch

    我将 Pyspark 与 Elasticsearch 结合使用 我注意到 当您创建 RDD 时 它不会在任何收集 计数或任何其他 最终 操作之前执行 当我将转换后的 RDD 的结果用于其他事情时 是否可以执行和缓存转换后的 RDD 正如我在
  • 正则表达式检测字符重复

    我使用表达式来检测字符串中重复的一个字符 if str replace g length gt 1 现在 我希望检测到多个重复的字符 例如 让我们尝试检测 或 的重复项 Wordwithone here match Word withdup
  • 如果未安装.NET 3.5,如何避免 FileNotFoundException?

    如果您尝试在未安装此版本 NET Framework 的 Windows 计算机上启动 NET 3 5 应用程序 您会收到FileNotFoundException对于某些系统程序集 例如 System Core 3 5 0 0 是否可以捕
  • 将 UIButton 旋转 360 度

    我一直在尝试运行一个旋转我的动画UIButton360 度使用此代码 UIView animateWithDuration 3 0 animations self vineTimeCapButton transform CGAffineTr
  • 将对象设置为 nil 时不会调用 dealloc 方法

    我有个问题 我首先创建了一个扩展 NSObject 的对象 我提供了描述和 dealloc 方法的重写 这是我的 Employee m 文件 implementation Employee NSString description retu
  • 错误:不兼容的类型:Fragment 无法转换为 MapFragment

    在我的项目中 我使用带有选项卡的导航抽屉 在其中一个选项卡中 我想调用谷歌地图 但我遇到了这个错误 Error incompatible types Fragment cannot be converted to MapFragment 包
  • .NET Core DI,为包注册默认实现

    如何使用 NET Core 的 IoC 容器注册默认实现 并提供一种覆盖现有实现的方法 例如 我可能想创建一个包 为某些服务提供默认实现 namesapce Package public interface ISomeService pub