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. 五行强度得分_喜用神api免费接口_json数据八字五行强弱接口

    本API接口基于深厚的八字学原理,为用户提供详尽的五行(金.木.水.火.土)强弱分析.五行打分评估,以及精准的喜用神判断.用户只需输入自己的八字信息,即可获得全面而深入的命理解读. ‌一.核心功能‌ ...

  2. C# 如何理解装箱和拆箱 ?

    装箱和拆箱就是C# 中数据类型的转换 : 装箱:值类型转换对象类型(引用类型,复杂类型) 拆箱:对象类型转换值类型 object obj=null; //引用类型 obj=1; //装箱 boxing ...

  3. Android复习(三)清单文件中的元素——>application

    <application> 语法: <application android:allowTaskReparenting=["true" | "false ...

  4. JavaScript原型链污染探讨

    如果你想弄明白什么怎样才可以实现JavaScript的原型链污染,那么你首先需要弄清楚两个东西,那就是__proto__和prototype. 到底什么才是__proto__和prototype? 那 ...

  5. 在华为云上安装高可用 KubeSphere

    随着多云多集群的场景越来越丰富,在各个云厂商环境部署 KubeSphere 的需求随之升高.由于各云厂商的云资源使用规则和菜单导航栏各不相同,会使用户花大量时间去排错.为降低部署过程错误率,本教程使用 ...

  6. OpenFunction 0.6.0 发布: FaaS 可观测性、HTTP 同步函数能力增强及更多特性

    OpenFunction 是一个开源的云原生 FaaS(Function as a Service,函数即服务)平台,旨在帮助开发者专注于业务逻辑的研发.在过去的几个月里,OpenFunction 社 ...

  7. 国内空白,AI将文字搜索转化为交互数据图表,融资4000万,已与Perplexity整合

    2024年10月17日.产品为利用生成式AI将文字搜索转化为数据图表的美国初创公司Tako,种子轮融资575万美元,折合人民币4000万元. 国外AI搜索主导者Perplexity,其创始人也参与了这 ...

  8. Go语言学习 _基础02 _条件表达式、分支、循环

    Go语言学习 _基础02 _条件表达式.分支.循环 条件表达式和switch package condition import "testing" func TestCondict ...

  9. 如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)

    我们在嵌入式Linux开发过程中经常会遇到一个问题,就是程序崩溃后不知道具体位置.因为我们发布到生产环境的一般是没有调试符号的(使用strip或编译时加-s参数,CMake生成的编译指令中的-O3也会 ...

  10. "安装VMware Tools"显示灰色的解决办法

    用VMware Workstation Pro好几年了,期间这个问题也遇到过好几次,这次把解决方案记录一下,若后续有其他情况其他解决方案将在此博文更新. Step1:关闭虚拟机: Step2:在虚拟机 ...