请选择 进入手机版 | 继续访问电脑版

[ASP.NET] ASP.NET Core怎样 注入多个服务实现类

  [复制链接]
查看513 | 回复111 | 2021-9-15 08:24:57 | 显示全部楼层 |阅读模式
目次

前言 :

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

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

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

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

来,看个例子。

1、定义个接口

  1. public interface IPlayGame
  2. {
  3. void Play();
  4. }
复制代码

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

  1. public class NBPlayGame : IPlayGame
  2. {
  3. public void Play()
  4. {
  5. Console.WriteLine("全民打麻药。");
  6. }
  7. }
复制代码

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

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddTransient<IPlayGame, NBPlayGame>();
  4. }
复制代码

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

    1. AddSingleton:
    复制代码
    单个实例,这是寿命最长的,与天同寿。整个应用程序中仅用一个实例。
    1. AddTransient
    复制代码
    :这个是最短命的,大概 是每天 晚上加班熬夜,死得很快。此种环境 下,服务类的实例是用的时间 创建,用完后直接烧毁 。
    1. AddScoped
    复制代码
    :这个比较难懂 白 。它的生命周期在单个哀求 内,包括客户端与服务器之间随后产生的子哀求 ,反正只要哀求 的会话竣事 了,就会清算 。

2、注入服务

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

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

  1. public class TestMiddleware
  2. {
  3. public TestMiddleware(RequestDelegate next) { }
  4. public Task InvokeAsync(HttpContext context, IPlayGame game)
  5. {
  6. game.Play();
  7. return Task.CompletedTask;
  8. }
  9. }
复制代码

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

末了 ,在 Startup 类的 Configure 方法中就可以 use 这个中心 件了。

  1. public void Configure(IApplicationBuilder app)
  2. {
  3. app.UseMiddleware<TestMiddleware>();
  4. }
复制代码

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

ASP.NET Core怎样
注入多个服务实现类

 3、功能类

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

  1. public class DoSomething
  2. {
  3. public string GetMessage() => "你好,刚才 Boss 找你。";
  4. }
复制代码

注册服务时更简单。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddScoped<DoSomething>();
  4. }
复制代码

在 Configure 方法中举行 注入。

  1. public void Configure(IApplicationBuilder app, DoSomething thing)
  2. {
  3. Console.WriteLine(thing.GetMessage());
  4. }
复制代码

运行后,输出结果 如下

 

ASP.NET Core怎样
注入多个服务实现类

 在容器中,利用 ServiceDescriptor 类来存储服务范例 干系 的信息。此中 ,ServiceType 表示的是服务的范例 ,假如 服务是有接口与实现类的,那么这个属性指的是接口的范例 ,实现类的范例 信息由 ImplementationType 属性存储。假如 没有接口,直接只定义范例 ,那么这个范例 的信息就存到 ServiceType 属性上,ImplementationType 属性不利用 。

上面这些例子中,ServiceType 是 IPlayGame 接口干系 信息,ImplementationType 是 NBPlayGame 类的信息。假如 像上面 DoSomething 类的环境 ,则 ServiceType 为 DoSomething 干系 的信息,ImplementationType 为空。

 4、高级类

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

定义一个接口。

  1. public interface IDemoService
  2. {
  3. string Version { get; }
  4. void Run();
  5. }
复制代码

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

  1. public class DemoService1 : IDemoService
  2. {
  3. public string Version => "v1";
  4. public void Run()
  5. {
  6. Console.WriteLine("第一个服务实现类。");
  7. }
  8. }
  9. public class DemoService2 : IDemoService
  10. {
  11. public string Version => "v2";
  12. public void Run()
  13. {
  14. Console.WriteLine("第二个服务实现类。");
  15. }
  16. }
复制代码

然后,我们注册服务。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddTransient<IDemoService, DemoService1>();
  4. services.AddTransient<IDemoService, DemoService2>();
  5. }
复制代码

然后我们照例,汲取 注入,咱们仍然 利用 中心 件的方法参数汲取 。

  1. public class DemoMiddleware
  2. {
  3. public DemoMiddleware(RequestDelegate next)
  4. {
  5. // 由于程序约定,此构造函数必须提供。
  6. }
  7. public async Task InvokeAsync(HttpContext context, IDemoService sv)
  8. {
  9. await context.Response.WriteAsync(sv.Version);
  10. }
  11. }
复制代码

然后,在 Startup.Configure 方法中利用 该中心 件。

  1. public void Configure(IApplicationBuilder app, DoSomething thing)
  2. {
  3. app.UseMiddleware<DemoMiddleware>();
  4. }
复制代码

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

 

ASP.NET Core怎样
注入多个服务实现类

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

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

下面,老周先容 两种办理 方法(实在 有三种,还有一种不太好弄,尤其是你对 Core 兄不熟的时间 ,以是 我说两种,基本够用)。

方法一、汲取 IServiceProvider 范例 的注入。

  1. public async Task InvokeAsync(HttpContext context, IServiceProvider provider)
  2. {
  3. StringBuilder sb = new StringBuilder();
  4. foreach (var sv in provider.GetServices<IDemoService>())
  5. {
  6. sb.Append($"{sv.Version}<br/>");
  7. }
  8. await context.Response.WriteAsync(sb.ToString());
  9. }
复制代码

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

方法二,这种方法老周很保举 ,更简单,直接注入 IEnumerable 范例 ,本例中就是 IEnumerable

  1. public async Task InvokeAsync(HttpContext context, IEnumerable<IDemoService> svs)
  2. {
  3. StringBuilder sb = new StringBuilder();
  4. foreach (var sv in svs)
  5. {
  6. sb.Append($"{sv.Version}<br/>");
  7. }
  8. await context.Response.WriteAsync(sb.ToString());
  9. }
复制代码

IEnumerable 的妙处就是可以 foreach ,如许 你也能访问多个实例,而且必要时还可以团结 LINQ 一起耍。

运行结果 如下。

 

ASP.NET Core怎样
注入多个服务实现类

到此这篇关于ASP.NET Core怎样 注入多个服务实现类的文章就先容 到这了,更多干系 ASP.NET Core何注多个服务实现类内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 123457441 | 2021-9-15 11:13:26 | 显示全部楼层
admin楼主很有艺术范!
回复

使用道具 举报

avatar 立郎 | 2021-9-16 05:46:13 | 显示全部楼层
关注一下!
回复

使用道具 举报

avatar 划翔的青鸟纲 | 2021-9-16 15:15:17 | 显示全部楼层
这个帖子会火的,鉴定完毕!
回复

使用道具 举报

avatar 荷叶224 | 2021-9-19 02:59:29 | 显示全部楼层
世界末日我都挺过去了,看到admin楼主我才知道为什么上帝留我到现在!
回复

使用道具 举报

avatar 123457025 | 2021-9-19 03:29:56 | 显示全部楼层
很有品味!
回复

使用道具 举报

avatar 123456879 | 2021-9-20 16:18:00 | 显示全部楼层
admin楼主的病历本丢我这里了!
回复

使用道具 举报

avatar 疑骨德秋忘 | 2021-9-21 06:57:08 | 显示全部楼层
admin楼主的病已经好了百分之六十二了!
回复

使用道具 举报

avatar 大头226 | 2021-9-21 22:21:25 | 显示全部楼层
这一年啥事没干,光研究admin楼主的帖子了!
回复

使用道具 举报

avatar 紫色214 | 2021-9-22 14:20:31 | 显示全部楼层
收藏了,改天让朋友看看!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则