Let's begin given our current message:
public interface IProductUpdatedEvent : IProductChangedEvent { } public interface IProductChangedEvent : IEvent { Int32 ProductNumber { get; set; } String Name { get; set; } String Description { get; set; } }Now let's say we want to add a new field to our event. We create the new event in a different namespace so we can use the same interface name and add our new field after we implement the old interface:
public interface IProductUpdatedEvent : Messages.IProductUpdatedEvent { Int32 DepartmentNumber { get; set; } }So now we have two distinct messages that have different data sets. This means our legacy clients can continue to receive the legacy message and our new clients can receive the new message. Here is an example of a handler pointing to the new message type:
public class EventMessageHandler : IMessageHandler<Messages.New.IProductUpdatedEvent> { private static ILog log = LogManager.GetLogger(typeof(EventMessageHandler)); public void Handle(Messages.New.IProductUpdatedEvent message) { log.Debug(String.Format("{0} Event Received for Product {1}: {2} : {3}", message.GetType().UnderlyingSystemType.Name, message.ProductNumber, message.Name, message.DepartmentNumber)); } }The rest of our Subscribers remain the same. All that is left is to update the Publisher to publish the new event. In the example code there is a Windows Forms app(UI) that pushes all events to a common Publisher endpoint. See the Documentation directory for a diagram. In the example all we have to do is add the new field and publish the new event.
Messages.New.IProductUpdatedEvent pu = new Messages.New.ProductUpdatedMessage { ProductNumber = Int32.Parse(textBoxUpdateID.Text), Description = textBoxUpdateDesc.Text, Name = textBoxUpdateName.Text, EventId = Guid.NewGuid(), Time = DateTime.Now, DepartmentNumber = 10 }; FireEvent(pu);If you pull down the sample and look in the PubSub directory, fire up the BusServer, UI, Subscriber1, and Subscriber3 projects. From the UI simple type in second group box and hit the "Update" button. This will send the new message to the "BusServer" Publisher endpoint which will do the actual Bus.Publish(). From there you will see Subscriber1 receive the legacy event and Subscriber3 receive the new event with the new data.
NSB allows us to gracefully support new message types and uphold backwards compatibility. We were able to introduce new data and rely upon inheritance to handle the rest. Full code can be found here: http://github.com/afyles/Blog/tree/master/NServiceBusExplorer/
No comments:
Post a Comment