配置Rebus总线时,您可以指定它应查找here所述的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())
答案 0 :(得分:2)
您可以使用
Configure.With(...)
.(...)
.Events(e => e.MessageSent += SetUsername)
让SetUsername
调用每个外发邮件,这就是您可以在HttpContext.Current
如果你认为缺少其他东西,请告诉我你的工作原理:)
答案 1 :(得分: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);
}
}
答案 2 :(得分:0)
可以很好地将标头添加到发送消息中。下面的示例。
private readonly IBus messageBus;
...
var expirationHeader = new Dictionary<string, string>
{
{ Headers.TimeToBeReceived, "00:00:30" },
};
this.messageBus.Send(reqMsg, expirationHeader).ConfigureAwait(false);