Skip to content

Commit

Permalink
Merge pull request #7673 from abpframework/liangshiwei/addDefaultRepo…
Browse files Browse the repository at this point in the history
…sitory

Add AddDefaultRepository method
  • Loading branch information
hikalkan committed Feb 26, 2021
2 parents d6d963d + 3b6a0ee commit bc0da76
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public abstract class AbpCommonDbContextRegistrationOptions : IAbpCommonDbContex

public Dictionary<Type, Type> CustomRepositories { get; }

public List<Type> DefaultRepositories { get; }

public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithoutKey != null;

protected AbpCommonDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services)
Expand All @@ -38,6 +40,7 @@ protected AbpCommonDbContextRegistrationOptions(Type originalDbContextType, ISer
DefaultRepositoryDbContextType = originalDbContextType;
CustomRepositories = new Dictionary<Type, Type>();
ReplacedDbContextTypes = new List<Type>();
DefaultRepositories = new List<Type>();
}

public IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext<TOtherDbContext>()
Expand Down Expand Up @@ -82,6 +85,23 @@ public IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories<TDef
return AddDefaultRepositories(typeof(TDefaultRepositoryDbContext), includeAllEntities);
}

public IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository<TEntity>()
{
return AddDefaultRepository(typeof(TEntity));
}

public IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository(Type entityType)
{
if (!typeof(IEntity).IsAssignableFrom(entityType))
{
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}.");
}

DefaultRepositories.AddIfNotContains(entityType);

return this;
}

public IAbpCommonDbContextRegistrationOptionsBuilder AddRepository<TEntity, TRepository>()
{
AddCustomRepository(typeof(TEntity), typeof(TRepository));
Expand Down Expand Up @@ -118,4 +138,4 @@ private void AddCustomRepository(Type entityType, Type repositoryType)
CustomRepositories[entityType] = repositoryType;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ public interface IAbpCommonDbContextRegistrationOptionsBuilder
/// </param>
IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(Type defaultRepositoryDbContextType, bool includeAllEntities = false);

/// <summary>
/// Registers custom repository for a specific entity.
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository<TEntity>();


/// <summary>
/// Registers default repository for a specific entity.
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository(Type entityType);

/// <summary>
/// Registers custom repository for a specific entity.
/// Custom repositories overrides default repositories.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
Expand All @@ -17,20 +18,29 @@ protected RepositoryRegistrarBase(TOptions options)
}

public virtual void AddRepositories()
{
RegisterCustomRepositories();

RegisterDefaultRepositories();

RegisterSpecifiedDefaultRepositories();
}

protected virtual void RegisterCustomRepositories()
{
foreach (var customRepository in Options.CustomRepositories)
{
Options.Services.AddDefaultRepository(customRepository.Key, customRepository.Value, replaceExisting: true);
}

if (Options.RegisterDefaultRepositories)
{
RegisterDefaultRepositories();
}
}

protected virtual void RegisterDefaultRepositories()
{
if (!Options.RegisterDefaultRepositories)
{
return;
}

foreach (var entityType in GetEntityTypes(Options.OriginalDbContextType))
{
if (!ShouldRegisterDefaultRepositoryFor(entityType))
Expand All @@ -42,6 +52,17 @@ protected virtual void RegisterDefaultRepositories()
}
}

protected virtual void RegisterSpecifiedDefaultRepositories()
{
foreach (var entityType in Options.DefaultRepositories)
{
if (!Options.CustomRepositories.ContainsKey(entityType))
{
RegisterDefaultRepository(entityType);
}
}
}

protected virtual void RegisterDefaultRepository(Type entityType)
{
Options.Services.AddDefaultRepository(
Expand Down Expand Up @@ -92,4 +113,4 @@ protected virtual bool ShouldRegisterDefaultRepositoryFor(Type entityType)

protected abstract Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,60 @@ public void Should_Register_Default_Repositories_With_Custom_Base()
services.ShouldContainTransient(typeof(IRepository<MyTestEntityWithInt32Pk, int>), typeof(MyTestCustomBaseRepository<MyTestEntityWithInt32Pk, int>));
}

[Fact]
public void Should_Register_Default_Repository()
{
//Arrange

var services = new ServiceCollection();

var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services);
options.AddDefaultRepository<MyTestAggregateRootWithGuidPk>();

//Act

new MyTestRepositoryRegistrar(options).AddRepositories();

//MyTestAggregateRootWithoutPk
services.ShouldNotContainService(typeof(IReadOnlyRepository<MyTestAggregateRootWithoutPk>));
services.ShouldNotContainService(typeof(IBasicRepository<MyTestAggregateRootWithoutPk>));
services.ShouldNotContainService(typeof(IRepository<MyTestAggregateRootWithoutPk>));

//MyTestAggregateRootWithGuidPk
services.ShouldContainTransient(typeof(IReadOnlyRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IBasicRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IReadOnlyRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IBasicRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
}

[Fact]
public void Should_Not_Register_Default_Repository_If_Registered_Custom_Repository()
{
//Arrange

var services = new ServiceCollection();

var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services);
options
.AddDefaultRepository<MyTestAggregateRootWithGuidPk>()
.AddRepository<MyTestAggregateRootWithGuidPk, MyTestAggregateRootWithDefaultPkCustomRepository>();;

//Act

new MyTestRepositoryRegistrar(options).AddRepositories();

//MyTestAggregateRootWithGuidPk
services.ShouldContainTransient(typeof(IReadOnlyRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IBasicRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IReadOnlyRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IReadOnlyBasicRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IBasicRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
}

public class MyTestRepositoryRegistrar : RepositoryRegistrarBase<AbpCommonDbContextRegistrationOptions>
{
public MyTestRepositoryRegistrar(AbpCommonDbContextRegistrationOptions options)
Expand Down

0 comments on commit bc0da76

Please sign in to comment.