NATS: 对依赖注入支持
NuGet:
使用方法:
serviceCollection.AddNats();
在容器中添加了 2 个单例服务:
- NATS.Client.Core.NatsConnection 实际类型
- NATS.Client.Core.INatsConnection ,接口类型
所以在注入的时候,既可以使用接口注入,也可以使用实际类型注入。
具体定义
- 当指定 poolSize 为 1 的时候,注册了单例的
NatsConnection和INatsConnection。 - 否则,将
NatsConnectionPool注册为单例,而NatsConnection和INatsConnection通过从池中获得而实现为瞬态。
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: 对依赖注入支持的更多相关文章
- 封装了一些sqlsugar的常用方法 用来动态切换数据库和依赖注入 支持泛型
接口: /// <summary> /// 数据库操作 /// </summary> public interface IDAL_Services { /// <summ ...
- ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器
原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...
- 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入
12.2 注解实现Bean依赖注入 12.2.1 概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的 ...
- Unity文档阅读 第三章 依赖注入与Unity
Introduction 简介In previous chapters, you saw some of the reasons to use dependency injection and lea ...
- 注解实现Bean依赖注入
12.2.1 概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数 ...
- ASP.NET Core 中的框架级依赖注入
https://tech.io/playgrounds/5040/framework-level-dependency-injection-with-asp-net-core 作者: Gunnar P ...
- ASP.NET Core MVC 之依赖注入 Controller
ASP.NET Core MVC 控制器应通过构造函数明确地请求它们地依赖关系,在某些情况下,单个控制器地操作可能需要一个服务,在控制器级别上的请求可能没有意义.在这种情况下,也可以将服务作为 Ac ...
- ThinkPHP6.0 容器和依赖注入
ThinkPHP6.0 容器和依赖注入 分为如下两部分: 依赖注入 容器 依赖注入 依赖注入其实本质上是指对类的依赖通过构造器完成自动注入: 在控制器架构方法和操作和方法中一旦对参数进行对象类型约束则 ...
- 018-019 NET5_内置容器支持依赖注入+IServiceCollection的生命周期
概念: DI依赖注入: IServiceCollection仅支持构造函数注入 什么是依赖注入? 如果对象A依赖对象B,对象B依赖对象C,就可以先构造对象C,然后传递给对象B,再把对象B传递给A.得到 ...
- 创建支持依赖注入、Serilog 日志和 AppSettings 的 .NET 5 控制台应用
翻译自 Mohamad Lawand 2021年3月24日的文章 <.NET 5 Console App with Dependency Injection, Serilog Logging, ...
随机推荐
- [namespace hdk] diff.h
Example cth.txt 12345 54321 114514 hdk.txt 12345 54321 114514 #include"diff.h" using names ...
- 《Programming from the Ground Up》读后感
之所以看这本书,是想了解一些跟汇编相关的知识,打开这本书后就被作者的观点--"If you don't understand something the first time, reread ...
- iOS Xcode真机调试包下载地址
下载地址 https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport 本地安装路径 /Applications/Xco ...
- KubeSphere 社区双周报|2024.06.07-06.20
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- Nuxt.js 应用中的 app:resolve 事件钩子详解
title: Nuxt.js 应用中的 app:resolve 事件钩子详解 date: 2024/10/17 updated: 2024/10/17 author: cmdragon excerpt ...
- hydra爆破工具
hydra爆破工具 命令详细: 1.破解ssh: hydra -l 用户名 -p 密码字典 -t 线程 -vV -e ns ip ssh hydra -l 用户名 -p 密码字典 -t 线程 -o s ...
- VuePress安装
linux 下预构建二进制文件安装 Nodejs Nodejs预购建二级制文件下载地址 安装 Nodejs 和 npm # 解压 tar xvf node-v20.15.1-linux-x64.tar ...
- DRF-Authention组件源码分析及扩展
drf 认证组件 1.认证组件源码执行流程 在该图中,我把与认证组件无关的代码都删除了,只留下了认证的代码,方便解析.每行注释的开头数字即代表了执行顺序 注意事项: 第5步中的self.authent ...
- hbase的管理相关看法
运维任务 regionserver添加/删除节点 master备份 1 添加新节点 复制hbase目录并进行配置文件修改(regionserver增加新节点)并保持配置文件在全集群一致,在新节点上启动 ...
- C240731B
B 游戏类问题 先假设一瓶毒药都不用, 先把治疗的贡献加进答案里面,这样治疗.毒药.攻击的贡献分别是独立的. 如果 \(i\) 位置本来是治疗, 那么用毒药多扣的血是 \(a[i]=(p+r) \ti ...