首页 > 其他分享 >自动注册实体类到EntityFramework Core上下文,并适配ABP及ABP VNext

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

时间:2022-11-25 22:46:05浏览次数:59  
标签:VNext ... 实体类 省略 适配 ABP var modelAssemblyName

继上篇文章(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<IEntity>(modelAssemblyName);//泛型IEntity为所有实体类的规约类型
    base.OnModelCreating(modelBuilder);//这个必须加,否则报错
    
    ...//此处省略其它代码
  }
}

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

    public static class AutoRegisterEntityRepositoryExtensions
    {
        /// <summary>
        /// 将数据表实体类型对应的仓储注入到IOC容器
        /// </summary>
        /// <param name="iocManager"></param>
        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);
            }
        }

        /// <summary>
        /// 获取数据表实体类型列表
        /// </summary>
        /// <param name="constraintType">实体定义约束类型</param>
        /// <param name="modelAssemblyName">实体类所在dll名称,不包含后缀名(.dll)</param>
        /// <returns></returns>
        private static List<Type> 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<NotMappedAttribute>().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);
  }
}

标签:VNext,...,实体类,省略,适配,ABP,var,modelAssemblyName
From: https://www.cnblogs.com/zengxw/p/16926591.html

相关文章

  • 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
    ​​ 李华明Himi ​​​原创,转载务必在明显处注明​ ListView:在Android应用开发过程中属于最常用的系统组件之一,当然可能童鞋们问为什么会突然游戏开发中讲这个,呵呵,其......
  • 【转】Android 12.0蓝牙适配
    原文网址:Android12.0蓝牙适配-掘金(juejin.cn)前言  在我的申请下,公司终于购买了一台基于Android12.0的手机,然后我就开心的拿去安装测试了,发现程序崩溃了,于是我......
  • 超级好用的仿recycleview的listview适配器与viewholder封装
    由于公司项目频繁使用适配器,于是就使用java牛逼的泛型写了这和Recycleviwew那样的设计架构的lsitviewadapter超级好用的仿recycleview的listview适配器与viewholder+java......
  • 适配器模式c++
    [实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。  #include<iostream>usingnamespacestd;classCat{public:virtualvoid......
  • 初学银河麒麟linux笔记 第五章 windows中开发的QT程序适配linux的修改——外部控件重
    本人在WINDOWS系统中使用了“飞扬青云”的控件https://gitee.com/feiyangqingyun/QUCSDK由于系统移植,调用库应改为linux系统,首先下载对应版本的库,我windows上使用的是QT.......
  • 【Abp笔记】验证 Validation
    验证Validation官方文档https://docs.abp.io/zh-Hans/abp/latest/Validation哪里可以验证?哪里都行怎么验证?1.需要验证的类型(实体、DTO、Options之类的)实现IValid......
  • 【Abp笔记】依赖注入
    Abp依赖注入官方文档https://docs.abp.io/zh-Hans/abp/latest/Dependency-Injection基本使用直接注册context.Services.AddTransient<IGreetService,GreetService>(......
  • 适配器模式
    Adapter模式:我的电脑只有Type-c接口,要使用usb设备,那就需要适配器来进行转接。构成:目标接口(Target):用户所期待的接口,抽象类、或者是具体的类,比如电脑上的type-c接口。......
  • Adapter 适配器模式(结构型模式)
    意图:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。要点:1、Adapter模式......
  • 【Abp笔记】本地化
    本地化1.在自己模块添加本地化模块依赖在自己模块的DependsOn特性参数里,添加一个依赖typeof(AbpLocalizationModule),如果没有,就添加一个[DependsOn(typeof(AbpLoca......