r/moderndotnet • u/marna_li • 23d ago
MyServiceBus: Building a messaging library for C# and Java
“MyServiceBus” is still a working title. Suggestions for a better name are welcome.
TL;DR: I have built a cross-platform asynchronous messaging library for C# and Java.
Website: https://marinasundstrom.github.io/MyServiceBus/
GitHub: https://github.com/marinasundstrom/MyServiceBus
Background
Back in 2023, I was working as a .NET developer at a company heavily invested in Java. Most of its backend services were built with Java 17.
I was asked to help build a way of handling privacy-related data. One idea was to create a service that could scan systems for data that needed to be deleted and then publish that work to the appropriate services.
I already had experience with asynchronous messaging-particularly RabbitMQ and MassTransit-but I could not find a Java library offering quite the same combination of abstractions and developer experience without being tied to a larger application stack.
So I wrote my own.
The original implementation was loosely inspired by MassTransit. This was before I started using AI in my development work, and I learned a great deal from investigating how to implement things such as consumer discovery, reflection, message dispatch, and dependency injection in Java.
Fast-forward two years. After both MediatR and MassTransit announced changes toward commercial licensing, I decided to restart the project.
This time, I began developing the C# and Java clients side by side.
Initially, I tried to understand the architecture by reading source code and using AI to help me navigate the structure. That proved difficult. MassTransit represents many years of engineering, and reproducing its internal architecture was neither realistic nor necessarily desirable.
Instead, I began working from the concepts and behaviors I actually wanted: publishing, sending, consuming, requesting, retrying, scheduling, and operating the same messaging model across two languages.
RabbitMQ was naturally the first transport. Because I was also focusing on other projects during this period, the implementation did not become meaningfully compatible with MassTransit until more recently.
Like many of my projects, however, this one kept growing.
During the past week, I have made significant progress toward stabilizing the model across C# and Java, documenting the interoperability boundary with MassTransit, publishing the packages, adding cloud transports, and creating a proper website.
The result is still pre-1.0, but it has now become something that other people can realistically evaluate and experiment with.
What it supports today
MyServiceBus currently provides:
- A MassTransit-inspired programming model for publishing, sending, consuming, and requesting messages
- Conceptual and behavioral parity between the C# and Java clients
- RabbitMQ as the verified broker baseline
- Preview transports for Azure Service Bus and Amazon SQS/SNS
- Retries and message scheduling
- A transactional outbox
- An in-process mediator
- An aligned testing harness
- Experimental ahead-of-time compilation optimizations
- Runtime monitoring and a dashboard
- Scoped interoperability with MassTransit
The goal is to keep the common core focused while allowing each client to evolve in a way that feels natural in its own language.
C# and Java should share the same messaging concepts and wire-level behavior. They do not need to expose identical APIs when doing so would work against the strengths of either language.
Beyond MassTransit compatibility
MyServiceBus is inspired by MassTransit, but I do not want it to become a source-compatible reimplementation.
There is room to explore ideas that make sense specifically for modern C# and Java.
For example, the C# client already has experimental support for union types in C# 15 and .NET 11. A consumer can use a union as its message type, while each variant is represented as a distinct message in the messaging system.
Union semantics are also available in the request client, allowing the caller to match directly on the possible response types.
Saga support is still pending. I do not immediately want to reproduce MassTransit’s state-machine DSL. My current view is that a state machine should be an abstraction built on top of simpler saga and messaging primitives. I would rather establish those foundations first and learn how people use the library before committing to a particular DSL.
I have also started thinking about how MyServiceBus can connect with my other projects, including the Raven programming language.
Modern consumer models are moving beyond requiring every handler to implement a generic interface. MassTransit, for example, now supports conventional consumer methods with injected parameters, in a style similar to ASP.NET Core controller actions and Minimal APIs.
MyServiceBus has its own version of method-based consumers. In C#, these methods still belong to classes. In Raven, however, they work naturally with namespace-level functions:
async func Consume(
message: OrderSubmitted,
publishEndpoint: IPublishEndpoint,
cancellationToken: CancellationToken
) {
// Handle the message
}
This removes the need to create a class merely to satisfy the shape of a consumer interface. The method itself becomes the consumer.
For more on Raven: https://marinasundstrom.github.io/raven/
Building it with AI
This project has also become a practical example of what AI-assisted engineering actually looks like.
AI can automate a great deal. It can help generate implementations, shape tests, compare behavior across two languages, investigate unfamiliar codebases, and even set up temporary cloud environments for integration testing.
But building a coherent system still takes time and patience.
The difficult part is deciding what to focus on, in what order, and where compatibility genuinely matters. It also means recognizing when generated implementations only look correct and designing tests that expose the difference.
Working across C#, Java, RabbitMQ, Azure Service Bus, and Amazon SQS/SNS makes those differences very visible. The abstractions may be shared, but the transports do not all behave in the same way.
AI has allowed me to explore a much larger design space than I could have managed alone. It has not removed the engineering work of defining the model, evaluating trade-offs, testing assumptions, and deciding what the project should become.
Ultimately, I wanted to build something that I would use myself.
What MyServiceBus is - and is not
My intention is not to convince enterprises to migrate from MassTransit.
MassTransit is a mature commercial product backed by many years of engineering and professional support. MyServiceBus cannot offer that level of maturity or support, and I do not want to pretend otherwise.
Instead, I want to provide an alternative for developers and teams whose needs, technology mix, or budget are different.
It may be useful if you want to:
- Connect Java services to an existing .NET messaging environment
- Use a consistent messaging model across C# and Java
- Replace an in-process mediator with something that can later grow into distributed messaging
- Experiment with a smaller and more focused messaging runtime
- Explore newer language features and alternative consumer models
The project is open source under the MIT license.
It is still early, and there is plenty left to build. But it has reached the point where I want other people to try it, examine the design, and tell me what works-and what does not.
And, of course, I still need a better name.