• 自动注册实体类到EntityFramework Core上下文,并适配ABP及ABP VNext


    继上篇文章(EF Core懒人小技巧之拒绝DbSet)之后,最近笔者把这个小功能单独封装成一个扩展方法并开源,欢迎交流和Star~

    GitHub: EntityFrameworkCore.Extension.AutoMapping

    Nuget:EntityFrameworkCore.Extension.AutoMapping

                 EntityFrameworkCore.Extension.AutoMapping.Abp

                 EntityFrameworkCore.Extension.AutoMapping.AbpVNext

    如何使用

    在DbContext.cs中重写OnModelCreating方法:

    using EntityFrameworkCore.Extension;
    ... //此处省略其它代码
    public class XmateDbContext:DbContext
    {
      ... //此处省略其它代码
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
        var modelAssemblyName = "XMate.Models";//实体类所在类库的名称,不包含扩展名(.dll)
        modelBuilder.AutoMappingEntityTypes(modelAssemblyName);//泛型IEntity为所有实体类的规约类型
        base.OnModelCreating(modelBuilder);//这个必须加,否则报错
        
        ...//此处省略其它代码
      }
    }
    

    这样,我们就可以不用写满屏的DbSet了。
    但是,在有的第三方框架中可能就会诞生新的问题。。。
    比如在ABP或者VNext框架中,用过ABP框架的都应该知道,ABP是通过扫描DbContext中的DbSet来实现将实体类的仓储自动注册到IOC容器中的,下面我们就需要自己动手来实现:

        public static class AutoRegisterEntityRepositoryExtensions
        {
            /// 
            /// 将数据表实体类型对应的仓储注入到IOC容器
            /// 
            /// 
            public static void RegisterDbEntityRepositories<TDbContext>(this IIocManager iocManager, string modelAssemblyName) where TDbContext : DbContext
            {
                foreach (var entityType in GetDbEntityType(typeof(IEntity<>), modelAssemblyName))
                {
                    var keyType = entityType.GetInterfaces().Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEntity<>)).SelectMany(t => t.GetGenericArguments()).First();
                    var genericRepositoryType = typeof(IRepository<,>).MakeGenericType(entityType, keyType);
                    var impType = typeof(EfCoreRepositoryBase<,,>).MakeGenericType(typeof(TDbContext), entityType, keyType);
                    iocManager.RegisterIfNot(genericRepositoryType, impType, lifeStyle: DependencyLifeStyle.Transient);
                }
            }
    
            /// 
            /// 获取数据表实体类型列表
            /// 
            /// 实体定义约束类型
            /// 实体类所在dll名称,不包含后缀名(.dll)
            /// 
            private static List GetDbEntityType(Type constraintType, string modelAssemblyName)
            {
                var all = AppDomain.CurrentDomain.GetAssemblies();
                var types = all.WhereIf(!modelAssemblyName.IsNullOrWhiteSpace(), a => a.FullName.Contains(modelAssemblyName))
                    .SelectMany(m => m.GetTypes().Where(t => t.IsClass && !t.IsAbstract && (t.IsImplement(constraintType) || t.IsSubclass(constraintType))).ToList())
                    .Distinct()
                    .ToList();
                return types.Where(t => !t.GetCustomAttributes().Any()).ToList();
            }
        }
    

    注:以上代码摘自:AutoRegisterEntityRepositoryExtensions.cs

    在ABP VNext中的实现思路也是如此,这里就不贴代码了,感兴趣的可以查阅源代码

    在Abp中实现自动注入实体类对应的Repository

    using EntityFrameworkCore.Extension.AutoMapping.Abp;
    ... //此处省略其它代码
    public class XmateModule:AbpModule
    {
      ... //此处省略其它代码
      //重写Initialize方法
      public override void Initialize()
      {
          ... //此处省略其它代码
          var modelAssemblyName = "XMate.Models";//实体类所在类库的名称,不包含扩展名(.dll)
          IocManager.RegisterDbEntityRepositories(modelAssemblyName);
      }
    }
    
    

    在Abp VNext中实现自动注入实体类对应的Repository

    using EntityFrameworkCore.Extension.AutoMapping.AbpVNext;
    ... //此处省略其它代码
    public class XmateModule:AbpModule
    {
      ... //此处省略其它代码
      //重写ConfigureServices方法
      public override void ConfigureServices(ServiceConfigurationContext context)
      {
          ... //此处省略其它代码
          var modelAssemblyName = "XMate.Models";//实体类所在类库的名称,不包含扩展名(.dll)
          context.Services.RegisterDbEntityRepositories(modelAssemblyName);
      }
    }
    
    
  • 相关阅读:
    java毕业设计小区停车场管理系统mybatis+源码+调试部署+系统+数据库+lw
    数组力扣485题---最大连续1的个数
    触摸控件——键盘录入之ASCII录入
    DataFrame(11):数据转换——map()函数的使用
    jvm-基础
    【owt-server】m88分支和m59-server
    SpringBoot 04 多环境配置和配置文件小技巧
    一篇文章带你用动态规划解决打家劫舍问题
    abstract抽象 与interface接口
    【原创】Ubuntu Pro RealTime linux(Ubuntu22.04 安装PREEMPT-RT实时内核/PREEMPT-RT/ubuntu官方PREEMPT-RT)
  • 原文地址:https://www.cnblogs.com/zengxw/p/16926591.html