无法订阅来自 ASP.NET Core 6.0 API NServiceBus 端点的事件
Cannot subscribe to events from an ASP.NET Core 6.0 API NServiceBus endpoint
我想让我的 API 既发布事件(在任何传入消息处理程序之外,例如来自操作方法)又订阅事件。发布活动有效。我使用 Program
和 Startup
的旧版本使用 GenericHost
进行集成,并且 IMessageSession
成功地注入到构造函数中。
但是在激活注释掉的代码让API订阅和处理事件时,初始化host时突然抛出注入IMessageSession
的异常,运行 应用程序。
TestController.cs
namespace TestContext
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase/*, IHandleMessages<ReceivedEvent>*/
{
private IMessageSession _session;
public TestController(IMessageSession session)
{
_session = session;
}
/*
[NonAction]
public Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
throw new NotImplementedException();
}*/
[HttpPost]
public async Task<ActionResult> Test()
{
await _session.Publish(new PublishedEvent());
return Ok();
}
}
}
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNServiceBus(context =>
{
var endpointConfiguration = new EndpointConfiguration("Test");
var transport = endpointConfiguration.UseTransport<LearningTransport>();
return endpointConfiguration;
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
异常
为什么会抛出异常,如何让API订阅和处理事件?
编辑
从单独的服务 class 处理事件时,不会抛出异常。
public class HandlerService : IHandleMessages<ReceivedEvent>
{
public Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
Console.WriteLine(message);
return Task.CompletedTask;
}
}
这里的异常信息其实挺好的。大多数 NServiceBus 异常消息都是。
Interfaces IMessageSession or IEndpointInstance should not be resolved from the container to enable sending or publishing messages from within sagas or message handlers. Instead, use the context parameter on the TestController.Handle method to send or publish messages.
所以首先,不要在控制器中混用处理程序。它需要是一个单独的 class.
那么,不要注入IMessageSession。该接口明确用于诸如控制器操作之类的事情,在这些操作中,您没有现有的“正在处理消息”并且您想发送消息。
相反,如果您想在处理程序中发送或发布,请使用上下文:
不要这样做
public class MyHandler : IHandleMessages<ReceivedEvent>
{
private IMessageSession session;
public MyHandler(IMessageSession session)
{
// Won't work! Don't inject IMessageSession!
this.session = session;
}
public async Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
// NOPE!
session
}
}
改为这样做
public class MyHandler : IHandleMessages<ReceivedEvent>
{
public async Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
context.Send(new CommandToSend());
context.Publish(new EventToPublish());
}
}
我想让我的 API 既发布事件(在任何传入消息处理程序之外,例如来自操作方法)又订阅事件。发布活动有效。我使用 Program
和 Startup
的旧版本使用 GenericHost
进行集成,并且 IMessageSession
成功地注入到构造函数中。
但是在激活注释掉的代码让API订阅和处理事件时,初始化host时突然抛出注入IMessageSession
的异常,运行 应用程序。
TestController.cs
namespace TestContext
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase/*, IHandleMessages<ReceivedEvent>*/
{
private IMessageSession _session;
public TestController(IMessageSession session)
{
_session = session;
}
/*
[NonAction]
public Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
throw new NotImplementedException();
}*/
[HttpPost]
public async Task<ActionResult> Test()
{
await _session.Publish(new PublishedEvent());
return Ok();
}
}
}
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNServiceBus(context =>
{
var endpointConfiguration = new EndpointConfiguration("Test");
var transport = endpointConfiguration.UseTransport<LearningTransport>();
return endpointConfiguration;
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
异常
为什么会抛出异常,如何让API订阅和处理事件?
编辑
从单独的服务 class 处理事件时,不会抛出异常。
public class HandlerService : IHandleMessages<ReceivedEvent>
{
public Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
Console.WriteLine(message);
return Task.CompletedTask;
}
}
这里的异常信息其实挺好的。大多数 NServiceBus 异常消息都是。
Interfaces IMessageSession or IEndpointInstance should not be resolved from the container to enable sending or publishing messages from within sagas or message handlers. Instead, use the context parameter on the TestController.Handle method to send or publish messages.
所以首先,不要在控制器中混用处理程序。它需要是一个单独的 class.
那么,不要注入IMessageSession。该接口明确用于诸如控制器操作之类的事情,在这些操作中,您没有现有的“正在处理消息”并且您想发送消息。
相反,如果您想在处理程序中发送或发布,请使用上下文:
不要这样做
public class MyHandler : IHandleMessages<ReceivedEvent>
{
private IMessageSession session;
public MyHandler(IMessageSession session)
{
// Won't work! Don't inject IMessageSession!
this.session = session;
}
public async Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
// NOPE!
session
}
}
改为这样做
public class MyHandler : IHandleMessages<ReceivedEvent>
{
public async Task Handle(ReceivedEvent message, IMessageHandlerContext context)
{
context.Send(new CommandToSend());
context.Publish(new EventToPublish());
}
}