-
-
Notifications
You must be signed in to change notification settings - Fork 364
Messages
To Rebus, a message is just a serializable object. Whether your particular object is serializable, depends on the layout of the object and which serializer you are using, but Rebus comes with a sturdy and tolerant built-in JSON serializer.
Since Rebus likes to route messages based on their types, you will most likely create a class for each type of message you want to send. An example event message could look like this in C# 6:
public class InventoryItemMoved
{
public InventoryItemMoved(string itemId, string newLocationId)
{
ItemId = itemId;
NewLocationId = newLocationId;
}
public string ItemId { get; }
public string NewLocationId { get; }
}
which you would then publish like this:
await bus.Publish(new InventoryItemMoved(someItemId, someNewLocationId));
in order to broadcast it to anyone who did this:
await bus.Subscribe<InventoryItemMoved>();
That's basically all there is to it - although there are some things you need to observe in order to avoid breaking the serialization of the messages. Please read on 😁
Unless you explicitly do something to change the serializer, Rebus will use a pretty robust and tolerant JSON serialization based on Newtonsoft JSON.NET.
It utilizes JSON.NET's ability to include FULL TYPE INFORMATION, which means that an instance of the InventoryItemMoved
event above will be serialized to this (just assuming that it is residing in the Events
namespace of the InventoryManagement.Messages
assembly):
{"$type":"InventoryManagement.Messages.Events.InventoryItemMoved, InventoryManagement.Messages","ItemId":"item-234-abc","NewLocationId":"LOC87484-A"}
which looks a little prettier if we add some indentation:
{
"$type": "InventoryManagement.Messages.Events.InventoryItemMoved, InventoryManagement.Messages",
"ItemId": "item-234-abc",
"NewLocationId": "LOC87484-A"
}
As you can see, the $type
property specifies an assembly-qualified type name for the message type, making it possible for the receiving end to deserialize the message to its proper type.
BUT PLEASE NOTE that each of the property names in the JSON text must correspond to either
- a publicly settable property with the same name and a compatible type, or
- a constructor parameter with the same name (possibly camelCase) and a compatible type
In other words, you would ALSO be able to deserialize the JSON shown above with this class:
public class InventoryItemMoved
{
public string ItemId { get; set; }
public string NewLocationId { get; set; }
}
where the following classes would FAIL to deserialize the JSON text shown above:
public class InventoryItemMoved
{
// \/ should have been 'itemId'!!
public InventoryItemMoved(string relevantItemId, string newLocationId)
{
ItemId = relevantItemId;
NewLocationId = newLocationId;
}
public string ItemId { get; }
public string NewLocationId { get; }
}
public class InventoryItemMoved
{
public string Item { get; set; } // << missing 'Id' in name!
public string NewLocationId { get; set; }
}
Another thing with messages is that it is usually advised to keep them small! This is because big messages can end up clogging the queues, leading to unpredictable latencies when processing them, etc.
It also this realization that has caused most queueing systems to have a hard cap on how big messages can be - e.g. MSMQ allows for maximum 4 MB messages (which is actually pretty big!) where Azure Service Bus has a maximum of 64 kB.
If you need to transfer bigger chunks of data with Rebus, you should probably look into using Rebus' data bus.
Basic stuff
- Home
- Introduction
- Getting started
- Different bus modes
- How does rebus compare to other .net service buses?
- 3rd party extensions
- Rebus versions
Configuration
Scenarios
Areas
- Logging
- Routing
- Serialization
- Pub sub messaging
- Process managers
- Message context
- Data bus
- Correlation ids
- Container adapters
- Automatic retries and error handling
- Message dispatch
- Thread safety and instance policies
- Timeouts
- Timeout manager
- Transactions
- Delivery guarantees
- Idempotence
- Unit of work
- Workers and parallelism
- Wire level format of messages
- Handler pipeline
- Polymorphic message dispatch
- Persistence ignorance
- Saga parallelism
- Transport message forwarding
- Testing
- Outbox
- Startup/shutdown
Transports (not a full list)
Customization
- Extensibility
- Auto flowing user context extensibility example
- Back off strategy
- Message compression and encryption
- Fail fast on certain exception types
Pipelines
- Log message pipelines
- Incoming messages pipeline
- Incoming step context
- Outgoing messages pipeline
- Outgoing step context
Prominent application services