Dependency Injection 8.0新功能——KeyedService

这篇具有很好参考价值的文章主要介绍了Dependency Injection 8.0新功能——KeyedService。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文只介绍 .NET Dependency Injection 8.0新功能——KeyedService,假定读者已熟练使用之前版本的功能。

注册带Key的类

8.0之前,注册一个类往往是AddSingleton<IFoo, Foo>(),8.0添加了一个新功能:“可以注册一个带Key的类AddKeyedSingleton<IFoo, Foo>("keyA")。获取服务方法由GetService<IFoo>()变成了GetKeyedService<IFoo>("keyA"),并且调用这两个方法创建出来的对象是不同的。
Dependency Injection 8.0新功能——KeyedService

如果想通过构造函数注入,只需要在参数前面加上特性[FromKeyedServices("keyA")] 即可,特性里的参数就是key的名字。如果想在构造函数中获取key的值则使用特性[ServiceKey]。我们还可以注册时把key设置为KeyedService.AnyKey(这是框架提供的类),只需使用任意非null值作为key就可以获取对象。暂时不支持使用通配符匹配,也许以后会加......
Dependency Injection 8.0新功能——KeyedService

class Bar : IBar
{
    public Bar([ServiceKey] int key, [FromKeyedServices("keyA")] IFoo foo, IServiceProvider root)
    {
        //注意:key的类型要和调用时一致。
        Console.WriteLine($"key:{key},Compare:{foo == root.GetKeyedService<IFoo>("keyA")}");
    }
}
public static class KeyedService
{
    /// Represents a key that matches any key.
    public static object AnyKey { get; } = new AnyKeyObj();
    private sealed class AnyKeyObj
    {
        public override string? ToString() => "*";
    }
}

深入理解

8.0之前,获取一个对象需要用到的一个“标识”,比如调用GetService<IFoo>(),这个“标识”就是IFoo;也就是ServiceDescriptor里面的ServiceType。而在8.0后“标识”变成了IFoo+"keyA",也就是ServiceDescriptor里面的ServiceType+新增的ServiceKey

public class ServiceDescriptor
{
    public object? ServiceKey { get; } 
    public Type? ImplementationType => _implementationType;        
    public Type ServiceType { get; }
    public ServiceLifetime Lifetime { get; }

对于以前注册的类,ServiceKey默认是null,所以“标识”就是ServiceKey+null。调用GetService<IFoo>()就等于调用GetKeyedService<IFoo>(null)
Dependency Injection 8.0新功能——KeyedService

再举一个例子:
Dependency Injection 8.0新功能——KeyedService

//类型的注册信息放在_descriptorLookup,8.0前,是通过ServiceType作为字典的键,
//8.0是把ServiceIdentifier(也就是ServiceKey+ServiceType)作为字典的键
//7.0
private readonly Dictionary<Type, ServiceDescriptorCacheItem> _descriptorLookup = new();
//8.0
private readonly Dictionary<ServiceIdentifier, ServiceDescriptorCacheItem> _descriptorLookup = new();
internal readonly struct ServiceIdentifier : IEquatable<ServiceIdentifier>
{
    public object? ServiceKey { get; }
    public Type ServiceType { get; }
}

Dependency Injection 8.0新功能——KeyedService

循环引用

前面讲到可以通过[ServiceKey]获取调用时的Key;而没有注册key的服务是无法在构造函数中注入key的值。通过这个功能可以解决循环引用的问题,先看代码。

class Foo : IFoo
{
    //这个构造函数给GetService<IFoo>()使用
    public Foo()
    {
        this.Num = 10;
    }
    //这个构造函数给GetKeyedServices<IFoo>("keyA")使用
    public Foo([ServiceKey] string key, IFoo foo)
    {
        Console.WriteLine($"key:{key},this.Num:{this.Num},foo.Num:{foo.Num}");
    }
    public int Num { get; set; }
}

Dependency Injection 8.0新功能——KeyedService

代码执行流程:

  • 1.DI首先获取Foo的所有构造函数并且按构造函数的参数从多到少进行排序
  • 2.遍历所有构造函数,首先获取参数最多的构造函数 Foo([ServiceKey] string key, IFoo foo),开始判断构造函数的参数能否被DI创建
  • 3.DI首先判断string key这个参数,能够创建;然后继续判断第二个参数IFoo foo能否被创建
  • 4.重复第一步
  • 5.重复第二步
  • 6.DI首先判断string key这个参数,不能够创建;所以无法调用构造函数 Foo([ServiceKey] string key, IFoo foo)创建Foo实例
  • 7.继续遍历构造函数,第二个构造函数是无参的,DI能够创建foo对象。
  • 8.对于GetKeyedServices<IFoo>("keyA"),是使用的这个构造函数Foo([ServiceKey] string key, IFoo foo)创建的对象。IFoo foo是使用无参构造函数创建的。

注意点:

  • 参数[ServiceKey] string key一定要写在参数IFoo foo前面,否则就会循环引用
  • 注册服务时,要注册两种(带key的和不带key的都要注册)AddScoped<IFoo, Foo>() .AddKeyedScoped<IFoo, Foo>("keyA")

总结

以前的用法往往是接口对应实现类,通过DI获取对象,只需要知道接口的名字,就可以通过GetService方法或者构造函数注入获取对象。
现在是接口+key对应实现类,通过DI获取对象,需要知道接口+key。如果key为null就和以前的用法一模一样。
结束。第一次写文章如有错误,欢迎各位批评指点,谢谢!文章来源地址https://www.toymoban.com/news/detail-712151.html

到了这里,关于Dependency Injection 8.0新功能——KeyedService的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TypeScript 5.1发布,新功能更新

    1:返回类型增加undefined 这里设置了一个别名 fun,当时使用它的时候,我们必须显示返回一个 undefined 。 现在你可以直接设置返回类型: 而不仅限于 void any 。 4.3版本 :❌ 5.1版本 :✅ 2:getter可以设置和 setter 的不相关类型 在之前版本 ,get 返回类型应该为 set 的子类型,如

    2024年02月09日
    浏览(50)
  • SOLIDWORKS 2023新功能揭秘(一):3D CAD功能的十大更新

    SolidWorks 3D CAD  软件拥有设计、模拟、成本估算、可制造性检查、CAM、可持续设计和数据管理等功能,同时还包含适用于钣金,焊件,曲面,模具,产品配置,DFM和CAM的专业工具,支持ECAD/MCAD协作,复杂的零部件库以及高级真实感渲染。更重要的是具有结构和运动分析功能,

    2024年02月05日
    浏览(48)
  • 三星泄露微软 Copilot 新功能:用自然语言操控各种功能

    3 月 11 日消息,微软计划本月晚些时候发布新款 Surface 电脑和适用于 Windows 11 的 Copilot 新功能,但三星似乎等不及了,在其即将推出的 Galaxy Book4 系列产品宣传材料中泄露了一些即将到来的 Copilot 功能。 三星官网上发布的图片证实了此前关于微软正为其人工智能助手 Copilo

    2024年04月09日
    浏览(87)
  • Microsoft Releases .NET 7新功能

    Microsoft Visual Studio是一种统一的开发体验,使开发人员能够跨web、云和设备创建多层应用程序。11月8日,微软发布了该强大开发环境的下一版本:Visual Studio 2022 17.4版。 除了修复许多顶级报告的bug之外,17.4版还包括了许多基于开发者社区建议的新功能,包括: Visual Studio的本

    2024年02月06日
    浏览(47)
  • 【C++】C++11类的新功能

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》 《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 默认成员函数 类成员变量初始化 强制生成默认函数的default 禁止生

    2024年04月17日
    浏览(56)
  • C# 12 预览版的新功能

    作者:Kathleen Dollard 排版:Alan Wang Visual Studio 17.7 Preview 3 和 .NET 8 Preview 6 的发布推进了 C# 12的发展。此预览版包含的功能为将来的性能增强奠定了基础。现在,您能够在库中更方便的使用内联函数。此预览版首次推出了一项实验性功能:拦截器。该功能允许生成器重新路由代

    2024年02月14日
    浏览(44)
  • 揭密.NET 8到底有什么新功能

    .NET 8 是微软于2021年8月24日宣布的下一代编程语言和框架,它是 .NET 宇宙的一部分,与 C# (Common Language Infrastructure) 紧密集成。.NET 8 引入了许多新功能,如原生编译、值类型 (Value Types)、结构化并发 (structured concurrency) 和快速数组 (RapidArray)。.NET 8 还支持本机 (native) AOT (Ahead-Of

    2024年02月03日
    浏览(45)
  • Syncfusion Essential Studio Enterprise新功能

    添加了新的MediaQuery、Menute和Rating组件。 应用程序栏、浮动操作按钮、消息和快速拨号组件现在可以在生产中使用。 添加了对甘特图中按需加载的支持。 ASP.NET核心 添加了新的分级控件。 应用程序栏、浮动操作按钮、提及、消息和快速拨号控件现在可以在生产中使用。 现在

    2024年01月21日
    浏览(47)
  • 探索PostgreSQL的新功能:最新版本更新解析

    PostgreSQL作为一种强大而开源的关系型数据库管理系统,不断在不断进化和改进。每一次的版本更新都带来了更多功能和改进,让用户在处理大规模数据和复杂查询时体验更好的性能和功能。在本文中,我们将深入探索PostgreSQL的最新版本更新,了解新增的功能和改进,以及这

    2024年02月14日
    浏览(46)
  • Windows 12:发布日期、新功能、价格、硬件要求

    距离Windows 11首次发布仅一年时间,但关于 Windows 12 的传言已经开始四处流传。有报道称,微软正计划切换到Windows 的新更新周期,未来几个月将不会发布 Windows 11 23H2 或 24H2 版本。事实上,据报道Windows 11 23H2“太阳谷3”更新已经停止,Windows 12(代号:Next Valley)的工作已经开

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包