.NET Core中Clean/Onion架构依赖关系及eShopOnWeb实现疑问
Great questions—let’s unpack these concepts to clear up any confusion.
What exactly does "dependency" mean in the context of Clean/Onion architecture?
When Microsoft docs state "outer layers depend inward," they’re referring to compile-time dependencies and dependency direction, not just runtime object instantiation. Here’s a breakdown:
- Compile-time dependencies: A project or module can only reference types from layers closer to the center. For example, your Infrastructure layer can reference the Core layer, but the Core layer can never reference Infrastructure or UI layer types.
- Code-level dependencies: If a class in an outer layer uses a class from the Core, that’s allowed. But if a Core class tried to directly use an outer-layer class, that would break the rule—because the Core would now depend on an external, changeable layer.
- Abstractions over concretions: The core pattern here is defining interfaces in the Core layer to outline what the application needs, then having outer layers implement those interfaces. This way, the Core only depends on its own abstractions, not concrete implementations from outer layers.
Why does the eShopOnWeb repo have Infrastructure implementing Core repositories—and is that a contradiction?
This is not a contradiction—it’s actually the textbook implementation of Clean/Onion architecture! Here’s why it works:
- Core defines the contract: The Core layer declares repository interfaces (like
IProductRepository) that describe the data operations the application’s business logic requires. These interfaces live in the Core because they’re tied to domain rules, not how data is stored. - Infrastructure provides the implementation: The Infrastructure layer takes those Core interfaces and builds concrete implementations (like
EfCoreProductRepositoryusing Entity Framework Core). Since Infrastructure is an outer layer, it can safely reference the Core to implement its interfaces. - Dependency injection bridges the gap: At runtime, your app uses dependency injection to inject the concrete Infrastructure implementation into Core services that depend on the repository interface. The Core never interacts directly with EF Core-specific code—it only uses the interface it defined.
This approach keeps your Core layer completely decoupled from external concerns like databases. You could swap the EF Core implementation for a MongoDB one tomorrow, and the Core layer wouldn’t need any changes—you’d just write a new MongoProductRepository in Infrastructure and update your DI configuration.
内容的提问来源于stack exchange,提问作者Jon Sherman

