Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AddDefaultRepository method #7673

Merged
merged 2 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!typeof(IEntity).IsAssignableFrom(entityType))
if (!EntityHelper.IsEntity(entityType))

{
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}.");
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);
}

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