百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

ABP vNext框架文档解读14-仓储(word文档里怎么做组织框架图)

ccwgpt 2024-09-20 13:35 35 浏览 0 评论

仓储

"在领域层和数据映射层之间进行中介,使用类似集合的接口来操作领域对象." (Martin Fowler).

实际上,仓储用于领域对象在数据库中的操作, 通常每个 聚合根 或不同的实体创建对应的仓储.

通用(泛型)仓储

ABP为每个聚合根或实体提供了 默认的通用(泛型)仓储 . 你可以在服务中注入 IRepository<TEntity, TKey> 使用标准的CRUD操作.

public class PersonAppService : ApplicationService
{
    private readonly IRepository<Person, Guid> _personRepository;

    public PersonAppService(IRepository<Person, Guid> personRepository)
    {
        _personRepository = personRepository;
    }

    public async Task Create(CreatePersonDto input)
    {
        var person = new Person { Name = input.Name, Age = input.Age };

        await _personRepository.InsertAsync(person);
    }

    public List<PersonDto> GetList(string nameFilter)
    {
        var people = _personRepository
            .Where(p => p.Name.Contains(nameFilter))
            .ToList();

        return people
            .Select(p => new PersonDto {Id = p.Id, Name = p.Name, Age = p.Age})
            .ToList();
    }
}
  • PersonAppService 在它的构造函数中注入了 IRepository<Person, Guid> .
  • Create 方法使用了 InsertAsync 创建并保存新的实体.
  • GetList 方法使用标准LINQ WhereToList 方法在数据源中过滤并获取People集合.
  • 了解如何使用 异步扩展方法, 如 ToListAsync() (建议始终使用异步) 而不是 ToList()
  • 上面的示例在实体DTO之间使用了手动映射. 可以了解自动映射的使用方式.

通用仓储提供了一些开箱即用的标准CRUD功能:

  • 提供 Insert 方法用于保存新实体.
  • 提供 UpdateDelete 方法通过实体或实体id更新或删除实体.
  • 提供 Delete 方法使用条件表达式过滤删除多个实体.
  • 实现了 IQueryable<TEntity>, 所以你可以使用LINQ和扩展方法 FirstOrDefault, Where, OrderBy, ToList 等...
  • 所有方法都具有 sync(同步)async(异步) 版本.

基础仓储

IRepository<TEntity, TKey> 接口扩展了标准 IQueryable<TEntity> 你可以使用标准LINQ方法自由查询.但是,某些ORM提供程序或数据库系统可能不支持IQueryable接口.

ABP提供了 IBasicRepository<TEntity, TPrimaryKey>IBasicRepository<TEntity> 接口来支持这样的场景. 你可以扩展这些接口(并可选择性地从BasicRepositoryBase派生)为你的实体创建自定义存储库.

依赖于 IBasicRepository 而不是依赖 IRepository 有一个优点, 即使它们不支持 IQueryable 也可以使用所有的数据源, 但主要的供应商, 像 Entity Framework, NHibernate 或 MongoDb 已经支持了 IQueryable.

因此, 使用 IRepository 是典型应用程序的 建议方法. 但是可重用的模块开发人员可能会考虑使用 IBasicRepository 来支持广泛的数据源.

只读仓储

对于想要使用只读仓储的开发者,提供了IReadOnlyRepository<TEntity, TKey>IReadOnlyBasicRepository<Tentity, TKey>接口.

无主键的通用(泛型)仓储

如果你的实体没有id主键 (例如, 它可能具有复合主键) 那么你不能使用上面定义的 IRepository<TEntity, TKey>, 在这种情况下你可以仅使用实体(类型)注入 IRepository<TEntity>.

IRepository<TEntity> 有一些缺失的方法, 通常与实体的 Id 属性一起使用. 由于实体在这种情况下没有 Id 属性, 因此这些方法不可用. 比如 Get 方法通过id获取具有指定id的实体. 不过, 你仍然可以使用IQueryable<TEntity>的功能通过标准LINQ方法查询实体.

自定义仓储

ABP不会强制你实现任何接口或从存储库的任何基类继承. 它可以只是一个简单的POCO类. 但是建议继承现有的仓储接口和类, 获得开箱即用的标准方法使你的工作更轻松.

首先在领域层定义一个仓储接口:

public interface IPersonRepository : IRepository<Person, Guid>
{
    Task<Person> FindByNameAsync(string name);
}

此接口扩展了 IRepository<Person, Guid> 以使用已有的通用仓储功能.

自定义存储库依赖于你使用的数据访问工具. 在此示例中, 我们将使用Entity Framework Core:

public class PersonRepository : EfCoreRepository<MyDbContext, Person, Guid>, IPersonRepository
{
    public PersonRepository(IDbContextProvider<TestAppDbContext> dbContextProvider) 
        : base(dbContextProvider)
    {

    }

    public async Task<Person> FindByNameAsync(string name)
    {
        return await DbContext.Set<Person>()
            .Where(p => p.Name == name)
            .FirstOrDefaultAsync();
    }
}

IQueryable & 异步操作

IRepository 继承自 IQueryable,这意味着你可以直接使用LINQ扩展方法.

但在你使用标准的应用程序启动模板时会发现无法在应用层或领域层使用这些异步扩展方法,因为:

  • 这里异步方法不是标准LINQ方法,它们定义在Microsoft.EntityFrameworkCoreNuget包中.
  • 标准模板应用层与领域层不引用EF Core 包, 以实现数据库提供程序独立.

强烈建议使用异步方法! 在执行数据库查询时不要使用同步LINQ方法,以便能够开发可伸缩的应用程序.

根据你的需求和开发模式,你可以根据以下选项使用异步方法:

1: 引用EF Core

最简单的方法是在你想要使用异步方法的项目直接引用EF Core包.

添加Volo.Abp.EntityFrameworkCore NuGet包到你的项目间接引用EF Core包. 这可以确保你的应用程序其余部分兼容正确版本的EF Core.

如果使用的是MongoDB,则需要将[Volo.Abp.MongoDB] NuGet包添加到项目中. 但在这种情况下你也不能直接使用异步LINQ扩展(例如ToListAsync),因为MongoDB不提供 IQueryable<T>的异步扩展方法,而是提供 IMongoQueryable<T>. 你需要先将查询强制转换为 IMongoQueryable<T> 才能使用异步扩展方法.

2: 自定义仓储方法

你始终可以创建自定义仓储方法并使用特定数据库提供程序的API,比如这里的异步扩展方法.

此方法建议;

  • 如果你想完全隔离你的领域和应用层和数据库提供程序.
  • 如果你开发可重用的应用模块,并且不想强制使用特定的数据库提供程序,这应该作为一种最佳实践.

3: IAsyncQueryableExecuter

IAsyncQueryableExecuter 是一个用于异步执行 IQueryable<T> 对象的服务,不依赖于实际的数据库提供程序.

示例: 注入并使用 IAsyncQueryableExecuter.ToListAsync() 方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;

namespace AbpDemo
{
    public class ProductAppService : ApplicationService, IProductAppService
    {
        private readonly IRepository<Product, Guid> _productRepository;
        private readonly IAsyncQueryableExecuter _asyncExecuter;

        public ProductAppService(
            IRepository<Product, Guid> productRepository,
            IAsyncQueryableExecuter asyncExecuter)
        {
            _productRepository = productRepository;
            _asyncExecuter = asyncExecuter;
        }

        public async Task<ListResultDto<ProductDto>> GetListAsync(string name)
        {
            //Create the query
            var query = _productRepository
                .Where(p => p.Name.Contains(name))
                .OrderBy(p => p.Name);

            //Run the query asynchronously
            List<Product> products = await _asyncExecuter.ToListAsync(query);

            //...
        }
    }
}

ApplicationServiceDomainService 基类已经预属性注入了 AsyncExecuter 属性,所以你可直接使用.

ABP框架使用实际数据库提供程序的API异步执行查询.虽然这不是执行查询的常见方式,但它是使用异步API而不依赖于数据库提供者的最佳方式.

值对象

  • TODO

领域服务

  • TODO

规约

  • TODO

相关推荐

Spring WebFlux vs. Spring MVC(springboot是什么)

背景随着异步I/O和Netty等框架的流行,响应式编程逐渐走入大众的视野。但是,响应式编程本身并不是太新的概念,这个术语最早出现在1985年DavidHarel和AmirPnue...

深度解析微服务高并发:适配SpringMVC框架适配模块及实现原理

适配主流框架如果不借助Sentinel提供的适配主流框架的模块,则在使用Sentinel时需要借助try-catchfinally将要保护的资源(方法或代码块)包起来,在目标方法或代码块执行之前,调...

Spring MVC 底层原理深度解析:从请求到响应的全链路拆解

一、Servlet容器与DispatcherServlet的启动博弈1.Tomcat初始化阶段java//Tomcat初始化流程StandardContext#startInterna...

改造总结之传统SpringMVC架构转换为SpringBoot再到集群

改造出发点,是基于现在服务都在向上云的目标前进,传统SpringMVC难以满足项目持续构建、服务节点任意扩展的需求,所以开始了历史项目的改造。项目改造考虑的主要是兼容以前的业务代码,以及session...

SpringBoot3 整合 Spring MVC 全解析:开启高效 Web 开发之旅

在当今的JavaWeb开发领域,Spring框架家族无疑占据着重要的地位。其中,SpringBoot3和SpringMVC更是开发者们构建强大、高效Web应用的得力工具。今天,...

一文读懂SpringMVC(一文读懂!残疾人低保边缘家庭能领的超实用福利政策)

1.SpringMVC定义1.1.MVC定义Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据View(视图):是应用程序中处理数据显示的部分。通常...

69 个Spring mvc 全部注解:真实业务使用案例说明(必须收藏)

SpringMVC框架的注解为Web开发提供了一种简洁而强大的声明式方法。从控制器的定义、请求映射、参数绑定到异常处理和响应构建,这些注解涵盖了Web应用程序开发的各个方面。它们不仅简化了编码工作,...

Spring MVC工作原理:像拼积木一样构建Web应用

SpringMVC工作原理:像拼积木一样构建Web应用在Java的Web开发领域,SpringMVC无疑是一个让人又爱又恨的存在。它像一位神通广大的积木搭建大师,将一个个分散的功能模块巧妙地拼接在...

5千字的SpringMVC总结,我觉得你会需要

思维导图文章已收录到我的Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary概述SpringMVC再熟悉不过的框架了,因为现在最火的...

SpringMVC工作原理与优化指南(springmvc工作原理和工作流程)

SpringMVC工作原理与优化指南在现代Java开发中,SpringMVC无疑是构建Web应用程序的首选框架之一。它以其优雅的设计和强大的功能吸引了无数开发者。那么,SpringMVC究竟是如何工作...

Spring MVC框架源码深度剖析:从入门到精通

SpringMVC框架源码深度剖析:从入门到精通SpringMVC框架简介SpringMVC作为Spring框架的一部分,为构建Web应用程序提供了强大且灵活的支持。它遵循MVC(Model-V...

3000字搞明白SpringMVC工作流程、DispatcherServlet类、拦截器!

SpringMVC基础虽然SpringBoot近几年发展迅猛,但是SpringMVC在Web开发领域仍然占有重要的地位。本章主要讲解SpringMVC的核心:DispatcherServlet类...

多年经验大佬用2000字透彻解析SpringMVC的常用注解及相关示例

SpringMVC注解SpringMVC框架提供了大量的注解,如请求注解、参数注解、响应注解及跨域注解等。这些注解提供了解决HTTP请求的方案。本节主要讲解SpringMVC的常用注解及相关示例...

知乎热议:如何成为前端架构师,赚百万年薪?

作者|慕课网精英讲师双越最近有一条知乎热议:从一个前端工程师,如何根据目标,制定计划,才能快速进阶成为前端架构师?不久之前我参与了一次直播,讲到了自己对于Web前端架构师的理解。架构师这个角色...

学习笔记-前端开发架构设计(前端架构设计方案)

前端开发的技术选项主要包含以下几点,下面对一些名词概念的解释做了笔记:1、分层架构:把功能相似,抽象级别相近的实现进行分层隔离优势:松散耦合(易维护,易复用,易扩展)常见分层方式:MVC,MVVM2、...

取消回复欢迎 发表评论: