首页 > 解决方案 > 如何避免在表示层使用数据访问层?

问题描述

我有一个使用 Sqlite 进行 CRUD 操作的数据层,所以在我的 Sqlite 类中我必须传递数据库的路径,为此我IConnectionProvider在数据层中有如下接口:

public interface IConnectionProvider
 {
        string DbPath { get; }
 }

SqliteDb.cs

public class SQLiteDb : DbContext, IDbContext
    {
        internal const string DefaultDatabaseName = "My.db";

        private string connectionString = null;

        public SQLiteDb(IConnectionProvider connectionProvider)
        {
            this.connectionString = connectionProvider.DbPath;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite(connectionString);
        }
    }

我的项目架构如下:

 Data Layer -> View Model -> Presentation Layer

我想避免将数据层直接用于表示层,但要传递 DBPath,我必须添加它的引用。

以下是IConnectionProvider我的表示层中的实现:

public class SqlConnectionProvider : IConnectionProvider
    {
        public string dbPath = string.Empty;
        public string DbPath
        {
            get
            {
                if (string.IsNullOrEmpty(dbPath))
                {
                    dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MyDb.sqlite");
                }

                return dbPath;
            }
        }
  }

有什么办法可以避免直接在表示层中使用 DataLayer 吗?我想在 VM 中创建包装器,但我认为这不是一个好主意,因为它会创建更多的依赖项。

标签: c#design-patternsninject

解决方案


执行此操作的常用方法是使用存储库模式。在 ViewModel 层中定义一个接口并在 DataLayer 中实现它。然后 ViewModel 对 DataLayer 一无所知。然后通过依赖注入在主类中使用 ConnectionProvider 实例化存储库。dbContext 也必须移动到 DataLayer,您应该在存储库中使用它。我建议将连接字符串放在配置文件中并在 DL 中使用它。这些类应该看起来像这样

namespace ViewModel;
interface IDatabaseRepository {
   DataObject LoadData()
}

namespace DataLayer;
class DataRepository {
   public DataRepository(DbContext context) {
      this.context = context;
   }

   public DataObject LoadData() {
      //load data from DB using dbContext
   }
}

namespace ViewModel;
class ViewModel {
   public ViewModel(IDataRepository repository) {
      this.repository = repository;
   }

   // use the repository inside this class to acces data
}

还要查找依赖倒置原则,因为这有助于解耦这样的事情。


推荐阅读