Solution & Project Structure of a Loosely Coupled Monolith

Solution & Project Structure of a Loosely Coupled Monolith

Here’s how you can create a solution and project structure to develop a loosely coupled monolith using a .NET Solution with C# Projects.

Each boundary is in a solutions folder with 3 projects. Implementation, Contracts, and Tests. All of which are class libraries. The two top-level executable projects, AspNetCore and Worker are console applications that reference the implementation projects.

Loosely Coupled Monolith

This blog post is apart of a series of posts I’ve created around Loosely Coupled Monoliths.

YouTube

Check out my YouTube channel where I post all kinds of content that accompanies my posts.

System Diagram

Here’s a diagram of what the Solution and C# project structure should reflect.

Solution & Project Structure of a Loosely Coupled Monolith

Bounded Context

The middle row of the diagram has 3 boxes that represent a boundary. These boundaries should define the set of capabilities of your system. Each boundary contains 3 projects: Contracts, Implementation, and Tests.

Solution & Project Structure of a Loosely Coupled Monolith

In my example above, there are 2 boundaries: Sales, and Shipping. For each one, I’ve created a solutions folder which the 3 respective projects for each boundary inside. All 6 projects are C# Class Libraries.

References

Each implementation project (Sales & Shipping) will only reference other Contract projects. They will never reference another implementation project.

Solution & Project Structure of a Loosely Coupled Monolith

The example above has the Sales implementation referencing the Shipping.Contracts.

Top-Level

There are two top-level projects that are our executable projects. AspNetCore and a Message Process (Worker).

Top-level projects will reference the implementation projects to expose their capabilities

ASP.NET Core

This top-level project is an ASP.NET Core app. Which is really just basically a console app using Kestrel as the HTTP server.

Dependencies

The mentioned this project will reference the Sales and Shipping projects.

This is because each implementation project must define its own configuration. Things like Dependency Injection, HTTP routing, etc.

ConfigureServices

The above example is of an extension method for defining all of the types that needed to be registered with a ServiceCollection. In the case above it’s adding the Entity Framework SalesDbContext.

This can then be used in the AspNetCore’s ConfigureServices.

ASP.NET Core

Worker

The Message Processor (Worker) is the other top-level project that is a console application. Its purpose is to connect to a message broker and dispatch the relevant messages to the implementation projects. I’ll cover message processing in other blogs/videos as the purpose of this post is simply the solution and project structure.

As you can expect, it will reference the implementation projects and use the extension methods just as the AspNetCore project does.

Generic Host

The Worker is using the Generic Host which is very similar to the WebHost from ASP.NET Core. It provides all the same goodness that you get with an ASP.NET Core app such as Dependency Injection and Logging.

In this case, I’m creating a HostedService which is a BackgroundService. This is ultimately where we would be communicating with a message broker to dispatch and handle messages within our Monolith.

Again, more on how that works in other posts (which will be linked at the bottom of this post when they are published).

Questions or Feedback

If you have any questions or comments, let me know in the comments of the YouTube video, in the comments on this post or on Twitter.

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

Migrating to .NET Core: Mission Complete

Migrating to .NET Core: Mission Complete

It’s been over 5 years since I started a greenfield project that initially was developed using Katana/Owin with ASP.NET Web API. Over the past 3 years, since .NET Core 2.0 was released and .NET Standard 2.0 was defined, I’ve been slowly chipping away at migrating to .NET Core. It’s been a long road but we’re now fully migrated and running in production with ASP.NET Core on .NET Core 3.1.

Migrating from .NET Framework to .NET Core

This blog post is in a series about migrating from .NET Framework to .NET Core.

Solution/Project Size

To give some sense of scale, our application consist of two primary entry points.

The first is an HTTP API that started out as a shelf hosted (not using IIS) Owin/Kata using ASP.NET WebAPI. Over time that morphed into using Nancy. During the migration, it ultimately moved to ASP.NET Core using the OWIN Middleware to still use Nancy.

The second entry point is a worker process that processes messages from a message broker. This is primarily for handling events and fire-and-forget commands. This has always been a console app.

To give a sense of scale, I ran NDepend over our solution to get lines of code metric, just to give some idea of the size.

Migrating to .NET Core

Journey: Migrating to .NET Core

I’ve given a full experience report on my YouTube channel. This covers pretty much everything I’ve done along with the process of getting our app running under .NET Core in production.

Questions or Feedback

If you’re thinking of doing a migration and have any questions, let me know in the YouTube comments, in the comments on this blog or on Twitter. I’d be glad to help if possible.

If you’ve done a migration and would like to share some tips, get in touch with me!

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

Getting Started: Apache Kafka with .NET Core

Getting Started with Apache Kafka & .NET Core

If you’re interested in playing around with Apache Kafka with .NET Core, this post contains everything you need to get started.

I’ve been interested in Kafka for awhile and finally sat down and got everything configured using Docker, then created a .NET console app that contained a Producer and a Consumer.

Here’s my complete process of what that involved.

YouTube

Check out my YouTube channel where I created a video that accompanies this blog post.

Docker

The first thing you need is to pull down the latest Docker images of both Zookeeper and Kafka.

Before we create any contains, first create a new network that both contains are going to use.

Now you can create both Zookeeper and Kafka containers. Kafka needs to communicate with Zookeeper. All the port mappings are the standard ports listed in the Zookeeper and Kafka docs.

Producer

Now that we have Zookeeper and Kafka containers running, I created an empty .net core console app. I’m going to create a hosted service for both Producer and Consumer.

For the producer in this demo, I’m using the Confluent.Kafka NuGet Package.

For this example, I’m going to iterate 100 times and produce a string of “Hello World {i}” that is going to be sent to a topic called “demo”.

In the constructor I’m creating a new producer and specifying that Kafka is running on localhost:9092, which is our container.

The other thing to note is that this “demo” topic I’ve created manually ahead of time, not within this code sample.

Kafka UI

If you need to create a topic, you can do so using the command line tools, or if you prefer something visual you can check out Conduktor.

Consumer

For the consumer, I decided to try the kafka-sharp NuGet Package after I saw this tweet.

The consumer follows a similar type of pattern where in the Constructor I’m creating the connection to localhost:9092. In the StartAsync is where the magic happens of subscribing to the demo topic. The MessageReceived lambda is what will handle all messages received, where I’m just logging the message value.

Full Sample

For completeness, here’s the generic host and both Producer and Consumer hosted services above.

You can find the entire sample on my GitHub.

If you’re using Kafka, which library are you using? Are you using a event/message dispatcher on top of Kafka or using it directly. Let me know in the comments or on Twitter.

Related Links

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design