You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于依赖倒置原则(DIP):.NET项目中领域与数据访问层依赖方向的困惑

关于依赖倒置原则(DIP)与领域层、数据访问层依赖方向的困惑解答

首先得明确:你说的“依赖接口而非具体实现”确实是DIP的常见实践,但DIP的核心本质是反转依赖方向——让高层模块(领域层)主导抽象定义,低层模块(数据访问层)去适配这个抽象,而不是高层依赖低层的具体实现。

你在.NET项目里觉得“领域层必须依赖数据访问层”,其实是陷入了常规的依赖思维,用DIP可以完全反转这个方向,具体操作分三步:

  • 在领域层定义仓储接口,比如:

    // 领域层代码
    public interface IOrderRepository
    {
        void SaveOrder(Order order);
        Order GetOrderById(Guid orderId);
    }
    

    领域层的业务逻辑只依赖这个接口,完全不用知道数据访问层的任何细节,比如你用EF Core还是Dapper。

  • 在数据访问层实现这个接口,这时候数据访问层需要引用领域层项目(因为要实现领域层的接口),比如:

    // 数据访问层代码
    public class EfCoreOrderRepository : IOrderRepository
    {
        private readonly AppDbContext _dbContext;
    
        public EfCoreOrderRepository(AppDbContext dbContext)
        {
            _dbContext = dbContext;
        }
    
        public void SaveOrder(Order order)
        {
            _dbContext.Orders.Update(order);
            _dbContext.SaveChanges();
        }
    
        public Order GetOrderById(Guid orderId)
        {
            return _dbContext.Orders.Find(orderId);
        }
    }
    
  • 在应用启动环节(比如ASP.NET Core的Program.cs),通过依赖注入注册实现与接口的映射:

    builder.Services.AddScoped<IOrderRepository, EfCoreOrderRepository>();
    

    这样领域层在需要仓储时,直接通过构造函数注入IOrderRepository即可,完全不用关心具体是哪个实现类。

这么做之后,依赖方向就变成了数据访问层依赖领域层,而非领域层依赖数据访问层,完全符合DIP的要求:

  1. 高层模块(领域层)和低层模块(数据访问层)都依赖抽象(IOrderRepository);
  2. 抽象(接口)不依赖细节(EF Core的DbContext、具体存储逻辑),细节依赖抽象。

你之前觉得“领域层要向仓储发送数据必须依赖数据访问层”,其实是混淆了“依赖接口”和“依赖具体实现”——领域层只需要依赖自己定义的接口,数据发送的具体逻辑由数据访问层来完成,领域层根本不需要知道数据访问层的存在。

内容的提问来源于stack exchange,提问作者Francisco Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:25:08