美文网首页ABP
ABP入门系列(3)——领域层定义仓储并实现

ABP入门系列(3)——领域层定义仓储并实现

作者: 圣杰 | 来源:发表于2017-01-07 14:29 被阅读10522次

    ABP入门系列目录——学习Abp框架之实操演练
    源码路径:Github-LearningMpaAbp


    一、先来介绍下仓储

    仓储(Repository): 仓储用来操作数据库进行数据存取。仓储接口在领域层定义,而仓储的实现类应该写在基础设施层。

    在ABP中,仓储类要实现IRepository接口,接口定义了常用的增删改查以及聚合方法,其中包括同步及异步方法。主要包括以下方法:

    IRepository接口定义的方法

    ABP针对不同的ORM框架对该接口给予了默认的实现;
    针对EntityFramework,提供了EfRepositoryBase<TDbContext, TEntity, TPrimaryKey>的泛型版本的实现方式。
    针对NHibernate,提供了NhRepositoryBase<TEntity, TPrimaryKey>的泛型版本的实现方式。

    泛型版本的实现就意味着,大多数的时候,这些方法已足已应付一般实体的需要。如果这些方法对于实体来说已足够,我们便不需要再去创建这个实体所需的仓储接口/类。

    直接通过在应用服务层定义仓储引用,然后通过构造函数注入即可。在我们的应用服务层即可按以下方式使用Task仓储:

    public class TaskAppService : ITaskAppService { 
    private readonly IRepository<Task> _taskRepository; 
    public TaskAppService(IRepository<Task> taskRepository) 
    { 
        _taskRepository = taskRepository; 
    }
    

    示例代码中使用的就是这种方式。

    二、如何实现自定义仓储

    假设我们需要查找某个用户都分配哪些任务。

    1. 在领域层,创建IRepositories文件夹,然后定义IBackendTaskRepository。
    namespace LearningMpaAbp.IRepositories
    {
        /// <summary>
        /// 自定义仓储示例
        /// </summary>
        public interface IBackendTaskRepository : IRepository<Task>
        {
            /// <summary>
            /// 获取某个用户分配了哪些任务
            /// </summary>
            /// <param name="personId">用户Id</param>
            /// <returns>任务列表</returns>
            List<Task> GetTaskByAssignedPersonId(long personId);
        }
    }
    
    1. 在基础架构层,实现该仓储。
    namespace LearningMpaAbp.EntityFramework.Repositories
    {
        public class BackendTaskRepository:LearningMpaAbpRepositoryBase<Task>,IBackendTaskRepository
        {
            public BackendTaskRepository(IDbContextProvider<LearningMpaAbpDbContext> dbContextProvider) : base(dbContextProvider)
            {
            }
    
            /// <summary>
            /// 获取某个用户分配了哪些任务
            /// </summary>
            /// <param name="personId">用户Id</param>
            /// <returns>任务列表</returns>
            public List<Task> GetTaskByAssignedPersonId(long personId)
            {
                var query = GetAll();
    
                if (personId>0)
                {
                    query = query.Where(t => t.AssignedPersonId == personId);
                }
    
                return query.ToList();
            }
        }
    }
    

    该仓储实现,继承自模板生成的LearningMpaAbpRepositoryBase泛型抽象类,然后再实现IBackendTaskRepository接口。这里要显示声明实现类的有参构造函数,使用泛型的IDbContextProvider将数据库上下文的子类ChargeStationContext传给父类的构造函数。

    自定义仓储的代码路径

    三、仓储的注意事项

    1. 仓储方法中,ABP自动进行数据库连接的开启和关闭。
    2. 仓储方法被调用时,数据库连接自动开启且启动事务
    3. 当仓储方法调用另外一个仓储的方法,它们实际上共享的是同一个数据库连接和事务。
    4. 仓储对象都是暂时性的,因为IRepository接口默认继承自ITransientDependency接口。所以,仓储对象只有在需要注入的时候,才会由Ioc容器自动创建新实例。
    5. 默认的泛型仓储能满足我们大部分的需求。只有在不满足的情况下,才创建定制化的仓储。

    源码已上传至Github-LearningMpaAbp,可自行参考。

    相关文章

      网友评论

      • e9cdaed3ec97:应用服务层如何调用自定义仓储.
        public class TestAppService : TestAbpAppServiceBase, ITestAppService
        {
        private readonly IMyTestRepository _测试Repository;

        public KongZhiQiAppService(IMyTestRepository 测试Repository)
        {
        _测试Repository=测试Repository;
        }
        }
        报错:

        Can't create component 'TestAbp.TestAppService ' as it has dependencies to be satisfied.

        'TestAbp.TestAppService' is waiting for the following dependencies:
        - Service 'TestApp.IRepositories.IMyTestRepository' which was not registered.
        e9cdaed3ec97:@圣杰 没有!应该怎么写?
        圣杰:有没有注册自定义仓储到到IOC中
      • 006f15d2fbb1:你好,我想实现自定义仓储,看你是BackendTaskRepository:LearningMpaAbpRepositoryBase<Task>
        我发现是ef层引用core层啊 没法继承啊
        006f15d2fbb1:奥 看错了 :smile:
      • 4ad7bac4e930:po主请教几个问题呢,最近因为项目原因,需要用到abp ,想请教几个问题,我现在已经创建了实体类,迁移也成功了。
        如果我的业务非常简单,是否不需要自己定义仓储接口,而在application 层,直接定义一个接口,在controller 中 直接 实现这个接口,并直接调用 自带的仓储接口呢?
        圣杰: @安静的小白哥哥
        你的应用服务接口命名不规范,请参考官方文档的命名约定。
        4ad7bac4e930:@圣杰 我现在的做法就是这样的,但是 一直报错,我在迁移完成后,我并没有自定义仓储借口,而是直接在 application 层,定义了一个业务借口,在实现这个接口的类中,将默认的仓储接口注入,实现业务。在controller 中 ,将改业接口注入,调用业务接口方法。但是一直提示
        Can't create component 'ABPDemoWith21.Web.Controllers.DefaultController' as it has dependencies to be satisfied.

        'ABPDemoWith21.Web.Controllers.DefaultController' is waiting for the following dependencies:
        - Service 'ABPDemoWith21.IAppService' which was not registered.

        还望能 指点一二
        圣杰: @安静的小白哥哥 如果业务简单,那abp自带的泛型仓储就足够用了。
      • 345b900a55e6:请问下,支持oracle 吗
        345b900a55e6:@圣杰 哦哦 谢谢
        圣杰:@Aiolos丶mo 支持

      本文标题:ABP入门系列(3)——领域层定义仓储并实现

      本文链接:https://www.haomeiwen.com/subject/ubrpvttx.html