.NET 6 Worker Service使用NServiceBus SqlServerTransport报错问题
问题根因
这根本不是.NET 6的兼容Bug,核心是两个问题叠在一起导致的:
- 你参照的是SqlServer传输7.x版本的配置写法,但初始安装的
NServiceBus.Transport.SqlServer 6.3.3是对应NServiceBus 7.x的正式版,这个版本的SqlServerTransport没有单参数接收连接字符串的构造函数,UseTransport方法也不支持直接传入传输实例,跨大版本抄文档写法必然报编译错误。 - 不管是升级beta版,还是回退正式版用旧泛型写法,运行时提示“未指定连接字符串”的核心原因是读配置的逻辑写错了:你在
UseNServiceBus委托里直接调用configuration.GetValue,但这个作用域里根本没有完成赋值的configuration变量,实际传进传输配置的连接字符串是null,和连接字符串本身能不能正常连数据库没有关系。
可直接运行的正确配置(基于正式稳定版,无需使用beta包)
先把所有NServiceBus相关包回退到经过验证的兼容.NET 6的正式版本,不需要碰测试版包:
- NServiceBus 保持7.7.3版本即可
- NServiceBus.Transport.SqlServer 保持6.3.3版本即可
- 配套的
Microsoft.Data.SqlClient 4.1.0不需要改动
配置代码修正如下,核心是从Host构建上下文里读取配置,使用6.x版本对应的泛型传输配置API:
IHost host = Host.CreateDefaultBuilder(args) .UseWindowsService() .UseNServiceBus(context => { var endpointConfiguration = new EndpointConfiguration("CRM"); // 从传入的上下文对象中取IConfiguration实例,不要直接用未定义的configuration变量 string connectionString = context.Configuration.GetValue<string>("ConnectionStrings:CrmDatabase"); // 6.x版本SqlServer传输的正确配置写法,不要用高版本传实例的写法 var transportConfig = endpointConfiguration.UseTransport<SqlServerTransport>(); transportConfig.ConnectionString(connectionString); // 路由、 critical error 处理等其余配置按业务需求正常编写即可 return endpointConfiguration; }) .ConfigureServices(services => { services.AddHostedService<GALSync.InterAction.Processes.CrmListener.Worker>(); }) .UseSerilog() .Build(); await host.RunAsync();
避坑提醒
- 看NServiceBus官方文档时一定要切换到和你安装的包版本匹配的文档版本,大版本之间API断层非常明显,直接抄最新版文档的写法大概率踩编译错误。
- 所有在
UseNServiceBus委托里要用到的配置、服务实例,都要从传入的context参数中获取,不要直接引用外部未赋值的变量,很容易传空值触发莫名其妙的配置缺失报错。 - 生产环境不要用beta版本的NServiceBus相关包,7.x正式版对.NET 6的兼容已经非常成熟,没必要承担测试版的不稳定风险。
内容的提问来源于stack exchange,提问作者joeschwa
相关产品推荐
相关产品推荐

