It might be that this question was already discussed and answered, and I just can't find proper link. The question is: how to properly implement 3 layers (Presentation, Business Logic, Data Access) with repositories and DI.
"Usual 3-layer architecture":
"Correct 3-layer architecture (or clean architecture)":
This way our BL is self-contained, and doesn't have any dependencies on UI or DAL, which is good.
And I want to implement a Repository to have another abstraction over data storage. In this case I have IRepository interface in BL, everything in BL is programmed against this generic interface. Implementation(s) of the interface is in DAL. The question which comes up is how to register repositories, if my composition root (place, where I register dependencies) is in Presentation layer, because it's where my application actually starts. But it doesn't have a reference to DAL. Options are:
The problem is that a lot of articles on the internet actually show pictures like in this question, but then in their code have this reference from Presentation to DAL, which is misleading. Example: https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures (figure 5-9 says it's a runtime dependency, but in their code https://github.com/dotnet-architecture/eShopOnWeb it's a reference)
It's okay if the Presentation has a reference to the DAL (in clean architecture, most often this layer is called Infrastructure) in order to properly register dependencies in the DI. The main thing is to ensure that classes implemented in the Infrastructure (DAL) are not used anywhere else in the Presentation layer (usually this is controlled at the time of the merge pull request, as well as specifying the access modifier (internal) for classes in the Infrastructure).
There is a great example of implementing a clean architecture in .NET by Jason Taylor.