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

如何避免在表示层中直接引用数据访问层?

如何避免表示层直接引用数据层

你的问题核心在于数据层定义的IConnectionProvider接口迫使表示层必须引用数据层,打破了Data Layer -> View Model -> Presentation Layer的依赖方向。下面是两种干净的解决方案,完全不需要在表示层引用数据层:

方案一:将抽象接口移到共享核心层(推荐)

这是最符合依赖倒置原则的做法,把所有跨层的抽象定义放到一个独立的核心/契约层,让所有层都依赖这个核心层,而不是互相依赖。

具体步骤:

  1. 创建共享核心项目
    新建一个类库项目(比如命名为MyApp.Core或MyApp.Contracts),把IConnectionProvider接口移到这里:

    namespace MyApp.Core;
    public interface IConnectionProvider 
    { 
        string DbPath { get; } 
    }
    
  2. 修改数据层依赖
    让你的数据层项目引用这个核心层,更新SQLiteDb的代码,依赖核心层的接口:

    using MyApp.Core;
    public class SQLiteDb : DbContext, IDbContext 
    { 
        internal const string DefaultDatabaseName = "My.db"; 
        private readonly string connectionString;
    
        public SQLiteDb(IConnectionProvider connectionProvider) 
        { 
            connectionString = connectionProvider.DbPath; 
        } 
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
        { 
            optionsBuilder.UseSqlite(connectionString); 
        } 
    }
    
  3. 表示层实现核心层接口
    表示层项目只需要引用核心层,实现核心层的IConnectionProvider,完全不用碰数据层:

    using MyApp.Core;
    public class SqlConnectionProvider : IConnectionProvider 
    { 
        private string dbPath = string.Empty; 
        public string DbPath 
        { 
            get 
            { 
                if (string.IsNullOrEmpty(dbPath)) 
                { 
                    dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MyDb.sqlite"); 
                } 
                return dbPath; 
            } 
        } 
    }
    
  4. 依赖注入注册
    在你的项目启动入口(比如MAUI的MauiProgram.cs、WPF的App.xaml.cs)注册这个实现,让DI容器把它注入到数据层:

    builder.Services.AddSingleton<IConnectionProvider, SqlConnectionProvider>();
    builder.Services.AddScoped<IDbContext, SQLiteDb>();
    

方案二:在ViewModel层定义接口(小型项目可选)

如果不想新增核心项目,也可以把IConnectionProvider定义在ViewModel层:

  • ViewModel层定义IConnectionProvider接口
  • 数据层引用ViewModel层,依赖这个接口
  • 表示层引用ViewModel层,实现接口

这种方式虽然不用新增项目,但会让数据层依赖ViewModel层(上层),不符合严格的依赖倒置原则,适合小型项目快速解决问题。

为什么不推荐ViewModel包装类?

你提到的ViewModel包装类确实会增加额外的依赖和冗余代码——相当于在ViewModel层再套一层抽象,反而让架构更复杂,不如直接把抽象提到共享层或ViewModel层来得简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:49:56