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

  • 自动注册实体类到EntityFramework Core上下文,并适配ABP及ABP VNext已关闭评论
  • 124 次浏览
  • A+
所属分类:.NET技术
摘要

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

继上篇文章(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);   } }