10

I have been tasked to set up a guide for a microservice solution structure and find myself reflecting on why exactly I do things the way I do them. I am struggling to find an answer to the question when exactly I want to add a new project to my solution in a microservice context.

Some Microsoft articles suggest you should do so (see first picture): https://docs.microsoft.com/de-de/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice while there were discussions going somewhat into detail on this topic already, which have a different result: https://stackoverflow.com/questions/8678251/what-are-the-benefits-of-multiple-projects-and-one-solution#:~:text=If%20you%20only%20ever%20have,things%20like%20sharing%20source%20files.

It is obvious that you need to organize your code inside a solution. So there are two options: projects and namespaces. The question is: If there is no technical reason to create multiple project files - like reusability across solutions, individual deployment - why not simply organize your code with namespaces in a folder structure in your service project?

The separation of frontend and backend is separated from this. I would create different solutions for frontend and backend, unless its a very small application.

As far as I know DDD is just demanding for a logical separation of application/domain/infrastructure layers. And there is an often undervalued Clean Code Priciple: KISS - Keep it simple, stupid (make it as easy as possible, but not easier).

To be on the same page as to what a solution using multiple projects and a solution using namespaces for those projects is:

Multiple Project Solution:

Ordering.sln
|-Ordering.Infrastructure.csproj
||-MyInfrastructureClass.cs
|-Ordering.Domain.csproj
||-Order.cs
||-OrderItem.cs
|-Ordering.Application.csproj
||-CreateNewOrder.cs
|-Ordering.Service.csproj
||-Controller
|||-OrderController.cs
|-Ordering.Tests.csproj

Namespace Solution:

Ordering.sln
|-Ordering.Service.csproj
||-Application
|||-CreateNewOrder.cs
||-Controller
|||-OrderController.cs
||-Domain
|||-Order.cs
|||-OrderItem.cs
||-Infrastructure
|||-MyInfrastructureClass.cs

Pro "New Project":

  • It forces you to get your dependencies right, as long as you place your classes in the right projects.
  • Smaller/Leaner service project
  • Assemblies are reusable

Pro Namespaces:

  • No need to deploy more Assemblies than necessary
  • Smaller/Leaner solution itself
  • Less complexity in the solution

The only real benefit of the multi-project solution seems to be that the threshold for messing up dependencies is lower in the namespace solution.

My conclusion so far is:

  1. The namespace solution is better, if code reviews are done properly to make sure nobody messes up the architecture of the solution.
  2. Make new projects in the solution only if there is a technical reason for it. Such as reusing an assembly.

So my question is: What do I miss here? I did quite some research before and found people doing it because of DDD or just to organize their code. From Microsofts code snippets it almost seems like it does not matter. Sometimes its done one way, sometimes another way. But those examples are showing something the article explained, so since the purpose is not to show a good solution structure this may be the reason why.

4
  • 6
    There is one good reason why multiple projects are better than multiple namespaces alone, a reason that nobody else has mentioned yet: once a project is compiled, it need not be compiled again unless the code changes. Commented Aug 7, 2020 at 22:37
  • @RobertHarvey, unless we made change in the "core" project which all other projects depend on ;)
    – Fabio
    Commented Aug 9, 2020 at 19:46
  • So you build one program which has all the services? How does each copy of the program know which service it is?
    – user20574
    Commented Aug 10, 2020 at 15:11
  • @user253751 No, in a microservice environment you don't want to put multiple services into one project. Unless you want to host different versions of your service. That you would separate via the controller route. If you set up a new service per bounded context (DDD) and these services are exclusively for your solution, then you would set up a new project - or rather projects as we found out in this question :-) Commented Aug 10, 2020 at 15:19

3 Answers 3

4

In case you are talking about having infrastructure and business logic concerns - projects would be preferable.

  • No need to deploy more Assemblies than necessary
    I think this shouldn't matter much, unless you have hundreds of dlls.

  • Smaller/Leaner solution itself
    Solution size would be approximately same - you just replace project folders with namespace folders.

  • Less complexity in the solution
    Hmm, I would say having everything in same project will create more complexity, because now everything can access everything. It will build a ground for effective shortcuts, which lead in more complex and difficult to maintain solution.

  • The namespace solution is better, if code reviews are done properly to make sure nobody messes up the architecture of the solution
    Project structure replaces code reviews to make sure that nobody mess up the architecture :)

Projects provides clear concern separation driven by compiler - you can not have circular dependency.

We can use approach from both "worlds".
Inside same concern project we can have namespaces for different "sub-concerns". For example inside infrastructure project we can have different namespaces for Web and for Database code.
Inside business logic project we can have different namespaces for different domain areas.

Notice that I am talking about two main concerns

  • Infrastructure (web, database etc)
  • Business logic (just c# in your case)

Tests would be located in separate project, only because tests have dependencies not required in actual application.

2

In the .NET world the consensus is to have projects/(DLL-)assemblies map to namespaces. Have a look at the framework assemblies, they are all named after the namespaces they implement. This makes perfect sense because if you need some functionality, it will be grouped in some namespace and you would need to deploy the corresponding assembly.

You may have one big assembly covering multiple sub-namespaces if they are tightly coupled anyway. Like an assembly named TopSpace.SubSpace that implements TopSpace.SubSpace.A, TopSpace.SubSpace.B and TopSpace.SubSpace.C.

It is not a choice between projects or namespaces, you use them together.

2
  • You are right and that is what we all do already I think. My question aimed more towards if you should create sub-namespaces inside your project instead of new projects for logical layers of your service. I.e. DDD Application layers such as Infrastructure and Domain - why not put it in a folder of your service project for which VS will create a sub-namespace automatically? Commented Aug 7, 2020 at 20:34
  • While I agree with your point, the framework assemblies are not organized that way. Many namespaces can be found in a single assembly, and many assemblies with different names use the same namespace. In Netcore this has been improved a lot, though.
    – Abel
    Commented Aug 9, 2020 at 16:19
1

I think your reasoning is perfectly fine, the main reason why you would like to make new projects is likely to be due practical modularization.

E.g. if you're contracted by a bank which made a collaboration deal with another entity(ies) then to separate the proyects is the right thing to do (among many other considerations). If they occur to share information then be it so.

A central adventage of microservices is to give more flexibility when facing changes. Now it is a double edge sword, extreme modularization may lead to slow and carefully done maintenance (which is not good in software quality terms).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.