Skip to content

Design Principles

The architecture of ServiceBus.Core is guided by a small set of design principles that influence every component of the framework.

Understanding these principles helps explain many of the design choices discussed throughout the documentation.


Provider Agnostic

The core library is intentionally independent from any specific messaging platform.

graph TD

    Core["ServiceBus.Core"]

    Rabbit["RabbitMQ"]

    Artemis["ActiveMQ Artemis"]
    Kafka["Apache Kafka"]
    Redis["Redis Pub/Sub"]

    Core --> Rabbit

    Core -. Future .-> Artemis
    Core -. Future .-> Kafka
    Core -. Future .-> Redis

The goal is to allow provider implementations to evolve independently from the contracts exposed by the core library.

The current implementation targets RabbitMQ, but the architecture does not depend on RabbitMQ-specific concepts.


Descriptor First

Topology and runtime behavior are described through descriptors.

Instead of writing infrastructure code such as:

channel.ExchangeDeclare(...);
channel.QueueDeclare(...);
channel.QueueBind(...);

applications define descriptors that describe the desired topology.

Benefits include:

  • centralized configuration;
  • environment portability;
  • easier testing;
  • configuration-driven deployments;
  • reduced infrastructure duplication.

Transport Abstraction

Applications should depend on messaging contracts rather than transport implementations.

graph LR

    Application --> IAsyncPublisher

    IAsyncPublisher --> RabbitMQ

The application publishes messages without knowledge of the underlying broker.


Formatter Abstraction

Message serialization is intentionally separated from transport logic.

graph LR

    Publisher --> IDataFormatter

    IDataFormatter --> JSON

    Publisher --> RabbitMQ

This separation allows:

  • different serialization technologies;
  • custom payload formats;
  • independent formatter evolution.

Event Driven Runtime

The framework promotes asynchronous communication patterns.

Applications communicate through messages rather than direct dependencies.

Benefits include:

  • decoupling;
  • scalability;
  • resilience;
  • independent deployment.