Clean Architecture 101. Create new solution in .NET CORE!
Today we will set up a project from scratch using the Clean Architecture model. We will start by adding proper projects to represent solution layers. Then we will add references between them, determining direction of communication. We will finish by adding folders for the code that will appear in the next post and removing unnecessary files.
Clean Architecture solution
We gonna use shell (i.e. PowerShell) and the .NET Core CLI. Of course all operations can be performed from the GUI, but the terminal is just faster and more effective (#hacker). I would like to note that I am using Windows.
Let’s create a folder where our application will be placed.
Now, using .NET Core CLI, we will add a solution, which is a container for projects.
Then we create two folders and move immediately to the first one — it will contain our application, the second one is for tests.
Projects in Clean Architecture
Let’s create three projects (representing layers). Two of them will be of classlib type, and one will be a webAPI. The last one will be the entry point to the application — the StartUp Project.
-n “name” — this option determines how the project should be named
-f “framework” — set the platform version, for example netcoreapp3.1 is .NET CORE 3.1
-no-restore — after creating project, dependencies will not be downloaded (no dotnet restore will be performed)
The next step is to add projects to the soloution. After this, every time we open MyCleanArchitecture.sln in Visual Studio, our projects will be loaded.
Now we point out references between projects. In this way, we set the direction of communication.
Directories for code
And now some folders for our classes and a description of what they are designed for.
Interfaces — are abstract contracts that will be implemented in specific services. The most important thing is that not all of them will be implemented in this layer, because they may depend on the environment or application version. Examples:
- IDriversLicenseService.cs — where we define methods like HandleDriversLicenseApplication
- RevokeDriversLicenseINotificationService — we will implement it only in the Infrastructure layer where, depending on the environment (production/development), we will send an email or an sms. This allows us to include “notify the person applying for a driver’s license” in the domain logic without the need to bind to a specific service
- Entities — all entities that exist in our domain, representations of real entities. Example: DriversLicense.cs, DriversLicenseApplication.cs, Driver.cs
- Exceptions — does not require explanation. Example: UnderAgeDriverException.cs
- Services — specific implementations of the abovementioned interfaces. Example: DriversLicenseService.cs (:IDriversLicenseService.cs)
- Specifications— classes containing definition of elements of the model are to be retrieved, how they are to be filtered, etc. Generally an implementation of Specification Patern. Example: DriverWithLicenseSpecification.cs
- Configs— all entity relationship configurations will take place here. Instead of using the EntityFramework annotations on the data model (ApplicationCore), we will use the Fluent API. Example: DriverConfiguration.cs which will contain entries about entity relationships Drivers
- Migrations— code generated by EntityFramework, which contains descriptions of the changes to the database model
- Services— implementations of interfaces, we will find here mainly database access and notification services. Example: NotificationService (implementing INotificationService from domain layer) that is our notification manager (email, sms or phone)
And now it’s time to finalize our efforts. We download the required libraries and build the solution
⭐BONUS CONTENT⭐
Created folders will not be visible in the soluion until we add a file to them, or attach them in proper projects. The easiest way to do it is to edit *.csproj file (e.g. ApplicationCore.csproj) and add tags <Folder Include=”Entities” /> as below:
In addition, in WebApi\Properties\launchSettings.json modify the following lines:
on (both in the “IIS Express” and “WebApi” profiles)
Next, we can remove the sample classes from the projects. To do this from the src folder we run:
Because git doesn’t support adding empty folders, I added emptyFile.txt to each of those folders. I did it just to make it easier for you to see what I mean. You can also find the whole script on the repo, so you’re very WELCOME!
Summary
We have successfully made the first step towards a better tomorrow for our code! We created projects, added dependencies between them and added folders for our classes. Most importantly, we know where the next elements will be placed!