From 0ef5daeb0e342b347d79dce9911466bc624d844a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 3 Jan 2017 00:01:33 +0300 Subject: [PATCH] Provide an option to set base repository classes, instead of defaults. --- .../ServiceCollectionRepositoryExtensions.cs | 2 +- .../CommonDbContextRegistrationOptions.cs | 20 ++++++++- ...mmonDbContextRegistrationOptionsBuilder.cs | 10 +++++ .../Repositories/RepositoryRegistrarBase.cs | 20 +++++++-- .../RepositoryRegistration_Tests.cs | 41 ++++++++++++++++++- 5 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs index b605dd8810..964c869175 100644 --- a/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs +++ b/src/Volo.Abp/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs @@ -41,7 +41,7 @@ namespace Microsoft.Extensions.DependencyInjection private static bool BothSupportsDefaultPrimaryKey(Type entityType, Type repositoryImplementationType) { - return typeof(IEntity).GetTypeInfo().IsAssignableFrom(entityType) && + return typeof(IEntity).GetTypeInfo().IsAssignableFrom(entityType) && ReflectionHelper.IsAssignableToGenericType(repositoryImplementationType, typeof(IRepository<>)); } } diff --git a/src/Volo.Abp/Volo/Abp/Data/CommonDbContextRegistrationOptions.cs b/src/Volo.Abp/Volo/Abp/Data/CommonDbContextRegistrationOptions.cs index eb593ad459..db93a133ed 100644 --- a/src/Volo.Abp/Volo/Abp/Data/CommonDbContextRegistrationOptions.cs +++ b/src/Volo.Abp/Volo/Abp/Data/CommonDbContextRegistrationOptions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using JetBrains.Annotations; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.Reflection; @@ -8,7 +9,11 @@ namespace Volo.Abp.Data { public class CommonDbContextRegistrationOptions : ICommonDbContextRegistrationOptionsBuilder { - //TODO: Provide an option to set base repository classes, instead of defaults. + public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithDefaultPrimaryKey != null; + + public Type DefaultRepositoryImplementationType { get; private set; } + + public Type DefaultRepositoryImplementationTypeWithDefaultPrimaryKey { get; private set; } public bool RegisterDefaultRepositories { get; private set; } @@ -25,12 +30,25 @@ namespace Volo.Abp.Data { RegisterDefaultRepositories = true; IncludeAllEntitiesForDefaultRepositories = includeAllEntities; + return this; } public ICommonDbContextRegistrationOptionsBuilder WithCustomRepository() { WithCustomRepository(typeof(TEntity), typeof(TRepository)); + + return this; + } + + public ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositoryClasses([NotNull] Type repositoryImplementationType, [NotNull] Type repositoryImplementationTypeWithDefaultPrimaryKey) + { + Check.NotNull(repositoryImplementationType, nameof(repositoryImplementationType)); + Check.NotNull(repositoryImplementationTypeWithDefaultPrimaryKey, nameof(repositoryImplementationTypeWithDefaultPrimaryKey)); + + DefaultRepositoryImplementationType = repositoryImplementationType; + DefaultRepositoryImplementationTypeWithDefaultPrimaryKey = repositoryImplementationTypeWithDefaultPrimaryKey; + return this; } diff --git a/src/Volo.Abp/Volo/Abp/Data/ICommonDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp/Volo/Abp/Data/ICommonDbContextRegistrationOptionsBuilder.cs index 7266dcff7c..6afa05a700 100644 --- a/src/Volo.Abp/Volo/Abp/Data/ICommonDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp/Volo/Abp/Data/ICommonDbContextRegistrationOptionsBuilder.cs @@ -1,3 +1,5 @@ +using System; + namespace Volo.Abp.Data { public interface ICommonDbContextRegistrationOptionsBuilder @@ -18,5 +20,13 @@ namespace Volo.Abp.Data /// Entity type /// Repository type ICommonDbContextRegistrationOptionsBuilder WithCustomRepository(); + + /// + /// Uses given class(es) for default repositories. + /// + /// Repository implementation type + /// Repository implementation type for default primary key type () + /// + ICommonDbContextRegistrationOptionsBuilder WithDefaultRepositoryClasses(Type repositoryImplementationType, Type repositoryImplementationTypeWithDefaultPrimaryKey); } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs b/src/Volo.Abp/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs index 6c6295cc41..6426f892bb 100644 --- a/src/Volo.Abp/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs +++ b/src/Volo.Abp/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; @@ -45,9 +44,22 @@ namespace Volo.Abp.Domain.Repositories protected void RegisterDefaultRepository(IServiceCollection services, Type dbContextType, Type entityType) { - var repositoryImplementationType = typeof(IEntity).GetTypeInfo().IsAssignableFrom(entityType) - ? GetRepositoryTypeForDefaultPk(dbContextType, entityType) - : GetRepositoryType(dbContextType, entityType, EntityHelper.GetPrimaryKeyType(entityType)); + var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType); + var isDefaultPrimaryKey = primaryKeyType == typeof(string); + + Type repositoryImplementationType; + if (Options.SpecifiedDefaultRepositoryTypes) + { + repositoryImplementationType = isDefaultPrimaryKey + ? Options.DefaultRepositoryImplementationTypeWithDefaultPrimaryKey.MakeGenericType(entityType) + : Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType); + } + else + { + repositoryImplementationType = isDefaultPrimaryKey + ? GetRepositoryTypeForDefaultPk(dbContextType, entityType) + : GetRepositoryType(dbContextType, entityType, primaryKeyType); + } services.AddDefaultRepository(entityType, repositoryImplementationType); } diff --git a/test/Volo.Abp.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs b/test/Volo.Abp.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs index 9b899eee43..1dfa092649 100644 --- a/test/Volo.Abp.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs +++ b/test/Volo.Abp.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs @@ -59,8 +59,9 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); var options = new CommonDbContextRegistrationOptions(); - options.WithDefaultRepositories(true); - options.WithCustomRepository(); + options + .WithDefaultRepositories(true) + .WithCustomRepository(); //Act @@ -73,6 +74,29 @@ namespace Volo.Abp.Domain.Repositories services.ShouldContainTransient(typeof(IRepository), typeof(MyTestDefaultRepository)); } + [Fact] + public void Should_Register_Default_Repositories_With_Custom_Base() + { + //Arrange + + var services = new ServiceCollection(); + + var options = new CommonDbContextRegistrationOptions(); + options + .WithDefaultRepositories(true) + .WithDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>), typeof(MyTestCustomBaseRepository<>)); + + //Act + + new MyTestRepositoryRegistrar(options).AddRepositories(services, typeof(MyFakeDbContext)); + + //Assert + + services.ShouldContainTransient(typeof(IRepository), typeof(MyTestCustomBaseRepository)); + services.ShouldContainTransient(typeof(IRepository), typeof(MyTestCustomBaseRepository)); + services.ShouldContainTransient(typeof(IRepository), typeof(MyTestCustomBaseRepository)); + } + public class MyTestRepositoryRegistrar : RepositoryRegistrarBase { public MyTestRepositoryRegistrar(CommonDbContextRegistrationOptions options) @@ -146,5 +170,18 @@ namespace Volo.Abp.Domain.Repositories { } + + public class MyTestCustomBaseRepository : MyTestCustomBaseRepository, IRepository + where TEntity : class, IEntity + { + + } + + public class MyTestCustomBaseRepository : MyTestDefaultRepository + where TEntity : class, IEntity + { + + } + } }