为什么在使用 TypesToScan() 后 NServiceBus 配置被破坏
Why is NServiceBus configuration broken after using TypesToScan()
我有一个控制台应用程序,您可以在其中指定参数,根据指定的参数将加载各种处理程序。例如:
prgm.exe nyse
prgm.exe nasdaq
目标是在我的代码中我有 INyseHandlers
和 INasdaqHandlers
并且在第一种情况下只加载任何扩展前者的处理程序,对于后者的情况类似。目标是有一个程序可以根据它的方式收听各种或所有来源 运行。为实现这一点,我已经按照上面提到的方式设置了我的接口。然后在我的配置中设置:
var configuration = new BusConfiguration();
configuration.InitializeStepBusConventions(); // extension method, not the problem
// Load all the handlers specified in command line arguments
if (!Args.Contains("any") && Args.Length != 0)
{
List<Type> handlersToLoad = new List<Type>();
foreach (var argument in Args)
{
Console.WriteLine("Adding {0} subscribers to loaded handlers. . .", argument.ToUpper());
switch (argument)
{
case "nyse":
AddToHandlerList(handlersToLoad, typeof(INyseProcessor));
break;
case "nasdaq":
AddToHandlerList(handlersToLoad, typeof(INasdaqProcessor));
break;
}
}
configuration.TypesToScan(handlersToLoad);
}
configuration.UseContainer<NinjectBuilder>(c => c.ExistingKernel(Kernel));
configuration.EndpointName(ConfigurationManager.AppSettings[Defaults.Project.DefaultEndPointName]);
NServiceBus.Logging.LogManager.Use<NLogFactory>();
Bus.Create(configuration).Start();
其中:
private void AddToHandlerList(List<Type> handlersToLoad, Type interfaceType)
{
List<Type> classesWhichExtendInterface = Assembly.GetExecutingAssembly().GetTypes().Where(t => interfaceType.IsAssignableFrom(t)).ToList();
classesWhichExtendInterface.Remove(interfaceType);
handlersToLoad.AddRange(classesWhichExtendInterface);
}
类型按预期加载,List
没问题。但是当我 运行 这个并到达 Bus.Start
行时,我收到以下错误:
The given key (NServiceBus.LocalAddress) was not present in the dictionary.
没有类型加载,默认行为工作正常,程序集内的所有处理器都被加载。为什么我在 运行 宁 TypesToScan()
行之后收到此错误?
编辑:这是扩展方法:
config.UseSerialization<JsonSerializer>();
config.UseTransport<RabbitMQTransport>();
config.UsePersistence<InMemoryPersistence>();
config.EnableInstallers();
return config;
你的异常发生在这里
localAddress = Address.Parse(Settings.Get<string>("NServiceBus.LocalAddress"));
设置获取传输设置的 "NServiceBus.LocalAddress" kvp。由于您没有使用 "Core" 传输 (MSMQ),我可能怀疑您的传输程序集类型需要包含在 TypesToScan 中,因为:
ForAllTypes<Feature>(TypesToScan, t => featureActivator.Add(t.Construct<Feature>()));
我在使用 SQL 服务器传输时遇到了类似的问题,当我将程序集列表发送到 With(assemblies) 并且没有在其中包含 NServiceBus 程序集时,传输无法初始化。一旦我添加了 NServiceBus.* 程序集,一切就开始工作了。
我想为任何可能发现与我遇到的情况类似的人添加一个答案,我在使用 NServiceBus.Testing
测试传奇时遇到了这个确切的错误。
当您 运行 Test.Initialize
设置您的单元测试时,您实际上可以通过一些 BusConfiguration
设置,其中您可以指定要扫描的程序集。我通常使用以下作为标准设置,如果您正在调试测试(至少使用 NUnit),它可以防止某些程序集加载问题:
Test.Initialize(conf => conf.AssembliesToScan(assembly.GetExecutingAssembly()))
但是,由于我不知道的原因,今天我正在设置 saga 测试并收到此问题中提到的 NServiceBus.LocalAddress
错误。我设法通过向 AssembliesToScan
添加一个附加参数来解决该问题,如下所示:
Test.Initialize(conf => conf.AssembliesToScan(
Assembly.GetExecutingAssembly(),
Assembly.GetCallingAssembly()));
希望这对某人有所帮助。
我有一个控制台应用程序,您可以在其中指定参数,根据指定的参数将加载各种处理程序。例如:
prgm.exe nyse
prgm.exe nasdaq
目标是在我的代码中我有 INyseHandlers
和 INasdaqHandlers
并且在第一种情况下只加载任何扩展前者的处理程序,对于后者的情况类似。目标是有一个程序可以根据它的方式收听各种或所有来源 运行。为实现这一点,我已经按照上面提到的方式设置了我的接口。然后在我的配置中设置:
var configuration = new BusConfiguration();
configuration.InitializeStepBusConventions(); // extension method, not the problem
// Load all the handlers specified in command line arguments
if (!Args.Contains("any") && Args.Length != 0)
{
List<Type> handlersToLoad = new List<Type>();
foreach (var argument in Args)
{
Console.WriteLine("Adding {0} subscribers to loaded handlers. . .", argument.ToUpper());
switch (argument)
{
case "nyse":
AddToHandlerList(handlersToLoad, typeof(INyseProcessor));
break;
case "nasdaq":
AddToHandlerList(handlersToLoad, typeof(INasdaqProcessor));
break;
}
}
configuration.TypesToScan(handlersToLoad);
}
configuration.UseContainer<NinjectBuilder>(c => c.ExistingKernel(Kernel));
configuration.EndpointName(ConfigurationManager.AppSettings[Defaults.Project.DefaultEndPointName]);
NServiceBus.Logging.LogManager.Use<NLogFactory>();
Bus.Create(configuration).Start();
其中:
private void AddToHandlerList(List<Type> handlersToLoad, Type interfaceType)
{
List<Type> classesWhichExtendInterface = Assembly.GetExecutingAssembly().GetTypes().Where(t => interfaceType.IsAssignableFrom(t)).ToList();
classesWhichExtendInterface.Remove(interfaceType);
handlersToLoad.AddRange(classesWhichExtendInterface);
}
类型按预期加载,List
没问题。但是当我 运行 这个并到达 Bus.Start
行时,我收到以下错误:
The given key (NServiceBus.LocalAddress) was not present in the dictionary.
没有类型加载,默认行为工作正常,程序集内的所有处理器都被加载。为什么我在 运行 宁 TypesToScan()
行之后收到此错误?
编辑:这是扩展方法:
config.UseSerialization<JsonSerializer>();
config.UseTransport<RabbitMQTransport>();
config.UsePersistence<InMemoryPersistence>();
config.EnableInstallers();
return config;
你的异常发生在这里
localAddress = Address.Parse(Settings.Get<string>("NServiceBus.LocalAddress"));
设置获取传输设置的 "NServiceBus.LocalAddress" kvp。由于您没有使用 "Core" 传输 (MSMQ),我可能怀疑您的传输程序集类型需要包含在 TypesToScan 中,因为:
ForAllTypes<Feature>(TypesToScan, t => featureActivator.Add(t.Construct<Feature>()));
我在使用 SQL 服务器传输时遇到了类似的问题,当我将程序集列表发送到 With(assemblies) 并且没有在其中包含 NServiceBus 程序集时,传输无法初始化。一旦我添加了 NServiceBus.* 程序集,一切就开始工作了。
我想为任何可能发现与我遇到的情况类似的人添加一个答案,我在使用 NServiceBus.Testing
测试传奇时遇到了这个确切的错误。
当您 运行 Test.Initialize
设置您的单元测试时,您实际上可以通过一些 BusConfiguration
设置,其中您可以指定要扫描的程序集。我通常使用以下作为标准设置,如果您正在调试测试(至少使用 NUnit),它可以防止某些程序集加载问题:
Test.Initialize(conf => conf.AssembliesToScan(assembly.GetExecutingAssembly()))
但是,由于我不知道的原因,今天我正在设置 saga 测试并收到此问题中提到的 NServiceBus.LocalAddress
错误。我设法通过向 AssembliesToScan
添加一个附加参数来解决该问题,如下所示:
Test.Initialize(conf => conf.AssembliesToScan(
Assembly.GetExecutingAssembly(),
Assembly.GetCallingAssembly()));
希望这对某人有所帮助。