我有一个使用Sqlite进行CRUD操作的数据层,所以在我的Sqlite类中我必须传递DB的路径,为此我在数据层中有接口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中创建包装器,但我不认为它会是一个好主意,因为它会创建更多的依赖项。
答案 0 :(得分:2)
执行此操作的常用方法是使用存储库模式。在ViewModel层中定义接口并在DataLayer中实现它。然后,ViewModel对DataLayer一无所知。然后通过依赖注入在主类中使用ConnectionProvider实例化Repository。 dbContext也必须移动到DataLayer,您应该在Repository中使用它。我建议将连接字符串放在配置文件中,并在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
}
同时查找依赖倒置原则,因为这有助于解耦这类问题。