[Abp vNext 源码分析] - 14. EntityFramework Core 的集成 (3)

在上述代码当中,调用了 AddAbpDbContext<TDbContext>() 方法之后,就会通过 Repository Registrar 进行仓储注入。

public virtual void AddRepositories() { // 遍历用户添加的自定义仓储。 foreach (var customRepository in Options.CustomRepositories) { // 调用 AddDefaultRepository() 方法注入仓储。 Options.Services.AddDefaultRepository(customRepository.Key, customRepository.Value); } // 判断是否需要注册实体的默认仓储。 if (Options.RegisterDefaultRepositories) { RegisterDefaultRepositories(); } }

可以看到,在注入仓储的时候,分为两种情况。第一种是用户的自定义仓储,这种仓储是通过 AddRepository() 方法添加的,添加之后将会把它的 实体类型仓储类型 放在一个字典内部。在仓储注册器进行初始化的时候,就会遍历这个字典,进行注入动作。

第二种情况则是用户在设置了 RegisterDefaultRepositories=true 的情况下,ABP vNext 就会从数据库上下文的类型定义上遍历所有实体类型,然后进行默认仓储注册。

具体的仓储注册实现:

public static IServiceCollection AddDefaultRepository(this IServiceCollection services, Type entityType, Type repositoryImplementationType) { // 注册 IReadOnlyBasicRepository<TEntity>。 var readOnlyBasicRepositoryInterface = typeof(IReadOnlyBasicRepository<>).MakeGenericType(entityType); // 如果具体实现类型继承了该接口,则进行注入。 if (readOnlyBasicRepositoryInterface.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(readOnlyBasicRepositoryInterface, repositoryImplementationType); // 注册 IReadOnlyRepository<TEntity>。 var readOnlyRepositoryInterface = typeof(IReadOnlyRepository<>).MakeGenericType(entityType); if (readOnlyRepositoryInterface.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(readOnlyRepositoryInterface, repositoryImplementationType); } // 注册 IBasicRepository<TEntity>。 var basicRepositoryInterface = typeof(IBasicRepository<>).MakeGenericType(entityType); if (basicRepositoryInterface.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(basicRepositoryInterface, repositoryImplementationType); // 注册 IRepository<TEntity>。 var repositoryInterface = typeof(IRepository<>).MakeGenericType(entityType); if (repositoryInterface.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(repositoryInterface, repositoryImplementationType); } } } // 获得实体的主键类型,如果不存在则忽略。 var primaryKeyType = EntityHelper.FindPrimaryKeyType(entityType); if (primaryKeyType != null) { // 注册 IReadOnlyBasicRepository<TEntity, TKey>。 var readOnlyBasicRepositoryInterfaceWithPk = typeof(IReadOnlyBasicRepository<,>).MakeGenericType(entityType, primaryKeyType); if (readOnlyBasicRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(readOnlyBasicRepositoryInterfaceWithPk, repositoryImplementationType); // 注册 IReadOnlyRepository<TEntity, TKey>。 var readOnlyRepositoryInterfaceWithPk = typeof(IReadOnlyRepository<,>).MakeGenericType(entityType, primaryKeyType); if (readOnlyRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(readOnlyRepositoryInterfaceWithPk, repositoryImplementationType); } // 注册 IBasicRepository<TEntity, TKey>。 var basicRepositoryInterfaceWithPk = typeof(IBasicRepository<,>).MakeGenericType(entityType, primaryKeyType); if (basicRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(basicRepositoryInterfaceWithPk, repositoryImplementationType); // 注册 IRepository<TEntity, TKey>。 var repositoryInterfaceWithPk = typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType); if (repositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType)) { services.TryAddTransient(repositoryInterfaceWithPk, repositoryImplementationType); } } } } return services; }

回到仓储自动注册的地方,可以看到实现类型是由 GetDefaultRepositoryImplementationType() 方法提供的。

protected virtual void RegisterDefaultRepository(Type entityType) { Options.Services.AddDefaultRepository( entityType, GetDefaultRepositoryImplementationType(entityType) ); } protected virtual Type GetDefaultRepositoryImplementationType(Type entityType) { var primaryKeyType = EntityHelper.FindPrimaryKeyType(entityType); if (primaryKeyType == null) { return Options.SpecifiedDefaultRepositoryTypes ? Options.DefaultRepositoryImplementationTypeWithoutKey.MakeGenericType(entityType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType); } return Options.SpecifiedDefaultRepositoryTypes ? Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType); } protected abstract Type GetRepositoryType(Type dbContextType, Type entityType); protected abstract Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjzfw.html