使用NServiceBus切换回Learning Transport时出现RabbitMQ相关KeyNotFoundException
从你的描述来看,这个问题确实有点费解——明明代码里完全没调用RabbitMQ的配置,却触发了RabbitMQ相关的字典查找错误。结合你使用的NServiceBus v6.4.3和RabbitMQ v4.4.1版本,我整理了几个最可能的解决思路:
1. 检查配置文件中的残留RabbitMQ设置
NServiceBus会优先读取配置文件(app.config/web.config)中的配置,哪怕你在代码里指定了Learning Transport。请检查你的配置文件中是否存在以下残留内容:
- 有没有
<NServiceBus>节点下的Transport配置,比如:<NServiceBus> <Transport Type="NServiceBus.RabbitMQ.RabbitMQTransport, NServiceBus.RabbitMQ" /> </NServiceBus> - 有没有RabbitMQ相关的自定义配置节,比如
<RabbitMQTransportSettings>之类的节点
如果找到这些内容,直接删除或注释掉,再重新运行程序。
2. 彻底清理输出目录与依赖项
即使代码里没引用RabbitMQ,只要bin/obj目录里还残留着NServiceBus.RabbitMQ.dll等相关程序集,NServiceBus的扩展加载机制就可能会自动加载这些程序集,进而触发内部的配置逻辑。请按以下步骤操作:
- 右键项目 → 选择「清理」
- 手动删除项目根目录下的
bin和obj文件夹 - 重新生成解决方案,确保输出目录里只有Learning Transport相关的程序集(如果当前不需要RabbitMQ支持的话)
如果需要同时兼容两种Transport,建议通过条件编译或依赖项隔离(比如不同环境用不同的NuGet引用)来避免程序集冲突。
3. 排查代码中的隐性RabbitMQ引用
检查项目中是否有其他地方隐性引用了RabbitMQ的类型或扩展方法:
- 有没有
using NServiceBus.RabbitMQ;的语句没清理? - 有没有全局配置类、Startup代码中调用过RabbitMQ的扩展方法(比如
UseConventionalRoutingTopology())? - 你的两个
ConfigureEndPoint方法是否在同一个类中?如果是,可能存在编译时的冲突,建议拆分到不同的类或用条件编译指令区分(比如#if RABBITMQ)
这些隐性引用会导致RabbitMQ程序集被提前加载,即使当前用的是Learning Transport,也可能触发内部字典的配置逻辑,引发KeyNotFoundException。
4. 验证版本兼容性(兜底检查)
虽然你之前用RabbitMQ是正常的,但还是可以确认一下版本匹配:NServiceBus v6.4.3对应的RabbitMQ传输版本确实是v4.x系列,这个组合是兼容的,所以这个可能性较低,但如果前面的方法都无效,可以尝试更新到对应版本的最新小版本(比如NServiceBus v6.4.14、RabbitMQ v4.4.6)再测试。
内容的提问来源于stack exchange,提问作者Ace Grace

