4

配置 Rebus 总线时,您可以指定它应该按照此处Headers.UserName所述查找标头。这允许您自动填充Thread.CurrentPrincipal使用正确的用户名自动填充。这很好用,但我想知道是否有一种以标准方式设置标题的好方法,而不是在发送每条消息时手动设置它。

我正在构建一个基于 ASP.NET Web API 的服务,并希望每个请求都将标头设置为在apiControllerInstance.RequestContext.Principal.Identity.Name.

一个不错的解决方案是在可以访问消息总线的基础上创建一个方法ApiController,因此您可以执行以下操作:

public IHttpActionResult SomeAction(SomeMessage message)
{
    SendWithUser(message);
    return Ok();
}

问题是你必须记住这样做,所以我想得到一些关于如何以更一般的方式做到这一点的建议。此外,其他标头将来可能会变得相关,这也将是这种方法的问题。

更新

根据 mookid 的回答,我提出了以下解决方案(我刚刚验证它适用于我的一个请求,但我不承诺稳健性):

public static void SetUserNameHeaderWhenCurrentPrincipalIsPresent(this IRebusEvents events)
{
    events.MessageSent += (bus, destination, message) =>
    {
        if (HttpContext.Current.User != null && !string.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name))
            bus.AttachHeader(message, Headers.UserName, HttpContext.Current.User.Identity.Name);
    };
}

用法:

.Events(e => e.SetUserNameHeaderWhenCurrentPrincipalIsPresent())
4

3 回答 3

2

您可以使用

Configure.With(...)
    .(...)
    .Events(e => e.MessageSent += SetUsername)

SetUsername调用每条传出消息,这就是您可以查找的地方HttpContext.Current

如果您认为缺少其他内容,请告诉我这对您有何影响:)

于 2013-11-24T06:54:52.390 回答
0

尝试使用结合 autofac 的装饰器模式。以下示例说明了一种可能的解决方案:

public class RebusConfig  {

    protected override void Load(ContainerBuilder builder)
    {
        //Autofac configuration to decorate Rebus
        builder.RegisterDecorator<IBus>(
                    (c, inner) => new RebusMetadataDecorator(
                            inner, c.Resolve<HttpRequestMessage>()),
                    fromKey: "Metadata")
                     .InstancePerRequest();

    }

    public override SetContainer(IContainer container){
            //Configure the desired rebus
            var bus = Rebus.Config.Configure.With(new AutofacContainerAdapter(container));

            //Reconfigure rebus to support decorator
            //Note: I want to improve this step!
            var containerUpdate = new ContainerBuilder();

            containerUpdate
                  .RegisterInstance(bus)
                  .SingleInstance()
                  .Named<IBus>("Metadata");

            containerUpdate.Update(container);
     }          
}           

//Rebus Decorator               
public class RebusMetadataDecorator : IBus
{
        private  HttpRequestMessage requestMessage;
        private  IBus bus;

        public RebusMetadataDecorator(
            IBus bus, HttpRequestMessage requestMessage)
        {
            this.requestMessage = requestMessage;
            this.bus = bus;
        }

        public void Publish<TEvent>(TEvent message)
        {
            SetHttpMetadataToHeader(bus, message, metadataProvider, prefix);
            bus.Publish<TEvent>(message);
        }
}
于 2016-10-26T17:18:21.630 回答
0

可以以一种很好的方式将标头添加到发送消息中。下面的例子。

private readonly IBus messageBus;
...
var expirationHeader = new Dictionary<string, string>
{
    { Headers.TimeToBeReceived, "00:00:30" },
};

this.messageBus.Send(reqMsg, expirationHeader).ConfigureAwait(false);
于 2019-08-26T08:22:43.287 回答