diff --git a/Volo.Abp.sln b/Volo.Abp.sln index eb9ba7e532..a0564a2690 100644 --- a/Volo.Abp.sln +++ b/Volo.Abp.sln @@ -122,6 +122,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.Tes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TestApp", "test\Volo.Abp.TestApp\Volo.Abp.TestApp.csproj", "{DE160F1A-92FB-44BA-87E2-B8AD7A938AC7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MemoryDb", "src\Volo.Abp.MemoryDb\Volo.Abp.MemoryDb.csproj", "{CF564447-8E0B-4A07-B0D2-396E00A8E437}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.MemoryDb.Tests", "test\Volo.Abp.MemoryDb.Tests\Volo.Abp.MemoryDb.Tests.csproj", "{D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -300,6 +304,14 @@ Global {DE160F1A-92FB-44BA-87E2-B8AD7A938AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE160F1A-92FB-44BA-87E2-B8AD7A938AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE160F1A-92FB-44BA-87E2-B8AD7A938AC7}.Release|Any CPU.Build.0 = Release|Any CPU + {CF564447-8E0B-4A07-B0D2-396E00A8E437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF564447-8E0B-4A07-B0D2-396E00A8E437}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF564447-8E0B-4A07-B0D2-396E00A8E437}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF564447-8E0B-4A07-B0D2-396E00A8E437}.Release|Any CPU.Build.0 = Release|Any CPU + {D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -357,6 +369,8 @@ Global {8343BE23-6A7B-4C58-BF0D-95188B11B180} = {37087D1B-3693-4E96-983D-A69F210BDE53} {27D76546-6091-4AEE-9079-1FE3991C81BC} = {37087D1B-3693-4E96-983D-A69F210BDE53} {DE160F1A-92FB-44BA-87E2-B8AD7A938AC7} = {37087D1B-3693-4E96-983D-A69F210BDE53} + {CF564447-8E0B-4A07-B0D2-396E00A8E437} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8} + {D0279C94-E9A3-4A1B-968B-D3BBF3E06FD8} = {37087D1B-3693-4E96-983D-A69F210BDE53} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs new file mode 100644 index 0000000000..2fbab6a9fd --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs @@ -0,0 +1,23 @@ +using System; +using Volo.Abp.MemoryDb; +using Volo.Abp.MemoryDb.DependencyInjection; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class AbpMemoryDbServiceCollectionExtensions + { + public static IServiceCollection AddMemoryDbContext(this IServiceCollection services, Action optionsBuilder = null) + where TMemoryDbContext : MemoryDbContext + { + var options = new MemoryDbContextRegistrationOptions(); + optionsBuilder?.Invoke(options); + + services.AddSingleton(); + + new MemoryDbRepositoryRegistrar(options) + .AddRepositories(services, typeof(TMemoryDbContext)); + + return services; + } + } +} diff --git a/src/Volo.Abp.MemoryDb/Volo.Abp.MemoryDb.csproj b/src/Volo.Abp.MemoryDb/Volo.Abp.MemoryDb.csproj new file mode 100644 index 0000000000..a54deee1ef --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo.Abp.MemoryDb.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.0 + Volo.Abp.MemoryDb + Volo.Abp.MemoryDb + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDatabase.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDatabase.cs new file mode 100644 index 0000000000..3b9ca358bf --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDatabase.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Domain.Repositories.MemoryDb +{ + public interface IMemoryDatabase + { + List Collection(); + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs new file mode 100644 index 0000000000..59f001195a --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.Domain.Repositories.MemoryDb +{ + public interface IMemoryDbRepository : IMemoryDbRepository, IQueryableRepository + where TEntity : class, IEntity + { + + } + + public interface IMemoryDbRepository : IQueryableRepository + where TEntity : class, IEntity + { + IMemoryDatabase Database { get; } + + List Collection { get; } + } +} diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabase.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabase.cs new file mode 100644 index 0000000000..dc6c6ffc99 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabase.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace Volo.Abp.Domain.Repositories.MemoryDb +{ + public class MemoryDatabase : IMemoryDatabase + { + private readonly ConcurrentDictionary _sets; + + private readonly object _syncObj = new object(); + + public MemoryDatabase() + { + _sets = new ConcurrentDictionary(); + } + + public List Collection() + { + return _sets.GetOrAdd(typeof(TEntity), _ => new List()) as List; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabaseManager.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabaseManager.cs new file mode 100644 index 0000000000..4926abebf3 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabaseManager.cs @@ -0,0 +1,19 @@ +using System.Collections.Concurrent; + +namespace Volo.Abp.Domain.Repositories.MemoryDb +{ + public static class MemoryDatabaseManager + { + private static ConcurrentDictionary _databases; + + static MemoryDatabaseManager() + { + _databases = new ConcurrentDictionary(); + } + + public static IMemoryDatabase Get(string databaseName) + { + return _databases.GetOrAdd(databaseName, _ => new MemoryDatabase()); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs new file mode 100644 index 0000000000..b91a95d73c --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +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 : MemoryDbRepository, IMemoryDbRepository + where TMemoryDbContext : MemoryDbContext + where TEntity : class, IEntity + { + public MemoryDbRepository(IMemoryDatabaseProvider databaseProvider) + : base(databaseProvider) + { + } + } + + public class MemoryDbRepository : QueryableRepositoryBase, IMemoryDbRepository + where TMemoryDbContext : MemoryDbContext + where TEntity : class, IEntity + { + public virtual List Collection => Database.Collection(); + + public virtual IMemoryDatabase Database => DatabaseProvider.GetDatabase(); + + protected IMemoryDatabaseProvider DatabaseProvider { get; } + + public MemoryDbRepository(IMemoryDatabaseProvider databaseProvider) + { + DatabaseProvider = databaseProvider; + } + + public override TEntity Insert(TEntity entity, bool autoSave = false) + { + 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 GetQueryable() + { + return Collection.AsQueryable(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs new file mode 100644 index 0000000000..71192d03ed --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories.MemoryDb; + +namespace Volo.Abp.Domain.Repositories +{ + public static class MemoryDbCoreRepositoryExtensions + { + public static IMemoryDatabase GetDatabase(this IRepository repository) + where TEntity : class, IEntity + { + return repository.ToMemoryDbRepository().Database; + } + + public static List GetCollection(this IRepository repository) + where TEntity : class, IEntity + { + return repository.ToMemoryDbRepository().Collection; + } + + public static IMemoryDbRepository ToMemoryDbRepository(this IRepository repository) + where TEntity : class, IEntity + { + var memoryDbRepository = repository as IMemoryDbRepository; + if (memoryDbRepository == null) + { + throw new ArgumentException("Given repository does not implement " + typeof(IMemoryDbRepository).AssemblyQualifiedName, nameof(repository)); + } + + return memoryDbRepository; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs new file mode 100644 index 0000000000..7a009991d3 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Modularity; +using Volo.Abp.Uow.MemoryDb; + +namespace Volo.Abp.MemoryDb +{ + public class AbpMemoryDbModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.TryAddTransient(typeof(IMemoryDatabaseProvider<>), typeof(UnitOfWorkMemoryDatabaseProvider<>)); + services.AddAssemblyOf(); + } + } +} diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs new file mode 100644 index 0000000000..240dd4803b --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/IMemoryDbContextRegistrationOptionsBuilder.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Data; + +namespace Volo.Abp.MemoryDb.DependencyInjection +{ + public interface IMemoryDbContextRegistrationOptionsBuilder : ICommonDbContextRegistrationOptionsBuilder + { + + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs new file mode 100644 index 0000000000..59901ab4b1 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Data; + +namespace Volo.Abp.MemoryDb.DependencyInjection +{ + public class MemoryDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMemoryDbContextRegistrationOptionsBuilder + { + + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbRepositoryRegistrar.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbRepositoryRegistrar.cs new file mode 100644 index 0000000000..bf0d7dc011 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbRepositoryRegistrar.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Repositories.MemoryDb; + +namespace Volo.Abp.MemoryDb.DependencyInjection +{ + public class MemoryDbRepositoryRegistrar : RepositoryRegistrarBase + { + public MemoryDbRepositoryRegistrar(MemoryDbContextRegistrationOptions options) + : base(options) + { + } + + protected override IEnumerable GetEntityTypes(Type dbContextType) + { + var memoryDbContext = (MemoryDbContext)Activator.CreateInstance(dbContextType); + return memoryDbContext.GetEntityTypes(); + } + + protected override Type GetRepositoryTypeForDefaultPk(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); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs new file mode 100644 index 0000000000..ad4456c793 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Domain.Repositories.MemoryDb; + +namespace Volo.Abp.MemoryDb +{ + public interface IMemoryDatabaseProvider + where TMemoryDbContext : MemoryDbContext + { + TMemoryDbContext DbContext { get; } + + IMemoryDatabase GetDatabase(); + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/MemoryDbContext.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/MemoryDbContext.cs new file mode 100644 index 0000000000..8b7093d41b --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/MemoryDbContext.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.MemoryDb +{ + public abstract class MemoryDbContext + { + private static readonly Type[] EmptyTypeList = new Type[0]; + + public virtual IReadOnlyList GetEntityTypes() + { + return EmptyTypeList; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/MemoryDbDatabaseApi.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/MemoryDbDatabaseApi.cs new file mode 100644 index 0000000000..90c5a49fc9 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/MemoryDbDatabaseApi.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Domain.Repositories.MemoryDb; + +namespace Volo.Abp.Uow.MemoryDb +{ + public class MemoryDbDatabaseApi: IDatabaseApi + { + public IMemoryDatabase Database { get; } + + public MemoryDbDatabaseApi(IMemoryDatabase database) + { + Database = database; + } + } +} diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs new file mode 100644 index 0000000000..386ec77b12 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs @@ -0,0 +1,45 @@ +using Volo.Abp.Data; +using Volo.Abp.Domain.Repositories.MemoryDb; +using Volo.Abp.MemoryDb; + +namespace Volo.Abp.Uow.MemoryDb +{ + public class UnitOfWorkMemoryDatabaseProvider : IMemoryDatabaseProvider + where TMemoryDbContext : MemoryDbContext + { + public TMemoryDbContext DbContext { get; } + + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly IConnectionStringResolver _connectionStringResolver; + + public UnitOfWorkMemoryDatabaseProvider( + IUnitOfWorkManager unitOfWorkManager, + IConnectionStringResolver connectionStringResolver, + TMemoryDbContext dbContext) + { + _unitOfWorkManager = unitOfWorkManager; + _connectionStringResolver = connectionStringResolver; + DbContext = dbContext; + } + + public IMemoryDatabase GetDatabase() + { + var unitOfWork = _unitOfWorkManager.Current; + if (unitOfWork == null) + { + throw new AbpException($"A {nameof(IMemoryDatabase)} instance can only be created inside a unit of work!"); + } + + var connectionString = _connectionStringResolver.Resolve(); + var dbContextKey = $"{typeof(TMemoryDbContext).FullName}_{connectionString}"; + + var databaseApi = unitOfWork.GetOrAddDatabaseApi( + dbContextKey, + () => new MemoryDbDatabaseApi( + MemoryDatabaseManager.Get(connectionString) + )); + + return ((MemoryDbDatabaseApi)databaseApi).Database; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/EfCoreRepositoryRegistrar.cs b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbRepositoryRegistrar.cs similarity index 100% rename from src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/EfCoreRepositoryRegistrar.cs rename to src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbRepositoryRegistrar.cs diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDatabaseProvider.cs b/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDatabaseProvider.cs index 5212f8550b..e1e79ee25d 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDatabaseProvider.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDatabaseProvider.cs @@ -27,7 +27,7 @@ namespace Volo.Abp.Uow.MongoDB var unitOfWork = _unitOfWorkManager.Current; if (unitOfWork == null) { - throw new AbpException("A IMongoDatabase instance can only be created inside a unit of work!"); + throw new AbpException($"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!"); } var connectionString = _connectionStringResolver.Resolve(); diff --git a/src/Volo.Abp.TestBase/AbpIntegratedTest.cs b/src/Volo.Abp.TestBase/AbpIntegratedTest.cs index a5a4e4e8a7..802ba0ae47 100644 --- a/src/Volo.Abp.TestBase/AbpIntegratedTest.cs +++ b/src/Volo.Abp.TestBase/AbpIntegratedTest.cs @@ -1,6 +1,8 @@ using System; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; +using Volo.Abp.Uow; +using System.Threading.Tasks; namespace Volo.Abp.TestBase { @@ -55,6 +57,37 @@ namespace Volo.Abp.TestBase return services.BuildServiceProviderFromFactory(); } + + protected virtual void UseUnitOfWork(Action action) + { + using (IServiceScope scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin()) + { + action(); + + uow.Complete(); + } + } + } + + protected virtual async Task UseUnitOfWorkAsync(Func action) + { + using (IServiceScope scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin()) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + public void Dispose() { Application.Shutdown(); diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj b/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj new file mode 100644 index 0000000000..0a6a06fb65 --- /dev/null +++ b/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.0 + Volo.Abp.MemoryDb.Tests + Volo.Abp.MemoryDb.Tests + true + false + false + false + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs new file mode 100644 index 0000000000..790e105b1d --- /dev/null +++ b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs @@ -0,0 +1,31 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.MemoryDb; +using Volo.Abp.Data; +using Volo.Abp.Autofac; +using Volo.Abp.TestApp; + +namespace Volo.Abp.MemoryDb +{ + [DependsOn(typeof(TestAppModule), typeof(AbpMemoryDbModule), typeof(AbpAutofacModule))] + public class AbpMemoryDbTestModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + var connStr = Guid.NewGuid().ToString(); + + services.Configure(options => + { + options.ConnectionStrings.Default = connStr; + }); + + services.AddMemoryDbContext(options => + { + options.WithDefaultRepositories(); + }); + + services.AddAssemblyOf(); + } + } +} diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/MemoryDbTestBase.cs b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/MemoryDbTestBase.cs new file mode 100644 index 0000000000..081dda8d4b --- /dev/null +++ b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/MemoryDbTestBase.cs @@ -0,0 +1,12 @@ +using Volo.Abp.TestBase; + +namespace Volo.Abp.MemoryDb.Repositories +{ + public abstract class MemoryDbTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/MemoryDb_Basic_Repository_Tests.cs b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/MemoryDb_Basic_Repository_Tests.cs new file mode 100644 index 0000000000..b20ba5c118 --- /dev/null +++ b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/MemoryDb_Basic_Repository_Tests.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.TestApp.Domain; +using Xunit; +using System.Linq; + +namespace Volo.Abp.MemoryDb.Repositories +{ + public class MemoryDb_Basic_Repository_Tests : MemoryDbTestBase + { + private readonly IQueryableRepository _personRepository; + + public MemoryDb_Basic_Repository_Tests() + { + _personRepository = ServiceProvider.GetRequiredService>(); + } + + [Fact] + public void GetList() + { + var people = _personRepository.GetList(); + people.Count.ShouldBeGreaterThan(0); + } + + [Fact] + public void Insert() + { + //Arrange + var name = Guid.NewGuid().ToString(); + + //Act + _personRepository.Insert(new Person(name, 42)); + + //Assert + UseUnitOfWork(() => + { + _personRepository.FirstOrDefault(p => p.Name == name).ShouldNotBeNull(); + }); + } + } +} diff --git a/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/TestAppMemoryDbContext.cs b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/TestAppMemoryDbContext.cs new file mode 100644 index 0000000000..74c08bcb5c --- /dev/null +++ b/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/TestAppMemoryDbContext.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.MemoryDb; +using Volo.Abp.TestApp.Domain; + +namespace Volo.Abp.TestApp.MemoryDb +{ + public class TestAppMemoryDbContext : MemoryDbContext + { + private static readonly Type[] EntityTypeList = new Type[] + { + typeof(Person) + }; + + public override IReadOnlyList GetEntityTypes() + { + return EntityTypeList; + } + } +} diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs index 7c6f9f91f1..78a8aabf9d 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs @@ -1,6 +1,8 @@ -namespace App +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.TestApp.Domain { - public class Person + public class Person : AggregateRoot { public string Name { get; set; } diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonAppService.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonAppService.cs index 9ec516dc5f..d50219b2ce 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonAppService.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonAppService.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Volo.Abp.Application.Services; -namespace App +namespace Volo.Abp.TestApp.Domain { public class PersonAppService : ApplicationService { diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs new file mode 100644 index 0000000000..25790a999f --- /dev/null +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.Domain; + +namespace Volo.Abp.TestApp +{ + public class TestAppModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.AddAssemblyOf(); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + using(IServiceScope scope = context.ServiceProvider.CreateScope()) + { + var personRepository = scope.ServiceProvider.GetRequiredService>(); + personRepository.Insert(new Person("Douglas", 42)); + } + } + } +}