Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing message definitions between NServiceBus services

Tags:

c#

nservicebus

Imaginative setup

  • Several services
  • Each lives in its own repository
  • Each developed separately
  • Each deployed separately
  • They want to communicate via NServiceBus

Research

Examples on NServiceBus basics show how several applications, which are part of the same solution, share message definitions using another Shared library project, that they all reference. Here, if services are not part of the same solution things become complicated.

I suppose, shared project can be extracted into a separate repository and then be referenced from other repositories as a DLL or as a custom NuGet package, for example. But it creates a lot of difficulties during development and doesn't feel to be right.

In this sample http://docs.particular.net/samples/step-by-step/, there is even a note saying:

Storing all message definitions in a single location is not a best practice, but serves to illustrate how things work for this simple example.

However I yet failed to find what is a best practice.

Question: How to share message definitions between services in a proper way?

like image 252
Alexei Matrosov Avatar asked Aug 09 '16 13:08

Alexei Matrosov


1 Answers

Your imaginative setup is good. However, rather than having one shared messages assembly, each service can have its own messages assembly, and then publish it as a NuGet package to a private repository.

So if you have the Sales service, for example, in the Sales repository, would also contain a Sales.Messages project. It the most basic form, it would contain the definitions for all commands processed by the Sales service, and the definitions for all events published by the Sales service.

It's also smart to further divide up messages between a Sales.InternalMessages and (let's just call it for now) Sales.Contracts.

Internal messages would be just messages that are tossed around within your service. Like private methods, you wouldn't want other teams to be able to invoke those from outside your service, and so you wouldn't distribute those messages externally as a NuGet package.

Then, Sales.Contracts would contain only those messages that go outside the service. Naming them "Contracts" reminds you that's what they are - a contract between services - and so you need to manage them as such. That means that changes to them need to be carefully considered and versioned as well.

like image 180
David Boike Avatar answered Oct 02 '22 16:10

David Boike