If you want to be more declarative about setting the expiration timeout on your messages, you can define your own [TimeToBeReceived(...)] attribute, and then take advantage of Rebus’ hooks to detect the attribute on sent messages and set the appropriate header.
E.g. define the attribute in your message assembly like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class TimeToBeReceivedAttribute : Attribute { readonly string hmsString; public TimeToBeReceivedAttribute(string hmsString) { this.hmsString = hmsString; } public string HmsString { get { return hmsString; } } } |
You can think of this attribute as a vital piece of business knowledge: “The information contained within this message is irrelevant after the specified time has elapsed.” Therefore, it definitely belongs somewhere within your code. You can of course argue whether it belongs within the message assembly, but there’s nothing in the snippet above that prevents you from passing MyBusinessConstants.SomeSpecificKindOfInformationMaxValidFor as the value, and then let the MyBusinessConstants be defined in another assembly. And then you could argue some more, but the point is that you get to avoid Rebus references in your message assemblies. Period.
And then you can detect it whenever Rebus sends a message by setting up a listener on the MessageSent event of the advanced bus’ Events.MessageSent event by using the event hooks configuration API, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Configure.With(myFavoriteContainerAdapter) // (your usual config blabla, possibly something like this:) .Logging(l => l.Log4Net()) .Transport(t => t.UseMsmqAndGetInputQueueNameFromAppConfig()) .DetermineEndpoints(d => d.FromRebusConfigurationSection()) // (and then:) .Events(e => { e.MessageSent += (advancedbus, destination, message) => { var attribute = message.GetType() .GetCustomAttributes(typeof (TimeToBeReceivedAttribute), false) .Cast<TimeToBeReceivedAttribute>() .SingleOrDefault(); if (attribute == null) return; advancedbus.AttachHeader(message, Headers.TimeToBeReceived, attribute.HmsString); }; }) .CreateBus() .Start(); |
which will then allow you to apply message expiration timeouts like this:
1 2 3 4 5 |
[TimeToBeReceived("00:00:30")] public class SomethingHappened { public DateTime Time { get; set; } } |
while keeping your messages assembly clean from Rebus stuff.
Please note, however, that the APIs shown here are only available in Rebus 0.13.0-alpha and forward, as this version contains the new stuff with the ability to set up hooks with the configuration API.