NuGet:

使用方法:

serviceCollection.AddNats();

在容器中添加了 2 个单例服务:

  1. NATS.Client.Core.NatsConnection 实际类型
  2. NATS.Client.Core.INatsConnection ,接口类型

所以在注入的时候,既可以使用接口注入,也可以使用实际类型注入。

具体定义

  • 当指定 poolSize 为 1 的时候,注册了单例的 NatsConnectionINatsConnection
  • 否则,将 NatsConnectionPool 注册为单例,而 NatsConnectionINatsConnection 通过从池中获得而实现为瞬态。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using NATS.Client.Core; namespace NATS.Client.Hosting; public static class NatsHostingExtensions
{
/// <summary>
/// Add NatsConnection/Pool to ServiceCollection. When poolSize = 1, registered `NatsConnection` and `INatsConnection` as singleton.
/// Others, registered `NatsConnectionPool` as singleton, `NatsConnection` and `INatsConnection` as transient(get from pool).
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1001:Commas should not be preceded by whitespace", Justification = "Required for conditional build.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009:Closing parenthesis should not be preceded by a space", Justification = "Required for conditional build.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on the same line as the last parameter", Justification = "Required for conditional build.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1113:Comma should be on the same line as previous parameter", Justification = "Required for conditional build.")]
public static IServiceCollection AddNats(
this IServiceCollection services,
int poolSize = 1,
Func<NatsOpts, NatsOpts>? configureOpts = null,
Action<NatsConnection>? configureConnection = null
#if NET8_0_OR_GREATER
, object? key = null // This parameter is only available in .NET 8 or greater
#endif
)
{
object? diKey = null;
#if NET8_0_OR_GREATER
diKey = key;
#endif poolSize = Math.Max(poolSize, 1); if (poolSize != 1)
{
NatsConnectionPool PoolFactory(IServiceProvider provider)
{
var options = NatsOpts.Default with
{
LoggerFactory = provider.GetRequiredService<ILoggerFactory>(),
};
if (configureOpts != null)
{
options = configureOpts(options);
} return new NatsConnectionPool(poolSize, options, configureConnection ?? (_ => { }));
} static NatsConnection ConnectionFactory(IServiceProvider provider, object? key)
{
#if NET8_0_OR_GREATER
if (key == null)
{
var pool = provider.GetRequiredService<NatsConnectionPool>();
return (pool.GetConnection() as NatsConnection)!;
}
else
{
var pool = provider.GetRequiredKeyedService<NatsConnectionPool>(key);
return (pool.GetConnection() as NatsConnection)!;
}
#else
var pool = provider.GetRequiredService<NatsConnectionPool>();
return (pool.GetConnection() as NatsConnection)!;
#endif
} if (diKey == null)
{
services.TryAddSingleton(PoolFactory);
services.TryAddSingleton<INatsConnectionPool>(static provider => provider.GetRequiredService<NatsConnectionPool>());
services.TryAddTransient<NatsConnection>(static provider => ConnectionFactory(provider, null));
services.TryAddTransient<INatsConnection>(static provider => provider.GetRequiredService<NatsConnection>());
}
else
{
#if NET8_0_OR_GREATER
services.TryAddKeyedSingleton(diKey, (provider, _) => PoolFactory(provider));
services.TryAddKeyedSingleton<INatsConnectionPool>(diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnectionPool>(key));
services.TryAddKeyedTransient<NatsConnection>(diKey, static (provider, key) => ConnectionFactory(provider, key));
services.TryAddKeyedTransient<INatsConnection>(diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnection>(key));
#endif
}
}
else
{
NatsConnection Factory(IServiceProvider provider)
{
var options = NatsOpts.Default with
{
LoggerFactory = provider.GetRequiredService<ILoggerFactory>(),
};
if (configureOpts != null)
{
options = configureOpts(options);
} var conn = new NatsConnection(options);
if (configureConnection != null)
{
configureConnection(conn);
} return conn;
} if (diKey == null)
{
services.TryAddSingleton(Factory);
services.TryAddSingleton<INatsConnection>(static provider => provider.GetRequiredService<NatsConnection>());
}
else
{
#if NET8_0_OR_GREATER
services.TryAddKeyedSingleton<NatsConnection>(diKey, (provider, _) => Factory(provider));
services.TryAddKeyedSingleton<INatsConnection>(diKey, static (provider, key) => provider.GetRequiredKeyedService<NatsConnection>(key));
#endif
}
} return services;
}
}

See: https://github.com/nats-io/nats.net.v2/tree/main/src/NATS.Client.Hosting

NATS: 对依赖注入支持的更多相关文章

  1. 封装了一些sqlsugar的常用方法 用来动态切换数据库和依赖注入 支持泛型

    接口: /// <summary> /// 数据库操作 /// </summary> public interface IDAL_Services { /// <summ ...

  2. ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器

    原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...

  3. 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入

    12.2  注解实现Bean依赖注入 12.2.1  概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的 ...

  4. Unity文档阅读 第三章 依赖注入与Unity

    Introduction 简介In previous chapters, you saw some of the reasons to use dependency injection and lea ...

  5. 注解实现Bean依赖注入

    12.2.1  概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数 ...

  6. ASP.NET Core 中的框架级依赖注入

    https://tech.io/playgrounds/5040/framework-level-dependency-injection-with-asp-net-core 作者: Gunnar P ...

  7. ASP.NET Core MVC 之依赖注入 Controller

    ASP.NET Core MVC 控制器应通过构造函数明确地请求它们地依赖关系,在某些情况下,单个控制器地操作可能需要一个服务,在控制器级别上的请求可能没有意义.在这种情况下,也可以将服务作为  Ac ...

  8. ThinkPHP6.0 容器和依赖注入

    ThinkPHP6.0 容器和依赖注入 分为如下两部分: 依赖注入 容器 依赖注入 依赖注入其实本质上是指对类的依赖通过构造器完成自动注入: 在控制器架构方法和操作和方法中一旦对参数进行对象类型约束则 ...

  9. 018-019 NET5_内置容器支持依赖注入+IServiceCollection的生命周期

    概念: DI依赖注入: IServiceCollection仅支持构造函数注入 什么是依赖注入? 如果对象A依赖对象B,对象B依赖对象C,就可以先构造对象C,然后传递给对象B,再把对象B传递给A.得到 ...

  10. 创建支持依赖注入、Serilog 日志和 AppSettings 的 .NET 5 控制台应用

    翻译自 Mohamad Lawand 2021年3月24日的文章 <.NET 5 Console App with Dependency Injection, Serilog Logging, ...

随机推荐

  1. 第5天:基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载

    文件上传下载-解决无图形化&解决数据传输 命令生成:https://forum.ywhack.com/bountytips.php?download 反弹shell 以参照物为准,以Linux ...

  2. P9118 [春季测试 2023] 幂次

    二诊前愉快的一次测试,关键是还有奶茶喝 第二题,本来直接暴力去重枚举可以的六十分的,但是.......花了30分钟优化剪纸,优化空间后,惨变35分. [春季测试 2023] 幂次 题目描述 小 Ω 在 ...

  3. manim边学边做--形状匹配

    manim中有几个特殊的用于形状匹配的对象,它们的作用是标记和注释已有的对象,本身一般不单独使用. 形状匹配对象一共有4种: BackgroundRectangle:为已有的对象提供一个矩形的背景 C ...

  4. CentOS7 安装配置笔记 v2

    1.通过镜像安装 CentOS72.安装 wget 下载工具3.修改镜像地址4.安装 nano 文本编辑工具5.安装 dotnet core6.安装vsftpd7.设置 firewalld8.为 do ...

  5. 使用c++ onnxruntime构建项目出现的bug

    bug1:The given version [11] is not supported, only version 1 to 7 is supported in this build. 应该是加载了 ...

  6. 关于set实现结构体自动去重原理的推论

    转自本人博客,原文链接 先说结论 在每个操作均为log复杂度的前提下,set无法在判断顺序和重复关键字不同时完成对结构体元素的去重. 首先我们先看这段结构体定义,目的是先按num相等进行去重,再按ke ...

  7. 墨天轮最受DBA欢迎的数据库技术文档-故障处理案例篇

    在之前发布的<墨天轮最受欢迎的技术文档-容灾备份篇>中,大家说想看故障处理案例篇的内容,这不!编辑部快马加鞭给大家整理来了,希望能够帮助到大家. 数据库故障可能出现在内存.网络.CPU.硬 ...

  8. 轨道控制器 threejs

    就是一个可以360转动的相机,通过不断的改变相机的参数 然后渲染达到效果. // 引入相机控件  -- 轨道控制器 // console.log('OrbitControls',OrbitContro ...

  9. 浅析Redis

    浅析Redis 什么是Redis Redis本质上是一个Key-Value类型的内存数据库,整个数据库加载在内存当中操作,定期通过异步操作把数据库中的数据flush到硬盘上进行保存. 因为是纯内存操作 ...

  10. 云原生周刊:Grafana Beyla 发布 | 2023.9.18

    开源项目推荐 Komiser Komiser 是一个与云无关的开源资源管理器.它与多个云提供商(包括 AWS.Azure.Civo.Digital Ocean.OCI.Linode.腾讯和 Scale ...