jasontaylordev / CleanArchitecture

Clean Architecture Solution Template for ASP.NET Core

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Making the Application layer independent of any specific technology or external library.

shahabfar opened this issue · comments

Adding a reference to Microsoft.EntityFrameworkCore in the Application layer can make it dependent on an external library, which is generally not recommended in Clean Architecture. The goal of Clean Architecture is to make the Application layer independent of any specific technology or external library.

One way to avoid this is to use the Dependency Inversion Principle. Instead of directly using DbContext in your IApplicationDbContext interface ( DbSet in your case), you can define your interfaces in the Application layer for the repositories that you need. These interfaces should include the methods that your application needs to interact with the database.

Then, in the Infrastructure layer, you can create implementations of these interfaces that use DbContext. This way, the Application layer isn’t directly dependent on Microsoft.EntityFrameworkCore; instead, it depends on abstractions that are implemented in the Infrastructure layer.

No external libraries in the application layer? So you want to remove FluentValidation, Mediatr and so on too?

You could of course abstract away the DbSet for a repository, but then you are adding a repository upon a repository... also you gotta implement your own UnitOfWork on top of your repositories. Remember that the DbSet already is a repository and the DbContext already is a UnitOfWork. Seems a lot of boilerplate code for nothing.

This doesn’t mean that you can’t use external libraries in the Application layer. Libraries that help implement application-level concerns, such as MediatR for mediating command/query handlers or FluentValidation for validation, are often used in the Application layer.

As for abstracting away the DbSet for a repository, you’re correct that DbSet and DbContext already provide repository and unit of work patterns, respectively. Adding another layer of abstraction can lead to more boilerplate code without much benefit, especially if you’re using Entity Framework Core which already implements these patterns.

However, abstracting the database access into a repository can still be beneficial in some cases. For example, it can make your application easier to test, as you can mock the repository interface. It can also make it easier to switch to a different database technology in the future, as the repository interface would remain the same.

I've created an architecture decision record for this topic: https://github.com/jasontaylordev/CleanArchitecture/wiki/ADR-001-Use-EFCore-In-Application-Layer. Feel free to suggest any changes.