Browse Source

Register repositories without PK.

pull/194/head
Halil İbrahim Kalkan 8 years ago
parent
commit
924ba47fe5
  1. 75
      src/Volo.Abp.Ddd/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs
  2. 26
      src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs
  3. 6
      src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs
  4. 50
      src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/EntityHelper.cs
  5. 9
      src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
  6. 2
      src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/IAggregateRoot.cs
  7. 54
      src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/QueryableRepositoryBase.cs
  8. 37
      src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs
  9. 119
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  10. 17
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs
  11. 2
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DbContextHelper.cs
  12. 8
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/EfCoreRepositoryRegistrar.cs
  13. 4
      src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs
  14. 2
      src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs
  15. 19
      src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs
  16. 89
      src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
  17. 5
      src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbRepositoryRegistrar.cs
  18. 5
      src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbRepositoryRegistrar.cs
  19. 1
      test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj
  20. 2
      test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj.DotSettings
  21. 91
      test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs
  22. 7
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/PhoneInSecondDbContext.cs
  23. 10
      test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs
  24. 2
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs
  25. 8
      test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/Repository_Tests.cs

75
src/Volo.Abp.Ddd/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs

@ -4,66 +4,49 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Reflection;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionRepositoryExtensions
{
public static void AddDefaultRepository(this IServiceCollection services, Type entityType, Type repositoryImplementationType)
public static IServiceCollection AddDefaultRepository(this IServiceCollection services, Type entityType, Type repositoryImplementationType)
{
AddDefaultRepositoryForGenericPrimaryKey(services, entityType, repositoryImplementationType);
//if (BothSupportsDefaultPrimaryKey(entityType, repositoryImplementationType))
//{
// AddDefaultRepositoryForDefaultPrimaryKey(services, entityType, repositoryImplementationType);
//}
}
private static void AddDefaultRepositoryForGenericPrimaryKey(IServiceCollection services, Type entityType, Type repositoryImplementationType)
{
var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType);
//IRepository<TEntity, TPrimaryKey>
var repositoryInterface = typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (!repositoryInterface.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
//IRepository<TEntity>
var repositoryInterfaceWithoutPk = typeof(IRepository<>).MakeGenericType(entityType);
if (!repositoryInterfaceWithoutPk.IsAssignableFrom(repositoryImplementationType))
{
throw new AbpException($"Given repositoryImplementationType ({repositoryImplementationType}) must implement {repositoryInterface}");
throw new AbpException($"Given repositoryImplementationType ({repositoryImplementationType}) must implement {repositoryInterfaceWithoutPk}");
}
services.TryAddTransient(repositoryInterface, repositoryImplementationType);
services.TryAddTransient(repositoryInterfaceWithoutPk, repositoryImplementationType);
//IQueryableRepository<TEntity, TPrimaryKey>
var queryableRepositoryInterface = typeof(IQueryableRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (queryableRepositoryInterface.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
//IQueryableRepository<TEntity>
var queryableRepositoryInterfaceWithPk = typeof(IQueryableRepository<>).MakeGenericType(entityType);
if (repositoryInterfaceWithoutPk.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(queryableRepositoryInterface, repositoryImplementationType);
services.TryAddTransient(queryableRepositoryInterfaceWithPk, repositoryImplementationType);
}
}
//private static void AddDefaultRepositoryForDefaultPrimaryKey(IServiceCollection services, Type entityType, Type repositoryImplementationType)
//{
// //IRepository<TEntity>
// var repositoryInterfaceWithDefaultPrimaryKey = typeof(IRepository<>).MakeGenericType(entityType);
// if (!repositoryInterfaceWithDefaultPrimaryKey.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
// {
// throw new AbpException($"Given repositoryImplementationType ({repositoryImplementationType}) must implement {repositoryInterfaceWithDefaultPrimaryKey}");
// }
// services.TryAddTransient(repositoryInterfaceWithDefaultPrimaryKey, repositoryImplementationType);
var primaryKeyType = EntityHelper.FindPrimaryKeyType(entityType);
// //IQueryableRepository<TEntity>
// var queryableRepositoryInterfaceWithDefaultPrimaryKey = typeof(IQueryableRepository<>).MakeGenericType(entityType);
// if (queryableRepositoryInterfaceWithDefaultPrimaryKey.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
// {
// services.TryAddTransient(queryableRepositoryInterfaceWithDefaultPrimaryKey, repositoryImplementationType);
// }
//}
if (primaryKeyType != null)
{
//IRepository<TEntity, TPrimaryKey>
var repositoryInterface = typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (repositoryInterface.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(repositoryInterface, repositoryImplementationType);
}
//IQueryableRepository<TEntity, TPrimaryKey>
var queryableRepositoryInterface = typeof(IQueryableRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (queryableRepositoryInterface.GetTypeInfo().IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(queryableRepositoryInterface, repositoryImplementationType);
}
}
//private static bool BothSupportsDefaultPrimaryKey(Type entityType, Type repositoryImplementationType)
//{
// return typeof(IEntity<Guid>).GetTypeInfo().IsAssignableFrom(entityType) &&
// ReflectionHelper.IsAssignableToGenericType(repositoryImplementationType, typeof(IRepository<>));
//}
return services;
}
}
}

26
src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Reflection;
@ -20,7 +19,7 @@ namespace Volo.Abp.DependencyInjection
public Type DefaultRepositoryImplementationType { get; private set; }
//public Type DefaultRepositoryImplementationTypeWithDefaultPrimaryKey { get; private set; }
public Type DefaultRepositoryImplementationTypeWithoutPrimaryKey { get; private set; }
public bool RegisterDefaultRepositories { get; private set; }
@ -28,7 +27,7 @@ namespace Volo.Abp.DependencyInjection
public Dictionary<Type, Type> CustomRepositories { get; }
public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null; // && DefaultRepositoryImplementationTypeWithDefaultPrimaryKey != null;
public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithoutPrimaryKey != null;
protected CommonDbContextRegistrationOptions(Type originalDbContextType)
{
@ -80,32 +79,37 @@ namespace Volo.Abp.DependencyInjection
return this;
}
public ICommonDbContextRegistrationOptionsBuilder AddCustomRepository<TEntity, TRepository>()
public ICommonDbContextRegistrationOptionsBuilder AddRepository<TEntity, TRepository>()
{
WithCustomRepository(typeof(TEntity), typeof(TRepository));
AddCustomRepository(typeof(TEntity), typeof(TRepository));
return this;
}
public ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses([NotNull] Type repositoryImplementationType)
public ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses(
Type repositoryImplementationType,
Type repositoryImplementationTypeWithoutPrimaryKey
)
{
Check.NotNull(repositoryImplementationType, nameof(repositoryImplementationType));
Check.NotNull(repositoryImplementationTypeWithoutPrimaryKey, nameof(repositoryImplementationTypeWithoutPrimaryKey));
DefaultRepositoryImplementationType = repositoryImplementationType;
DefaultRepositoryImplementationTypeWithoutPrimaryKey = repositoryImplementationTypeWithoutPrimaryKey;
return this;
}
private void WithCustomRepository(Type entityType, Type repositoryType)
private void AddCustomRepository(Type entityType, Type repositoryType)
{
if (!ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IEntity<>)))
if (!typeof(IEntity).IsAssignableFrom(entityType))
{
throw new AbpException($"Given entityType is not an entity: {entityType.AssemblyQualifiedName}. It must implement {typeof(IEntity<>).AssemblyQualifiedName}.");
}
if (!ReflectionHelper.IsAssignableToGenericType(repositoryType, typeof(IRepository<,>)))
if (!ReflectionHelper.IsAssignableToGenericType(repositoryType, typeof(IRepository<>)))
{
throw new AbpException($"Given repositoryType is not a repository: {entityType.AssemblyQualifiedName}. It must implement {typeof(IRepository<,>).AssemblyQualifiedName}.");
throw new AbpException($"Given repositoryType is not a repository: {entityType.AssemblyQualifiedName}. It must implement {typeof(IRepository<>).AssemblyQualifiedName}.");
}
CustomRepositories[entityType] = repositoryType;
@ -123,7 +127,7 @@ namespace Volo.Abp.DependencyInjection
return false;
}
if (!IncludeAllEntitiesForDefaultRepositories && !ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IAggregateRoot<>)))
if (!IncludeAllEntitiesForDefaultRepositories && !typeof(IAggregateRoot).IsAssignableFrom(entityType))
{
return false;
}

6
src/Volo.Abp.Ddd/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs

@ -1,4 +1,5 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.DependencyInjection
{
@ -41,14 +42,15 @@ namespace Volo.Abp.DependencyInjection
/// </summary>
/// <typeparam name="TEntity">Entity type</typeparam>
/// <typeparam name="TRepository">Repository type</typeparam>
ICommonDbContextRegistrationOptionsBuilder AddCustomRepository<TEntity, TRepository>(); //TODO: Rename to AddRepository!
ICommonDbContextRegistrationOptionsBuilder AddRepository<TEntity, TRepository>();
/// <summary>
/// Uses given class(es) for default repositories.
/// </summary>
/// <param name="repositoryImplementationType">Repository implementation type</param>
/// <param name="repositoryImplementationTypeWithoutPrimaryKey">Repository implementation type (without primary key)</param>
/// <returns></returns>
ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses(Type repositoryImplementationType);
ICommonDbContextRegistrationOptionsBuilder SetDefaultRepositoryClasses([NotNull] Type repositoryImplementationType, [NotNull] Type repositoryImplementationTypeWithoutPrimaryKey);
/// <summary>
/// Replaces given DbContext type with this DbContext type.

50
src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/EntityHelper.cs

@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
using Volo.Abp.Reflection;
namespace Volo.Abp.Domain.Entities
{
@ -13,18 +13,9 @@ namespace Volo.Abp.Domain.Entities
{
public static bool IsEntity([NotNull] Type type)
{
return ReflectionHelper.IsAssignableToGenericType(type, typeof (IEntity<>));
return typeof(IEntity).IsAssignableFrom(type);
}
/// <summary>
/// Default implementation of <see cref="Entity{TPrimaryKey}.IsTransient"/>.
///
/// This method is not used normally if given entity is derived from <see cref="Entity{TPrimaryKey}"/>.
/// Just directly call <see cref="Entity{TPrimaryKey}.IsTransient"/>.
///
/// This method is exists to help developers who want to directly implement <see cref="IEntity{TPrimaryKey}.IsTransient"/>
/// but want to use default IsTransient implementation as a shortcut.
/// </summary>
public static bool IsTransient<TPrimaryKey>(IEntity<TPrimaryKey> entity) // TODO: Completely remove IsTransient
{
if (EqualityComparer<TPrimaryKey>.Default.Equals(entity.Id, default))
@ -46,25 +37,50 @@ namespace Volo.Abp.Domain.Entities
return false;
}
public static Type GetPrimaryKeyType<TEntity>()
/// <summary>
/// Tries to find the primary key type of the given entity type.
/// May return null if given type does not implement <see cref="IEntity{TPrimaryKey}"/>
/// </summary>
[CanBeNull]
public static Type FindPrimaryKeyType<TEntity>()
where TEntity : IEntity
{
return GetPrimaryKeyType(typeof (TEntity));
return FindPrimaryKeyType(typeof(TEntity));
}
/// <summary>
/// Gets primary key type of given entity type
/// Tries to find the primary key type of the given entity type.
/// May return null if given type does not implement <see cref="IEntity{TPrimaryKey}"/>
/// </summary>
public static Type GetPrimaryKeyType([NotNull] Type entityType)
[CanBeNull]
public static Type FindPrimaryKeyType([NotNull] Type entityType)
{
if (!typeof(IEntity).IsAssignableFrom(entityType))
{
throw new AbpException($"Given {nameof(entityType)} is not an entity. It should implement {typeof(IEntity).AssemblyQualifiedName}!");
}
foreach (var interfaceType in entityType.GetTypeInfo().GetInterfaces())
{
if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IEntity<>))
if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
{
return interfaceType.GenericTypeArguments[0];
}
}
throw new AbpException("Can not find primary key type of given entity type: " + entityType + ". Be sure that this entity type implements " + typeof(IEntity<>).AssemblyQualifiedName);
return null;
}
public static Expression<Func<TEntity, bool>> CreateEqualityExpressionForId<TEntity, TPrimaryKey>(TPrimaryKey id)
where TEntity : IEntity<TPrimaryKey>
{
var lambdaParam = Expression.Parameter(typeof(TEntity));
var lambdaBody = Expression.Equal(
Expression.PropertyOrField(lambdaParam, "Id"),
Expression.Constant(id, typeof(TPrimaryKey))
);
return Expression.Lambda<Func<TEntity, bool>>(lambdaBody, lambdaParam);
}
}
}

9
src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/EntityNotFoundException.cs

@ -25,6 +25,15 @@ namespace Volo.Abp.Domain.Entities
}
/// <summary>
/// Creates a new <see cref="EntityNotFoundException"/> object.
/// </summary>
public EntityNotFoundException(Type entityType)
: this(entityType, null, null)
{
}
/// <summary>
/// Creates a new <see cref="EntityNotFoundException"/> object.
/// </summary>

2
src/Volo.Abp.Ddd/Volo/Abp/Domain/Entities/IAggregateRoot.cs

@ -13,7 +13,7 @@
/// Defines an aggregate root with a single primary key with "Id" property.
/// </summary>
/// <typeparam name="TPrimaryKey">Type of the primary key of the entity</typeparam>
public interface IAggregateRoot<TPrimaryKey> : IAggregateRoot, IEntity<TPrimaryKey>
public interface IAggregateRoot<TPrimaryKey> : IEntity<TPrimaryKey>, IAggregateRoot
{
}

54
src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/QueryableRepositoryBase.cs

@ -14,6 +14,10 @@ namespace Volo.Abp.Domain.Repositories
public abstract class QueryableRepositoryBase<TEntity> : RepositoryBase<TEntity>, IQueryableRepository<TEntity>
where TEntity : class, IEntity
{
public IDataFilter DataFilter { get; set; }
public ICurrentTenant CurrentTenant { get; set; }
public virtual Type ElementType => GetQueryable().ElementType;
public virtual Expression Expression => GetQueryable().Expression;
@ -45,18 +49,31 @@ namespace Volo.Abp.Domain.Repositories
Delete(predicate);
return Task.CompletedTask;
}
//TODO: Is that needed..?
protected virtual IQueryable<TEntity> ApplyDataFilters(IQueryable<TEntity> query)
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
query = query.WhereIf(DataFilter.IsEnabled<ISoftDelete>(), e => ((ISoftDelete)e).IsDeleted == false);
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
{
var tenantId = CurrentTenant.Id;
query = query.WhereIf(DataFilter.IsEnabled<IMultiTenant>(), e => ((IMultiTenant)e).TenantId == tenantId);
}
return query;
}
}
public abstract class QueryableRepositoryBase<TEntity, TPrimaryKey> : QueryableRepositoryBase<TEntity>, IQueryableRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public IDataFilter DataFilter { get; set; }
public ICurrentTenant CurrentTenant { get; set; }
public virtual TEntity Find(TPrimaryKey id)
{
return GetQueryable().FirstOrDefault(CreateEqualityExpressionForId(id));
return GetQueryable().FirstOrDefault(EntityHelper.CreateEqualityExpressionForId<TEntity, TPrimaryKey>(id));
}
public virtual TEntity Get(TPrimaryKey id)
@ -97,32 +114,5 @@ namespace Volo.Abp.Domain.Repositories
Delete(id);
return Task.CompletedTask;
}
protected virtual IQueryable<TEntity> ApplyDataFilters(IQueryable<TEntity> query)
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
query = query.WhereIf(DataFilter.IsEnabled<ISoftDelete>(), e => ((ISoftDelete)e).IsDeleted == false);
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
{
var tenantId = CurrentTenant.Id;
query = query.WhereIf(DataFilter.IsEnabled<IMultiTenant>(), e => ((IMultiTenant)e).TenantId == tenantId);
}
return query;
}
protected static Expression<Func<TEntity, bool>> CreateEqualityExpressionForId(TPrimaryKey id)
{
var lambdaParam = Expression.Parameter(typeof(TEntity));
var lambdaBody = Expression.Equal(
Expression.PropertyOrField(lambdaParam, "Id"),
Expression.Constant(id, typeof(TPrimaryKey))
);
return Expression.Lambda<Func<TEntity, bool>>(lambdaBody, lambdaParam);
}
}
}

37
src/Volo.Abp.Ddd/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Reflection;
namespace Volo.Abp.Domain.Repositories
{
@ -45,26 +44,26 @@ namespace Volo.Abp.Domain.Repositories
protected void RegisterDefaultRepository(IServiceCollection services, Type entityType)
{
var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityType);
//var isDefaultPrimaryKey = primaryKeyType == typeof(Guid);
services.AddDefaultRepository(
entityType,
GetDefaultRepositoryImplementationType(entityType)
);
}
Type repositoryImplementationType;
if (Options.SpecifiedDefaultRepositoryTypes)
{
repositoryImplementationType = Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType);
//repositoryImplementationType = isDefaultPrimaryKey
// ? Options.DefaultRepositoryImplementationTypeWithDefaultPrimaryKey.MakeGenericType(entityType)
// : Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType);
}
else
private Type GetDefaultRepositoryImplementationType(Type entityType)
{
var primaryKeyType = EntityHelper.FindPrimaryKeyType(entityType);
if (primaryKeyType == null)
{
repositoryImplementationType = GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType);
//repositoryImplementationType = isDefaultPrimaryKey
// ? GetRepositoryTypeForDefaultPk(Options.DefaultRepositoryDbContextType, entityType)
// : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType);
return Options.SpecifiedDefaultRepositoryTypes
? Options.DefaultRepositoryImplementationTypeWithoutPrimaryKey.MakeGenericType(entityType)
: GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType);
}
services.AddDefaultRepository(entityType, repositoryImplementationType);
return Options.SpecifiedDefaultRepositoryTypes
? Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType)
: GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType);
}
public bool ShouldRegisterDefaultRepositoryFor(Type entityType)
@ -79,7 +78,7 @@ namespace Volo.Abp.Domain.Repositories
return false;
}
if (!Options.IncludeAllEntitiesForDefaultRepositories && !ReflectionHelper.IsAssignableToGenericType(entityType, typeof(IAggregateRoot<>)))
if (!Options.IncludeAllEntitiesForDefaultRepositories && !typeof(IAggregateRoot).IsAssignableFrom(entityType))
{
return false;
}
@ -89,7 +88,7 @@ namespace Volo.Abp.Domain.Repositories
protected abstract IEnumerable<Type> GetEntityTypes(Type dbContextType);
//protected abstract Type GetRepositoryTypeForDefaultPk(Type dbContextType, Type entityType);
protected abstract Type GetRepositoryType(Type dbContextType, Type entityType);
protected abstract Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType);
}

119
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -7,30 +7,16 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Threading;
namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
//public class EfCoreRepository<TDbContext, TEntity> : EfCoreRepository<TDbContext, TEntity, Guid>, IEfCoreRepository<TEntity>
// where TDbContext : IEfCoreDbContext
// where TEntity : class, IEntity<Guid>
//{
// public EfCoreRepository(IDbContextProvider<TDbContext> dbContextProvider)
// : base(dbContextProvider)
// {
// }
//}
public class EfCoreRepository<TDbContext, TEntity, TPrimaryKey> : QueryableRepositoryBase<TEntity, TPrimaryKey>,
IEfCoreRepository<TEntity, TPrimaryKey>,
ISupportsExplicitLoading<TEntity, TPrimaryKey>
public class EfCoreRepository<TDbContext, TEntity> : QueryableRepositoryBase<TEntity>, IEfCoreRepository<TEntity>
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity<TPrimaryKey>
where TEntity : class, IEntity
{
public virtual DbSet<TEntity> DbSet => DbContext.Set<TEntity>();
DbContext IEfCoreRepository<TEntity, TPrimaryKey>.DbContext => DbContext.As<DbContext>();
DbContext IEfCoreRepository<TEntity>.DbContext => DbContext.As<DbContext>();
protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
@ -40,34 +26,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
_dbContextProvider = dbContextProvider;
}
protected override IQueryable<TEntity> GetQueryable()
{
return DbSet.AsQueryable();
}
public override async Task<TEntity> GetAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
var entity = await FindAsync(id, GetCancellationToken(cancellationToken));
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public override TEntity Find(TPrimaryKey id)
{
return DbSet.Find(id);
}
public override Task<TEntity> FindAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
return DbSet.FindAsync(new object[] { id }, GetCancellationToken(cancellationToken));
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
var savedEntity = DbSet.Add(entity).Entity;
@ -103,6 +62,11 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
DbSet.Remove(entity);
}
protected override IQueryable<TEntity> GetQueryable()
{
return DbSet.AsQueryable();
}
public override async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
var entities = await GetQueryable().Where(predicate).ToListAsync(GetCancellationToken(cancellationToken));
@ -130,4 +94,69 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return DbContext.Entry(entity).Reference(propertyExpression).LoadAsync(GetCancellationToken(cancellationToken));
}
}
public class EfCoreRepository<TDbContext, TEntity, TPrimaryKey> : EfCoreRepository<TDbContext, TEntity>,
IEfCoreRepository<TEntity, TPrimaryKey>,
ISupportsExplicitLoading<TEntity, TPrimaryKey>
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity<TPrimaryKey>
{
public EfCoreRepository(IDbContextProvider<TDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public TEntity Get(TPrimaryKey id)
{
var entity = Find(id);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual async Task<TEntity> GetAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
var entity = await FindAsync(id, GetCancellationToken(cancellationToken));
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual TEntity Find(TPrimaryKey id)
{
return DbSet.Find(id);
}
public virtual Task<TEntity> FindAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
return DbSet.FindAsync(new object[] { id }, GetCancellationToken(cancellationToken));
}
public virtual void Delete(TPrimaryKey id)
{
var entity = Find(id);
if (entity == null)
{
return;
}
Delete(entity);
}
public virtual Task DeleteAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
Delete(id);
return Task.CompletedTask;
}
}
}

17
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs

@ -1,20 +1,19 @@
using System;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
//public interface IEfCoreRepository<TEntity> : IEfCoreRepository<TEntity, Guid>, IQueryableRepository<TEntity>
// where TEntity : class, IEntity<Guid>
//{
//}
public interface IEfCoreRepository<TEntity, TPrimaryKey> : IQueryableRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
public interface IEfCoreRepository<TEntity> : IQueryableRepository<TEntity>
where TEntity : class, IEntity
{
DbContext DbContext { get; }
DbSet<TEntity> DbSet { get; }
}
public interface IEfCoreRepository<TEntity, TPrimaryKey> : IEfCoreRepository<TEntity>, IQueryableRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
}
}

2
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DbContextHelper.cs

@ -16,7 +16,7 @@ namespace Volo.Abp.EntityFrameworkCore
from property in dbContextType.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance)
where
ReflectionHelper.IsAssignableToGenericType(property.PropertyType, typeof(DbSet<>)) &&
ReflectionHelper.IsAssignableToGenericType(property.PropertyType.GenericTypeArguments[0], typeof(IEntity<>))
typeof(IEntity).IsAssignableFrom(property.PropertyType.GenericTypeArguments[0])
select property.PropertyType.GenericTypeArguments[0];
}
}

8
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/EfCoreRepositoryRegistrar.cs

@ -17,10 +17,10 @@ namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
return DbContextHelper.GetEntityTypes(dbContextType);
}
//protected override Type GetRepositoryTypeForDefaultPk(Type dbContextType, Type entityType)
//{
// return typeof(EfCoreRepository<,>).MakeGenericType(dbContextType, entityType);
//}
protected override Type GetRepositoryType(Type dbContextType, Type entityType)
{
return typeof(EfCoreRepository<,>).MakeGenericType(dbContextType, entityType);
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType)
{

4
src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs

@ -12,8 +12,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
services.AddAbpDbContext<IdentityDbContext>(options =>
{
options.AddDefaultRepositories();
options.AddCustomRepository<IdentityUser, EfCoreIdentityUserRepository>();
options.AddCustomRepository<IdentityRole, EfCoreIdentityRoleRepository>();
options.AddRepository<IdentityUser, EfCoreIdentityUserRepository>();
options.AddRepository<IdentityRole, EfCoreIdentityRoleRepository>();
});
services.AddAssemblyOf<AbpIdentityEntityFrameworkCoreModule>();

2
src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs

@ -14,7 +14,7 @@ namespace Volo.Abp.IdentityServer.EntityFrameworkCore
services.AddAbpDbContext<IdentityServerDbContext>(options =>
{
options.AddDefaultRepositories();
options.AddCustomRepository<Client, ClientRepository>();
options.AddRepository<Client, ClientRepository>();
});
services.AddAssemblyOf<AbpIdentityServerEntityFrameworkCoreModule>();

19
src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs

@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.Domain.Repositories.MemoryDb
{
//public interface IMemoryDbRepository<TEntity> : IMemoryDbRepository<TEntity, Guid>, IQueryableRepository<TEntity>
// where TEntity : class, IEntity<Guid>
//{
//}
public interface IMemoryDbRepository<TEntity, TPrimaryKey> : IQueryableRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
public interface IMemoryDbRepository<TEntity> : IQueryableRepository<TEntity>
where TEntity : class, IEntity
{
IMemoryDatabase Database { get; }
List<TEntity> Collection { get; }
}
public interface IMemoryDbRepository<TEntity, TPrimaryKey> : IMemoryDbRepository<TEntity>, IQueryableRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
}
}

89
src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs

@ -1,24 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MemoryDb;
namespace Volo.Abp.Domain.Repositories.MemoryDb
{
//public class MemoryDbRepository<TMemoryDbContext, TEntity> : MemoryDbRepository<TMemoryDbContext, TEntity, Guid>, IMemoryDbRepository<TEntity>
// where TMemoryDbContext : MemoryDbContext
// where TEntity : class, IEntity<Guid>
//{
// public MemoryDbRepository(IMemoryDatabaseProvider<TMemoryDbContext> databaseProvider)
// : base(databaseProvider)
// {
// }
//}
public class MemoryDbRepository<TMemoryDbContext, TEntity, TPrimaryKey> : QueryableRepositoryBase<TEntity, TPrimaryKey>, IMemoryDbRepository<TEntity, TPrimaryKey>
public class MemoryDbRepository<TMemoryDbContext, TEntity> : QueryableRepositoryBase<TEntity>, IMemoryDbRepository<TEntity>
where TMemoryDbContext : MemoryDbContext
where TEntity : class, IEntity<TPrimaryKey>
where TEntity : class, IEntity
{
public virtual List<TEntity> Collection => Database.Collection<TEntity>();
@ -33,11 +25,41 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
SetIdIfNeeded(entity);
Collection.Add(entity);
return entity;
}
public override TEntity Update(TEntity entity)
{
return entity;
}
public override void Delete(TEntity entity)
{
Collection.Remove(entity);
}
protected override IQueryable<TEntity> GetQueryable()
{
return ApplyDataFilters(Collection.AsQueryable());
}
}
public class MemoryDbRepository<TMemoryDbContext, TEntity, TPrimaryKey> : MemoryDbRepository<TMemoryDbContext, TEntity>, IMemoryDbRepository<TEntity, TPrimaryKey>
where TMemoryDbContext : MemoryDbContext
where TEntity : class, IEntity<TPrimaryKey>
{
public MemoryDbRepository(IMemoryDatabaseProvider<TMemoryDbContext> databaseProvider)
: base(databaseProvider)
{
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
SetIdIfNeeded(entity);
return base.Insert(entity, autoSave);
}
private void SetIdIfNeeded(TEntity entity)
{
if (typeof(TPrimaryKey) == typeof(int) || typeof(TPrimaryKey) == typeof(long) || typeof(TPrimaryKey) == typeof(Guid))
@ -49,19 +71,48 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
}
}
public override TEntity Update(TEntity entity)
public virtual TEntity Find(TPrimaryKey id)
{
return GetQueryable().FirstOrDefault(EntityHelper.CreateEqualityExpressionForId<TEntity, TPrimaryKey>(id));
}
public virtual TEntity Get(TPrimaryKey id)
{
var entity = Find(id);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public override void Delete(TEntity entity)
public virtual Task<TEntity> GetAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
Collection.Remove(entity);
return Task.FromResult(Get(id));
}
protected override IQueryable<TEntity> GetQueryable()
public virtual Task<TEntity> FindAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
return ApplyDataFilters(Collection.AsQueryable());
return Task.FromResult(Find(id));
}
public virtual void Delete(TPrimaryKey id)
{
var entity = Find(id);
if (entity == null)
{
return;
}
Delete(entity);
}
public virtual Task DeleteAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
Delete(id);
return Task.CompletedTask;
}
}
}

5
src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbRepositoryRegistrar.cs

@ -18,6 +18,11 @@ namespace Volo.Abp.MemoryDb.DependencyInjection
return memoryDbContext.GetEntityTypes();
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType)
{
return typeof(MemoryDbRepository<,>).MakeGenericType(dbContextType, entityType);
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType)
{
return typeof(MemoryDbRepository<,,>).MakeGenericType(dbContextType, entityType, primaryKeyType);

5
src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbRepositoryRegistrar.cs

@ -19,6 +19,11 @@ namespace Volo.Abp.MongoDB.DependencyInjection
return mongoDbContext.GetMappings().Select(m => m.EntityType);
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType)
{
throw new NotImplementedException();
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType)
{
return typeof(MongoDbRepository<,,>).MakeGenericType(dbContextType, entityType, primaryKeyType);

1
test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<AssemblyName>Volo.Abp.Ddd.Tests</AssemblyName>
<PackageId>Volo.Abp.Ddd.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>

2
test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj.DotSettings

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary>

91
test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
@ -25,8 +27,10 @@ namespace Volo.Abp.Domain.Repositories
//Assert
//services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithDefaultPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithDefaultPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithoutPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithoutPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldNotContainService(typeof(IRepository<MyTestEntityWithInt32Pk, int>));
}
@ -46,8 +50,10 @@ namespace Volo.Abp.Domain.Repositories
//Assert
//services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithDefaultPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithDefaultPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithoutPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithoutPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestEntityWithInt32Pk>), typeof(MyTestDefaultRepository<MyTestEntityWithInt32Pk, int>));
services.ShouldContainTransient(typeof(IRepository<MyTestEntityWithInt32Pk, int>), typeof(MyTestDefaultRepository<MyTestEntityWithInt32Pk, int>));
}
@ -61,7 +67,7 @@ namespace Volo.Abp.Domain.Repositories
var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext));
options
.AddDefaultRepositories(true)
.AddCustomRepository<MyTestAggregateRootWithGuidPk, MyTestAggregateRootWithDefaultPkCustomRepository>();
.AddRepository<MyTestAggregateRootWithGuidPk, MyTestAggregateRootWithDefaultPkCustomRepository>();
//Act
@ -69,7 +75,8 @@ namespace Volo.Abp.Domain.Repositories
//Assert
//services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithDefaultPk>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithoutPk>), typeof(MyTestDefaultRepository<MyTestAggregateRootWithoutPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestAggregateRootWithDefaultPkCustomRepository));
services.ShouldContainTransient(typeof(IRepository<MyTestEntityWithInt32Pk, int>), typeof(MyTestDefaultRepository<MyTestEntityWithInt32Pk, int>));
}
@ -84,7 +91,7 @@ namespace Volo.Abp.Domain.Repositories
var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext));
options
.AddDefaultRepositories(true)
.SetDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>));
.SetDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>), typeof(MyTestCustomBaseRepository<>));
//Act
@ -92,14 +99,15 @@ namespace Volo.Abp.Domain.Repositories
//Assert
//services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithDefaultPk>), typeof(MyTestCustomBaseRepository<MyTestAggregateRootWithDefaultPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithoutPk>), typeof(MyTestCustomBaseRepository<MyTestAggregateRootWithoutPk>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk>), typeof(MyTestCustomBaseRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestAggregateRootWithGuidPk, Guid>), typeof(MyTestCustomBaseRepository<MyTestAggregateRootWithGuidPk, Guid>));
services.ShouldContainTransient(typeof(IRepository<MyTestEntityWithInt32Pk, int>), typeof(MyTestCustomBaseRepository<MyTestEntityWithInt32Pk, int>));
}
public class MyTestRepositoryRegistrar : RepositoryRegistrarBase<CommonDbContextRegistrationOptions>
{
public MyTestRepositoryRegistrar(CommonDbContextRegistrationOptions options)
public MyTestRepositoryRegistrar(CommonDbContextRegistrationOptions options)
: base(options)
{
}
@ -109,14 +117,15 @@ namespace Volo.Abp.Domain.Repositories
return new[]
{
typeof(MyTestEntityWithInt32Pk),
typeof(MyTestAggregateRootWithGuidPk)
typeof(MyTestAggregateRootWithGuidPk),
typeof(MyTestAggregateRootWithoutPk)
};
}
//protected override Type GetRepositoryTypeForDefaultPk(Type dbContextType, Type entityType)
//{
// return typeof(MyTestDefaultRepository<>).MakeGenericType(entityType);
//}
protected override Type GetRepositoryType(Type dbContextType, Type entityType)
{
return typeof(MyTestDefaultRepository<>).MakeGenericType(entityType);
}
protected override Type GetRepositoryType(Type dbContextType, Type entityType, Type primaryKeyType)
{
@ -128,7 +137,7 @@ namespace Volo.Abp.Domain.Repositories
public class MyTestAggregateRootWithGuidPk : AggregateRoot<Guid>
{
}
public class MyTestEntityWithInt32Pk : Entity<int>
@ -136,31 +145,59 @@ namespace Volo.Abp.Domain.Repositories
}
//public class MyTestDefaultRepository<TEntity> : MyTestDefaultRepository<TEntity, Guid>
// where TEntity : class, IEntity<Guid>
//{
//}
public class MyTestAggregateRootWithoutPk : AggregateRoot
{
public string MyId { get; set; }
}
public class MyTestDefaultRepository<TEntity> : RepositoryBase<TEntity>
where TEntity : class, IEntity
{
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
throw new NotImplementedException();
}
public override TEntity Update(TEntity entity)
{
throw new NotImplementedException();
}
public override void Delete(TEntity entity)
{
throw new NotImplementedException();
}
}
public class MyTestDefaultRepository<TEntity, TPrimaryKey> : RepositoryBase<TEntity, TPrimaryKey>
public class MyTestDefaultRepository<TEntity, TPrimaryKey> : MyTestDefaultRepository<TEntity>, IRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public override TEntity Find(TPrimaryKey id)
public TEntity Get(TPrimaryKey id)
{
throw new NotImplementedException();
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
public Task<TEntity> GetAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public override TEntity Update(TEntity entity)
public TEntity Find(TPrimaryKey id)
{
throw new NotImplementedException();
}
public override void Delete(TEntity entity)
public Task<TEntity> FindAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public void Delete(TPrimaryKey id)
{
throw new NotImplementedException();
}
public Task DeleteAsync(TPrimaryKey id, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
@ -171,6 +208,12 @@ namespace Volo.Abp.Domain.Repositories
}
public class MyTestCustomBaseRepository<TEntity> : MyTestDefaultRepository<TEntity>
where TEntity : class, IEntity
{
}
public class MyTestCustomBaseRepository<TEntity, TPrimaryKey> : MyTestDefaultRepository<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
@ -179,7 +222,7 @@ namespace Volo.Abp.Domain.Repositories
public class TestDbContextRegistrationOptions : CommonDbContextRegistrationOptions
{
public TestDbContextRegistrationOptions(Type originalDbContextType)
public TestDbContextRegistrationOptions(Type originalDbContextType)
: base(originalDbContextType)
{
}

7
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/PhoneInSecondDbContext.cs

@ -1,11 +1,14 @@
using System.ComponentModel.DataAnnotations.Schema;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
{
[Table("AppPhones")]
public class PhoneInSecondDbContext : AggregateRoot<long>
public class PhoneInSecondDbContext : AggregateRoot
{
public virtual Guid PersonId { get; set; }
public virtual string Number { get; set; }
}
}

10
test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs

@ -12,5 +12,15 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PhoneInSecondDbContext>(b =>
{
b.HasKey(p => new { p.PersonId, p.Number });
});
}
}
}

2
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs

@ -22,7 +22,7 @@ namespace Volo.Abp.EntityFrameworkCore
services.AddAbpDbContext<TestAppDbContext>(options =>
{
options.AddDefaultRepositories();
options.AddDefaultRepositories(true);
options.ReplaceDbContext<IThirdDbContext>();
});

8
test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/Basic_Repository_Tests.cs → test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/Repository_Tests.cs

@ -10,17 +10,17 @@ using Xunit;
namespace Volo.Abp.EntityFrameworkCore.Repositories
{
public class Basic_Repository_Tests : EntityFrameworkCoreTestBase
public class Repository_Tests : EntityFrameworkCoreTestBase
{
private readonly IQueryableRepository<Person, Guid> _personRepository;
private readonly IQueryableRepository<BookInSecondDbContext, Guid> _bookRepository;
private readonly IQueryableRepository<PhoneInSecondDbContext, long> _phoneInSecondDbContextRepository;
private readonly IQueryableRepository<PhoneInSecondDbContext> _phoneInSecondDbContextRepository;
public Basic_Repository_Tests()
public Repository_Tests()
{
_personRepository = ServiceProvider.GetRequiredService<IQueryableRepository<Person, Guid>>();
_bookRepository = ServiceProvider.GetRequiredService<IQueryableRepository<BookInSecondDbContext, Guid>>();
_phoneInSecondDbContextRepository = ServiceProvider.GetRequiredService<IQueryableRepository<PhoneInSecondDbContext, long>>();
_phoneInSecondDbContextRepository = ServiceProvider.GetRequiredService<IQueryableRepository<PhoneInSecondDbContext>>();
}
[Fact]
Loading…
Cancel
Save