如何在nservicebus中预处理消息?

时间:2012-12-05 16:56:01

标签: c# log4net nservicebus

我希望在收到消息时初始化一些日志记录:

public class BaseMessage
{
    public long TraceID { get; set; }
}

public class MyMessage : BaseMessage, ICommand
{
    //..other properties
}

public class Handler : IHandleMessages<MyMessage>
{
    public void Handle(MyMessage message)
    {
        log4net.ThreadContext.Properties["TraceID"] = message.TraceID

        //Process message
    }
}

问题是我有很多消息,我希望在收到消息时为所有消息执行此操作。我希望能够做到这样的事情:

public class Handler : IInitializeHandlers, IHandleMessages<MyMessage>
{
    public void Init(BaseMessage message)
    {
        log4net.ThreadContext.Properties["TraceID"] = ((BaseMessage)message).TraceID
    }


    public void Handle(MyMessage message)
    {
        //Process message
    }
}

2 个答案:

答案 0 :(得分:1)

将跟踪ID移动到标头,并使用工作单元(IManageUnitsOfWork)将其注册到log4net上下文

答案 1 :(得分:0)

以下是我如何解决它。我想自动创建跟踪ID并将其发送到消息正文而不是标题。我不确定向总线添加标头的线程安全性,我不想更改所有调用代码或修改IHandleMessages实现。所以这就是我想出来的。

public class TraceIDMutator : IMutateIncomingMessages, IMutateOutgoingMessages
{
    public object MutateIncoming(object message)
    {
        var baseMsg = message as MessageBase;
        if (baseMsg != null)
            ThreadContext.Properties[Constants.TraceID] = baseMsg.TraceID;

        return message;
    }

    public object MutateOutgoing(object message)
    {
        var baseMsg = message as MessageBase;
        if(baseMsg != null)
        {
            if(baseMsg.TraceID == 0)
            {
                 var tid = ThreadContext.Properties[Constants.TraceID];
                 if (tid != null)
                     baseMsg.TraceID = (ulong)tid;
            }
        }

        return message;
    }
}

IMutateIncomingMessagesIMutateOutgoingMessages接口允许我接入nservicebus的消息传递管道。我只是在挖掘完源代码后才发现它,以找出实际发生的情况。您需要在IoC容器中注册此类才能使其正常工作。

        ObjectFactory.Configure(x =>
        {
            x.For<IMutateIncomingMessages>().Use<TraceIDMutator>();
            x.For<IMutateOutgoingMessages>().Use<TraceIDMutator>();
        });

发送消息时,将调用“MutateOutgoing”。此时,我从log4net.ThreadContext获取当前跟踪ID(如果有)并将其分配给消息。收到消息后,调用MutateIncoming,然后为该线程设置log4net.ThreadContext跟踪ID属性。