SamtecCraig
SamtecCraig

Reputation: 31

Event Subscriptions and Source-level coupling

When creating a pub/sub between service boundaries, the recommendation is to create a "Messages" or "Events" assembly. The publisher publishes an event (interface) from that assembly. The subscriber listens for that event (interface), which means there is at least source-level coupling in the subscriber to an assembly in the publisher's service boundary.

In an enterprise scenario with numerous pub/sub events, is it possible to publish the event in such a way that the subscriber can listen and deserialize the message without needing a reference to the publisher's message assembly? What would be the drawbacks of such a approach?

With automated builds and these shared assemblies, if the team publishes a new event (adds an interface to the shared assembly), to which I do not wish to subscribe, my services will be queued to build. This causes unnecessary work and potential confusion as to why my projects rebuilt and no action is necessary on my team's part (other than to investigate and find out that there is no action to take).

Here is a basic DotNetFiddle Example illustrating what I am trying to explain. In essence, I am trying to avoid a project/assembly reference to Purchasing.Events.dll from Quoting.Backend.dll.

Upvotes: 1

Views: 115

Answers (1)

David Boike
David Boike

Reputation: 18635

The third tenet of the four tenets of SOA is "Services share schema & contract, not class" but as it turns out the easiest way to exchange those schemas and contracts are via, well, classes, lest we get into WSDL hell like we do with SOAP-based web services.

So yes, if you abuse the implementation detail that the contracts are expressed as classes and have big monolithic solutions that reference all of the message assemblies, you will get all the problems you describe.

The solution is to pay more attention to 2 of the other tenets: Boundaries are explicit (#1) and Services are autonomous (#2).

What does this mean?

  • Especially in a big enterprise scenario like you describe, each service should be implemented in its own solution.
  • Each service should publish its own events assembly with events owned by the service, commonly called ServiceName.Events.dll or ServiceName.Contracts.dll
    • Only event classes (schema) should be included. No commands internal to the service. No commands at all, in fact, because autonomous services should only communicate via events.
    • A private NuGet server (or service like MyGet) would be optimal for the distribution of this assembly.
  • Each service's events should be versioned very explicitly, and preferably rigidly follow the rules of SemVer.

If you follow these guidelines, when a team publishes a new event that you don't want/need to subscribe to, no change is necessary. It will just continue to run. You can pay attention to the NuGet repository and make educated decisions about when and how to upgrade a different service's events assembly.

Upvotes: 3

Related Questions