3

How is NServiceBus maintaining consistency when the outgoing headers is static?

Does it mean if I were to set the outgoing headers for a particular message, it will affect all other outgoing messages since it's a singleton?

namespace NServiceBus.MessageHeaders
{
  [ComVisible(false)]
  public class MessageHeaderManager : IMutateOutgoingTransportMessages
  {
    private static IDictionary<string, string> staticOutgoingHeaders = (IDictionary<string, string>) new Dictionary<string, string>();
    private IUnicastBus bus;
    [ThreadStatic]
    private static IDictionary<object, IDictionary<string, string>> messageHeaders;
   .
   .
   .
 }

The incoming header seems to be correctly marked as [ThreadStatic] however.

Explain.

========================EDIT==============================

I guess I'm trying to understand because many examples show the code below:

Bus.OutgoingHeaders["Test"] = g.ToString("N");

Which's traced to:

IDictionary<string, string> IBus.OutgoingHeaders
{
  get
  {
    return ExtensionMethods.GetStaticOutgoingHeadersAction();
  }
}

Which's set at:

internal class Bootstrapper : INeedInitialization, IWantToRunWhenConfigurationIsComplete { public MessageHeaderManager Manager { get; set; }

void INeedInitialization.Init()
{
  Configure.Instance.Configurer.ConfigureComponent<MessageHeaderManager>(DependencyLifecycle.SingleInstance);
}

public void Run()
{
  ExtensionMethods.GetHeaderAction = (Func<object, string, string>) ((msg, key) => this.Manager.GetHeader(msg, key));
  ExtensionMethods.SetHeaderAction = (Action<object, string, string>) ((msg, key, val) => this.Manager.SetHeader(msg, key, val));
  ExtensionMethods.GetStaticOutgoingHeadersAction = (Func<IDictionary<string, string>>) (() => this.Manager.GetStaticOutgoingHeaders());
}

}

And of course the GetStaticOutgoingHeaders in the last line above goes to a static field.

I'm trying to figure out how to set the header, for the next message. But if I follow the examples, I end up setting the headers for ALL messages.

4

1 回答 1

4

[Udi 更新]如果您想在发送的特定消息上设置标头,只需调用.SetHeader(key, value);消息对象上的方法即可。静态传出标头对于进程范围的数据很有用,例如登录用户在桌面应用程序中的身份。[结束更新]

MessageHeaderManager是一个IMutateOutgoingTransportMessages,这意味着它只关心消息在他们的出路。这里没有显示传入的消息标题。

messageHeaders关注为每个消息设置的标头,例如发送时间,或者您可以从消息处理程序手动设置的任何内容。

staticOutgoingHeaders是一个缓存端点外每条消息的所有相同标头的地方,这样就不需要重新计算它们的值。这将包括诸如源机器名称之类的内容。

如果您查看该 MutateOutgoing 方法的内容,您将看到两者中的所有键/值对messageHeaders都已staticOutgoingHeaders添加到transportMessage.Headers集合中。此外,在添加Headers.Add(key, value)静态标题的同时添加静态标题,Headers[key] = value以便线程静态集合中的项目将覆盖同名的静态标题。

这是GitHub 上此类的完整源代码的链接,由 V4.0.3 的标签链接(在撰写本文时为当前版本),因此希望该链接不会过期。

于 2013-08-23T21:10:08.303 回答