Recently I have found that following approach works great for many projects that I have worked on. The issue however is, that I read that ef core DbContext is a UoW by itself, and I should NOT create my own UoW and repositories. But in such case, I am unable to abstract my persistance layer from my application logic layer.
TL;DR question is: Is it possible to NOT to have own repositories nor own UoW and still follow the mentioned architecture with DbContext as UoW?
My architecture is like follows:
Layer 1 (most inner): Aggregates, Entities, POCO domain classes, Value Objects
Layer 2: Domain services
Layer 3: Application services (CQRS commands, queries, handlers) and Repository Interfaces
Layer 4A: (persistance layer) Repositories implementation (DbContext injected here) EF Core mappings (ORM mappings)
Layer 4B: Asp MVC API (DI registered here)
Controllers of API just issues commands and queries (via MediatR).
The advantage of above approach is that the app core (layers 1, 2 and 3) are completely abstracted from persistance. The disadvantage is that you really have to write your own Repositories.
Is it correct approach? Or am I missing something?
Why is a DbContext is a unit of work?
The DbContext captures all changes that you are making within one single transaction via one single commit (SaveChanges).
Why shouldn't you create your own?
Ideally, you should only be committing to one single data store via one single transaction. If you are either saving to multiple data stores in multiple transactions or saving to the same data store in several transactions, then you face the likely possibility of data corruption. If you are using a distributed transaction across multiple data stores, well then God help you.
SaveChanges should therefore be sufficient, so why create your own?
But what about abstraction?
If SaveChanges is sufficient, then how do we abstract out our dependency on EF? You can introduce an IUnitOfWork interface with a single method, Commit, which you can implement by calling DbContext.SaveChanges.
And repositories?
I am not sure I understand not creating Repositories as a hard rule. As part of abstracting out your persistence layer, it is helpful to have a layer such as IRepository to provide that separation. That said, you should not be creating a repository per table. A repository per Aggregate is more appropriate. Each repository will load the entire Aggregate to ensure consistency within the boundary of the Aggregate.
...
In general, I would caution against following advice that speaks in absolutes if you don't understand the reasoning behind that advice. You should be able to formulate the same conclusion given the same starting information for yourself. Otherwise, you are just applying rote memorization to a pattern that does not always benefit from that approach.