ABP_扩展IRepository添加自定义方法


在ABP实际使用过程有时候需要对IRepository进行扩展,增加一些自定义方法。

先创建一个自定义仓储接口对IRepository<TEntity, TPrimaryKey>进行扩展。

using System;
using System.Linq.Expressions;
using Abp.Dependency;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;

namespace MyProject.Domain
{
    /// <summary>
    /// 定义仓储模型中的扩展操作
    /// </summary>
    public interface IMyRepository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        /// <summary>
        ///<see cref="IRepository{TEntity, TPrimaryKey}"/>扩展一个可以获取关联实体的FirstOrDefault操作
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="includeExpression"></param>
        /// <returns></returns>
        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] includeExpression);
    }

    public interface IMyRepository<TEntity> : IMyRepository<TEntity, int>, IRepository, ITransientDependency
    where TEntity : class, IEntity<int>
    {
    }
}

 

创建IMyRepository的实现类MyRepository,它继承自ABP自动创建的MyProjectRepositoryBase的这个基类。

using System;
using System.Linq;
using System.Linq.Expressions;
using Abp.Domain.Entities;
using Abp.EntityFrameworkCore;
using Abp.EntityFrameworkCore.Repositories;
using MyProject.Domain;

namespace MyProject.EntityFrameworkCore.Repositories
{
    /// <summary>
    /// 实现仓储模型中的扩展操作
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TPrimaryKey"></typeparam>
    public class MyRepository<TEntity, TPrimaryKey> :  MyProjectRepositoryBase<TEntity, TPrimaryKey>, IMyRepository<TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        public MyRepository(IDbContextProvider<MyProjectDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] includeExpression)
        {
            return GetAllIncluding(includeExpression).FirstOrDefault(predicate);
        }
    }

    public class MyRepository<TEntity> : MyRepository<TEntity, int>, IMyRepository<TEntity>
    where TEntity : class, IEntity<int>
    {
        public MyRepository(IDbContextProvider<MyProjectDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }
    }
}

 

创建MyEfCoreAutoRepositoryTypes用于关联仓储接口和其默认实现。

using System;
using Abp.Domain.Repositories;
using MyProject.Domain;

namespace MyProject.EntityFrameworkCore.Repositories
{
    /// <summary>
    /// 关联仓储接口和其默认实现。
    /// </summary>
    public class MyEfCoreAutoRepositoryTypes
    {
        public static AutoRepositoryTypesAttribute Default { get; }

        static MyEfCoreAutoRepositoryTypes()
        {
            Default = new AutoRepositoryTypesAttribute(
                typeof(IMyRepository<>),
                typeof(IMyRepository<,>),
                typeof(MyRepository<>),
                typeof(MyRepository<,>)
            );
        }
    }
}

 

修改MyProjectEntityFrameworkModule为其添加RegisterGenericRepositoriesAndMatchDbContexes方法为DbContext中每个实体注册一个IMyRepository的默认实现,并在Initialize中调用这个注册方法。

using System;
using System.Reflection;
using Abp.Collections.Extensions;
using Abp.Dependency;
using Abp.EntityFramework;
using Abp.EntityFramework.Repositories;
using Abp.EntityFrameworkCore;
using Abp.EntityFrameworkCore.Configuration;
using Abp.Modules;
using Abp.Orm;
using Abp.Reflection;
using Abp.Reflection.Extensions;
using Abp.Zero.EntityFrameworkCore;
using Castle.MicroKernel.Registration;
using MyProject.EntityFrameworkCore.Repositories;
using MyProject.EntityFrameworkCore.Seed;

namespace MyProject.EntityFrameworkCore
{
    [DependsOn(
        typeof(MyProjectCoreModule), 
        typeof(AbpZeroCoreEntityFrameworkCoreModule))]
    public class MyProjectEntityFrameworkModule : AbpModule
    {
        /* Used it tests to skip dbcontext registration, in order to use in-memory database of EF Core */
        public bool SkipDbContextRegistration { get; set; }

        public bool SkipDbSeed { get; set; }

        private readonly ITypeFinder _typeFinder;

        public MyProjectEntityFrameworkModule(ITypeFinder typeFinder)
        {
            _typeFinder = typeFinder;
        }

        public override void PreInitialize()
        {
      ... } public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(MyProjectEntityFrameworkModule).GetAssembly()); //调用注册方法 RegisterGenericRepositoriesAndMatchDbContexes(); } public override void PostInitialize() { ... } /// <summary> /// 为DbContext中表达的实体注册通用的Repository /// </summary> private void RegisterGenericRepositoriesAndMatchDbContexes() { //获取所有注入的数据库上下文 var dbContextTypes = _typeFinder.Find(type => { var typeInfo = type.GetTypeInfo(); return typeInfo.IsPublic && !typeInfo.IsAbstract && typeInfo.IsClass && typeof(AbpDbContext).IsAssignableFrom(type); }); if (dbContextTypes.IsNullOrEmpty()) { Logger.Warn("No class found derived from AbpDbContext."); return; } using (IScopedIocResolver scope = IocManager.CreateScope()) { foreach (var dbContextType in dbContextTypes) { Logger.Debug("Registering DbContext: " + dbContextType.AssemblyQualifiedName); //为数据上下文中的所有实体注册MyEfCoreAutoRepositoryTypes的定义的Repository。 scope.Resolve<IEfGenericRepositoryRegistrar>().RegisterForDbContext(dbContextType, IocManager, MyEfCoreAutoRepositoryTypes.Default); IocManager.IocContainer.Register( Component.For<ISecondaryOrmRegistrar>() .Named(Guid.NewGuid().ToString("N")) .Instance(new EfCoreBasedSecondaryOrmRegistrar(dbContextType, scope.Resolve<IDbContextEntityFinder>())) .LifestyleTransient() ); } } } } }

 

 写个单元测试使用IMyRepository调用自定义的FirstOrDefault对User进行查询,并且Roles把作为关联实体进行预加载。

    public class MyRepository_Test:MyProjectTestBase
    {
        private readonly IMyRepository<User, long> _myRepository;

        public MyRepository_Test()
        {
            //MyRepository<User, long>已经被自动注册
            _myRepository = Resolve<IMyRepository<User, long>>();
        }

        [Fact]
        public void GetUsers_IncludeRoles_Test()
        {
            // Act
            var User = _myRepository.FirstOrDefault(t => t.Name == "admin", t => t.Roles);

            //Assert
            User.Roles.ShouldNotBeNull();
        }
    }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM