It is possible to achieve this by some additional configuration?
Publish
/ Send
methods. In this case, if I change something in my message interface (e.g., rename a property), I won't get a compile-time error.Why is this recommended? How to deal with the fragility of anonymous objects?
Thanks!
When sending a message, MassTransit uses a message serializer to convert message contract instances (objects) into JSON, XML, or whatever output format is generated by the serializer. When receiving that message, a message deserializer is used to convert the formatted data back into the message contract.
MassTransit is a lightweight service bus for building distributed . NET applications. The main goal is to provide a consistent, . NET friendly abstraction over the message transport.
What is MassTransit? MassTransit is a free, open-source, distributed application framework for . NET applications. It abstracts away the underlying logic required to work with message brokers, such as RabbitMQ, making it easier to create message-based, loosely coupled applications.
The suggestion to prefer message interfaces is based on the principle "share schema, not type". An interface is a contract and contracts are ok to share. You mentioned yourself "avoid sharing message _classes". That's because classes also have behaviour and many projects suffered from message classes that included behavour, which could prevent deserialisation and introduce domain-specific concern to messages, which, in fact, are nothing more than property bags.
The documentation clearly states:
It is strongly suggested to use interfaces for message contracts, based on experience over several years with varying levels of developer experience.
and this suggestion, although strong, cannot be seen as a requirement. If all developers in your organisation clearly understand the concept of messages being property bags and only contain properties with primitive types and, at max, complex types that are property bags with primitive types - you can choose to work with classes instead of interfaces.
There's no recommendation or even a suggestion to use anonymous types. It is a possibility, but no more than that. You can perfectly use classes that implement message interfaces on the message producer side and then you won't be able to arbitrarily assign properties that don't exist in the interface.
You only share interfaces with your consumers, and since interfaces are read-only, you don't have an issue with getting deserialisation errors because some setters have some weird code that one developer thought is useful for the message type.
In our practice, we used interfaces but never used anonymous objects. We also widely use POCOs as messages, since developers got enough experience and understanding how messaging works.
The last thing about sharing is that we moved away from the practice of sharing message contracts using nuget packages. Although it looks attractive and safe, it creates some impediments in our daily work. We prefer copying message classes (or interfaces) over or use source packages. If teams follow good practices like versioning and weak schema, it doesn't create any issue. The only thing you need to take care of is keeping namespaces intact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With