我使用 Rebus 3.0.1 和 Simpleinjector。我已经注册了一个装饰器,用于记录所有处理程序,如下所示:
container.RegisterDecorator(typeof(IHandleMessages<>), typeof(HandlerLogDecorator<>));
除了 Sagas 之外,一切正常:因为在 LoadSagaDataStep 中,以下代码
var handlerInvokersForSagas = context.Load<HandlerInvokers>()
.Where(l => l.HasSaga)
.ToList();
无法在幕后找到 Saga。
如果我取消注册装饰器,saga 会再次开始工作。
有什么建议可以协调传奇故事和处理程序装饰器吗?
最佳答案
不幸的是,正如您所发现的,Rebus 并不期望处理程序(包括 sagas)被包装在装饰器中。
它在内部大量使用装饰器来处理各种事情,并且鼓励使用装饰器作为开发人员的扩展点,但这仅适用于 Rebus 的所有服务,例如 IPipeline
、 ISubscriptionStorage
等
如果您想记录与消息处理相关的内容,更好的扩展点是
a) 使用 Rebus.Events
只需安装一个事件处理程序,如下所示:
Configure.With(...)
.(...)
.Events(e => {
e.AfterMessageHandled += (bus, headers, message, context, args) => {
// log stuff in here :)
};
})
.Start();
或
b) 创建一个传入管道步骤来记录您想要记录的内容,如下所示:
Configure.With(...)
.(...)
.Options(o => {
o.Decorate<IPipeline>(c => {
var step = new YourLoggingStep();
var pipeline = c.Get<IPipeline>();
return new PipelineStepInjector(pipeline)
.OnReceive(step, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep));
});
})
.Start();
可能将所有丑陋的东西包装在一个扩展方法中,使用法看起来更像这样:
Configure.With(...)
.(...)
.Options(o => {
o.LogHandledMessages();
})
.Start();
关于decorator - ReBus:无法将 sagas 与处理程序装饰器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45051152/