Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why interfaces for message contracts are strongly recommended in MassTransit?

Tags:

MassTransit states that we should use interfaces for message contracts :

It is strongly suggested to use interfaces for message contracts, based on experience over several years with varying levels of developer experience. MassTransit will create dynamic interface implementations for the messages, ensuring a clean separation of the message contract from the consumer.

Source : Docs » Using MassTransit » Creating a message contract

What is downside of using POCO DTOs instead of interfaces, what are the obvious advantages of Interfaces over classes in the context of messaging with MassTransit?

On the other hand NServiceBus is fine with POCO, and sure it makes sense to not use internal classes like domain object, see below.

Source : NServiceBus » Messaging » Messages, Events and Commands

When creating messages one should follow the following guidelines:

  • Messages should be simple POCO objects.
  • Messages should be as small as possible.
  • Messages should satisfy a Single Responsibility Principle.
  • Classes used for other purposes (e.g. domain objects, data access objects and UI binding objects) should not be used as messages.
like image 535
Edgars Pivovarenoks Avatar asked Jun 05 '17 12:06

Edgars Pivovarenoks


1 Answers

Although not directly related to MassTransit, but I would say the reason is encapsulation. Creating a simple POCO with setters, but passing it on behind interface that promises only getters encapsulates the data in the DTO.

public class Program {     static void Main(string[] args)     {         User user = new User()         {             Username = "user99"         };          Account account = new Account(user);     } }  public interface IUser {     string Username { get; } }  public class User : IUser {     public string Username { get; set; } }  public class Account {     private IUser user;      //Currently used in main     public Account(User user)     {         user.Username = ""; //This is allowed                     this.user = user;     }      //But consider this ctor     public Account(IUser user)     {         //user.Username = ""; //Not allowed         this.user = user;     }      ... } 
like image 105
Siim Haas Avatar answered Dec 11 '22 02:12

Siim Haas