我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ASP.NET Core如何注入多个服务实现类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ASP.NET Core如何注入多个服务实现类

前言:

依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来。服务类型的实例转由容器自动管理,无需我们在代码中显式处理。

因此,有了依赖注入后,你的编程思维就得变一变了。在过去,许多功能性的类型(比如一个加密解密的类),我们都喜欢将其定义为静态(static),而有了依赖注入,你就要避免使用静态类型,应该交由服务容器帮你管理,只要你用好了,你会发现依赖注入是很方便的。

依赖注入的初级玩法,也是比较标准的玩法,此种玩法有两种模式:

  1. 十代单传模式:一个接口对应一个类,比如先定义接口 IA、IB,随后,类A实现 IA,类B 实现 IB。一对一。也可以是抽象类(或基类)E,然后 F 继承 E 类。
  2. 断子绝孙模式:直接就写一个类,不考虑派生,直接就添加到服务容器中。

来,看个例子。

1、定义个接口


    public interface IPlayGame
    {
        void Play();
    }


然后,写一个类来实现它。


    public class NBPlayGame : IPlayGame
    {
        public void Play()
        {
            Console.WriteLine("全民打麻药。");
        }
    }

我们知道,所谓服务类,其实就是普通类,这些类一般用于完成某些功能,比如计算 MD5 值。接着呢,还记得 Startup 类有个 ConfigureServices 方法吧,对,就在这厮里面把我们刚刚那个服务进行注册(就是添加到 ServiceCollection 集合中)。


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IPlayGame, NBPlayGame>();
        }


添加的时候很简单,类型一对一,IPlayGame 接口与 NBPlayGame 类对应。添加时有三种方法你可以调用,实际上对应着,服务类在容器中的生命周期。

  • AddSingleton:单个实例,这是寿命最长的,与天同寿。整个应用程序中仅用一个实例。
  • AddTransient:这个是最短命的,可能是天天晚上加班熬夜,死得很快。此种情况下,服务类的实例是用的时候创建,用完后直接销毁。
  • AddScoped:这个比较难理解。它的生命周期在单个请求内,包括客户端与服务器之间随后产生的子请求,反正只要请求的会话结束了,就会清理。

2、注入服务

比如在中间件,在控制器,或者在其他服务类的构造函数上(中间件是在 Invoke / InvokeAsync 方法上)进行实例接收。

现在来用一下,写一个中间件。


    public class TestMiddleware
    {
        public TestMiddleware(RequestDelegate next) { }

        public Task InvokeAsync(HttpContext context, IPlayGame game)
        {
            game.Play();
            return Task.CompletedTask;
        }
    }

已注册的服务会注入到 InvokeAsync 方法的参数中。注意第一个参数是 HttpContext,这是必须参数,后面的是注入的参数。

最后,在 Startup 类的 Configure 方法中就可以 use 这个中间件了。


        public void Configure(IApplicationBuilder app)
        {
            app.UseMiddleware<TestMiddleware>();
        }
 

运行后,Play 方法调用,在控制台中输出以下结果

 3、功能类

 也称“断子绝孙”模式,不使用接口规范,直接写功能类。


    public class DoSomething
    {
        public string GetMessage() => "你好,刚才 Boss 找你。";
    }

注册服务时更简单。


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<DoSomething>();
        }

在 Configure 方法中进行注入。


        public void Configure(IApplicationBuilder app, DoSomething thing)
        {
            Console.WriteLine(thing.GetMessage());
        }


运行后,输出结果如下

 

 在容器中,使用 ServiceDescriptor 类来存储服务类型相关的信息。其中,ServiceType 表示的是服务的类型,如果服务是有接口与实现类的,那么这个属性指的是接口的类型,实现类的类型信息由 ImplementationType 属性存储。如果没有接口,直接只定义类型,那么这个类型的信息就存到 ServiceType 属性上,ImplementationType 属性不使用。

上面这些例子中,ServiceType 是 IPlayGame 接口相关信息,ImplementationType 是 NBPlayGame 类的信息。如果像上面 DoSomething 类的情况,则 ServiceType 为 DoSomething 相关的信息,ImplementationType 为空。

 4、高级类

接下来,咱们看高级玩法。

定义一个接口。


    public interface IDemoService
    {
        string Version { get; }
        void Run();
    }


然后,有两个类实现这个接口。


    public class DemoService1 : IDemoService
    {
        public string Version => "v1";

        public void Run()
        {
            Console.WriteLine("第一个服务实现类。");
        }
    }

    public class DemoService2 : IDemoService
    {
        public string Version => "v2";

        public void Run()
        {
            Console.WriteLine("第二个服务实现类。");
        }
    }

然后,我们注册服务。


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IDemoService, DemoService1>();
            services.AddTransient<IDemoService, DemoService2>();
        }


然后我们照例,接收注入,咱们依旧使用中间件的方法参数接收。


    public class DemoMiddleware
    {
        public DemoMiddleware(RequestDelegate next)
        {
            // 由于程序约定,此构造函数必须提供。
        }

        public async Task InvokeAsync(HttpContext context, IDemoService sv)
        {
            await context.Response.WriteAsync(sv.Version);
        }
    }

然后,在 Startup.Configure 方法中使用该中间件。


        public void Configure(IApplicationBuilder app, DoSomething thing)
        {
            app.UseMiddleware<DemoMiddleware>();
        }


运行之后,你发现问题了,看看输出。

 

 出事了,参数仅能接收到最后注册的实现类型实例,也就是 DemoService2 类。所以就看到网上有不少朋友发贴问了,.NET Core 是不是不支持多个服务实现类的注入?这难倒了很多人。

实话告诉你,Core Core 兄是支持注入多个实现类的实例的。

下面,老周介绍两种解决方法(其实有三种,还有一种不太好弄,尤其是你对 Core 兄不熟的时候,所以我说两种,基本够用)。

方法一、接收 IServiceProvider 类型的注入。


        public async Task InvokeAsync(HttpContext context, IServiceProvider provider)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var sv in provider.GetServices<IDemoService>())
            {
                sb.Append($"{sv.Version}<br/>");
            }
            await context.Response.WriteAsync(sb.ToString());
        }

只要能接收到 IServiceProvider 所引用的实例,就能通过 GetServices 方法获取多个服务实例。

方法二,这种方法老周很推荐,更简单,直接注入 IEnumerable<T> 类型,本例中就是 IEnumerable<IDemoService>。


        public async Task InvokeAsync(HttpContext context, IEnumerable<IDemoService> svs)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var sv in svs)
            {
                sb.Append($"{sv.Version}<br/>");
            }
            await context.Response.WriteAsync(sb.ToString());
        }

IEnumerable<T> 的妙处就是可以 foreach ,这样你也能访问多个实例,而且必要时还可以联合 LINQ 一起耍。

运行结果如下。

 

到此这篇关于ASP.NET Core如何注入多个服务实现类的文章就介绍到这了,更多相关ASP.NET Core何注多个服务实现类内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ASP.NET Core如何注入多个服务实现类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

asp.net Core中如何实现同名服务注册

这篇文章主要为大家展示了“asp.net Core中如何实现同名服务注册”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“asp.net Core中如何实现同名服务注册”这篇文章吧。通常情况下,在使
2023-06-29

Asp.Net Core怎么使用Ocelot实现服务注册和发现

本文小编为大家详细介绍“Asp.Net Core怎么使用Ocelot实现服务注册和发现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Asp.Net Core怎么使用Ocelot实现服务注册和发现”文章能帮助大家解决疑惑,下面跟着小编的思路
2023-06-29

ASP.NET MVC如何实现依赖注入

这篇文章主要介绍了ASP.NET MVC如何实现依赖注入,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言在java的spring中有自动注入功能,使得代码变得更加简洁灵活,
2023-06-28

ASP.NET Core通用主机如何实现托管服务

本文小编为大家详细介绍“ASP.NET Core通用主机如何实现托管服务”,内容详细,步骤清晰,细节处理妥当,希望这篇“ASP.NET Core通用主机如何实现托管服务”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧
2023-07-02

ASP.NET Core中如何采用Autofac来替换IOC容器并实现属性注入

今天就跟大家聊聊有关ASP.NET Core中如何采用Autofac来替换IOC容器并实现属性注入,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。今天我们主要讲讲如何采用Autofac
2023-06-19

ASP.NET Core MVC如何实现运行时动态定义Controller类型

昨天有个朋友在微信上问我一个问题:他希望通过动态脚本的形式实现对ASP.NET Core MVC应用的扩展,比如在程序运行过程中上传一段C#脚本将其中定义的Controller类型注册到应用中,问我是否有好解决方案。我当时在外边,回复不太方
2022-06-07

ASP.NET MVC 3如何让依赖注入实现得更简单

本篇文章为大家展示了ASP.NET MVC 3如何让依赖注入实现得更简单,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。我没有找到一个完整的示例,只有一些代码片断,于是,我将其整理了一翻,也有一点点个
2023-06-17

在dotnet core如何实现类似crontab的定时任务

这篇文章将为大家详细讲解有关在dotnet core如何实现类似crontab的定时任务,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 首先通过Nuget安装PM> Install-Package
2023-06-09

ASP.NET如何使用SignalR2实现服务器广播

本篇内容介绍了“ASP.NET如何使用SignalR2实现服务器广播”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、概述这篇教程通过实现一
2023-06-30

如何注册多个阿里云服务器账号

#本文将详细指导读者如何注册多个阿里云服务器账号,包括注册步骤、注意事项以及推荐的注册方法。希望通过本文的指导,帮助读者快速、安全地注册并管理多个阿里云服务器账号。一、注册步骤:访问阿里云官网:首先,打开浏览器,输入"阿里云官网",然后点击搜索结果中的链接进入阿里云官方网站。注册账号:在首页右上角,点击"立即注册
如何注册多个阿里云服务器账号
2024-01-24

阿里云服务器购买多个IP:如何实现?

简介在互联网时代,拥有多个IP地址对于企业和个人来说都非常重要。阿里云服务器提供了购买多个IP的功能,使用户能够灵活地管理和使用自己的IP资源。本文将介绍如何在阿里云服务器上购买多个IP,并提供一些实际应用的例子。如何购买多个IP在阿里云服务器上购买多个IP非常简单。首先,登录阿里云控制台,选择需要购买IP的服务器实例
阿里云服务器购买多个IP:如何实现?
2024-01-29

使用Spring MVC如何实现将对象注入枚举类型中

今天就跟大家聊聊有关使用Spring MVC如何实现将对象注入枚举类型中,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先:这是一个枚举类:/** * 新闻类别 * @autho
2023-05-31

Spring Cloud中如何实现服务注册consul

这篇文章给大家分享的是有关Spring Cloud中如何实现服务注册consul的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、consul 简介consul 具有以下性质:服务发现:consul通过http
2023-06-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录