ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

大话领域驱动设计——基础设施层

2022-06-12 17:06:21  阅读:211  来源: 互联网

标签:await 基础设施 自定义 大话 实体 默认 仓储 驱动 数据库


1. 概述

基础设施层是整个系统的⽀持层,通过对第三⽅类库的调⽤或系统的抽象和集成来实现对其他层的⽀持。

与传统架构不同在DDD中,数据库访问的具体实现(仓储)也被放在了基础设施层。

在DDD的理念中,基础设施层是为领域和用例的逻辑实现提供支撑。在前面的章节我也提到,在DDD的理念中,数据访问具体实现不是设计过程需要关注的重点,所以将具体访问数据库的代码放在了基础设施层。

2. 概览

通常情况下,我们会将提供数据服务连接的相关类和方法存放于一个项目中,而将其他公共类,公共方法存放于另外的一个或多个项目中。这些自定义的公共类库,这里我就不具体讲述,请依据个人项目需要来进行规划设计。

基础设施层数据库连接服务主要包含以下组件:

  仓储(Repository)实现:对领域层定义的仓储接口的实现类,用户封装对领域对象的数据持久化操作的具体实现。

在ABP框架下,基础设施层提供数据库访问的类库包含应用程序的数据库上下文(DbContext)、数据库映射、仓储的实现等信息。依据项目需要,我们可以通过CLI中的 -d 参数来选择使用EF Core或者MongoDB,分别会包含以下两个类库:

  • EntityFrameworkCore:是EF Core的基本集成包,支持SQL Server、MySQL、SQLite、Oracle、PostgreSQL数据库。默认使用SQL Server数据库。
  • MongoDB:以MongoDB为数据库的基础设施层类库。

3. 实现细节

3.1. 默认仓储

ABP提供了用于实体增删改查的默认仓储接口和实现类,在大多数情况下,我们只需要直接注入使用默认仓储 IRepository<TEntity, TKey> 即可,其中TEntity为需要操作的实体,TKey为该实体主键的数据类型。

使用默认仓储时,需要在EntityFrameworkCore项目的Module类中的 ConfigureServices 方法中加入以下代码用于给所有实体创建默认仓储:

 context.Services.AddAbpDbContext<MyDbContext>(options =>
        {
            options.AddDefaultRepositories(includeAllEntities: true);
        });

其中 MyDbContext 为当前项目的数据上下文, includeAllEntities 参数为true时会给所有实体、聚合根创建默认仓储,如果为false则只给聚合根创建默认仓储。

在默认仓储中,ABP提供了以下方法可供直接操作数据库:

  • GetAsync:通过lambda 表达式查询单个实体,如果存在多个满足条件的实体,则抛出 InvalidOperationException 异常。
  • FindAsync:通过lambda 表达式查询单个实体,如果存在多个满足条件的实体,则抛出 InvalidOperationException 异常。
  • InsertAsync:添加实体。
  • InsertManyAsync:批量添加。
  • UpdateAsync:更新实体。
  • UpdateManyAsync:批量修改。
  • DeleteAsync:删除实体,也可根据Lambda表达式删除。
  • DeleteManyAsync:批量删除。
  • GetListAsync:获取数据库中所有实体的列表。
  • GetPagedListAsync:分页获取实体集合。
  • GetCountAsync:获取数据库中所有实体的计数。

GetAsync方法和FindAsync方法的区别为:如果实体未找到,GetAsync抛出 EntityNotFoundException 异常,而FindAsync方法返回 null 
在很多情况下,我们希望获取 IQueryable 类型用于自定义Linq查询,在ABP 5.0版本之后,获取IQueryable方式改为 await _personRepository.GetQueryableAsync(); 

3.2. 自定义仓储

如果默认仓储不能满足我们的需求,我们可以自定义仓储接口和实现。

自定义仓储接口声明存放与领域层,可继承自 IRepository<TEntity, TKey> ,其实现类存放与基础设施层,继承自 EfCoreRepository<TDbContext, TEntity, TKey> 或 MongoDbRepository<TDbContext, TEntity, TKey> 

3.3. Dapper集成

在一些情况下,我们希望可以使用自定义的SQL语句进行更灵活的数据库操作或者执行存储过程调用等操作,而Dapper框架可以满足我们需求。

在ABP,Dapper框架并被没有完整的集成,而是依托于EF Core实现。也就意味着如果要使用Dapper,创建项目时,数据访问对象依旧选择EF Core。

当使用Dapper时,我们需要创建自定义仓储,并将其实现类继承自 DapperRepository<TDbContext> ,其中TDbContext为EF Core项目的数据上下文。

具体用法,我们可以参考官方提供的示例:

public class PersonDapperRepository : DapperRepository<MyAppDbContext>, ITransientDependency
{
    public PersonDapperRepository(IDbContextProvider<MyAppDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }

    public virtual async Task<List<string>> GetAllPersonNames()
    {
        var dbConnection = await GetDbConnectionAsync();
        return (await dbConnection.QueryAsync<string>("select Name from People", transaction:  await GetDbTransactionAsync()))
            .ToList();
    }

    public virtual async Task<int> UpdatePersonNames(string name)
    {
        var dbConnection = await GetDbConnectionAsync();
        return await dbConnection.ExecuteAsync("update People set Name = @NewName", new { NewName = name },
             await GetDbTransactionAsync());
    }
}

 


 

 

同时

标签:await,基础设施,自定义,大话,实体,默认,仓储,驱动,数据库
来源: https://www.cnblogs.com/zklight/p/16344759.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有