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 index 3b9ca358bf..7cbaf15e70 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDatabase.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDatabase.cs @@ -5,5 +5,7 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb public interface IMemoryDatabase { List Collection(); + + TPrimaryKey GenerateNextId(); } } \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/InMemoryIdGenerator.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/InMemoryIdGenerator.cs new file mode 100644 index 0000000000..1741d2cc02 --- /dev/null +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/InMemoryIdGenerator.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading; + +namespace Volo.Abp.Domain.Repositories.MemoryDb +{ + internal class InMemoryIdGenerator + { + private int _lastInt; + private long _lastLong; + + public TPrimaryKey GenerateNext() + { + if (typeof(TPrimaryKey) == typeof(Guid)) + { + return (TPrimaryKey)(object)Guid.NewGuid(); + } + + if (typeof(TPrimaryKey) == typeof(int)) + { + return (TPrimaryKey)(object)Interlocked.Increment(ref _lastInt); + } + + if (typeof(TPrimaryKey) == typeof(long)) + { + return (TPrimaryKey)(object)Interlocked.Increment(ref _lastLong); + } + + throw new AbpException("Not supported PrimaryKey type: " + typeof(TPrimaryKey).FullName); + } + } +} \ No newline at end of file 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 index dc6c6ffc99..332138eae2 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabase.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDatabase.cs @@ -8,16 +8,24 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb { private readonly ConcurrentDictionary _sets; - private readonly object _syncObj = new object(); + private readonly ConcurrentDictionary _idGenerators; public MemoryDatabase() { _sets = new ConcurrentDictionary(); + _idGenerators = new ConcurrentDictionary(); } public List Collection() { return _sets.GetOrAdd(typeof(TEntity), _ => new List()) as List; } + + public TPrimaryKey GenerateNextId() + { + return _idGenerators + .GetOrAdd(typeof(TEntity), () => new InMemoryIdGenerator()) + .GenerateNext(); + } } } \ 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 index 78075b6752..93be92bd09 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs @@ -33,10 +33,22 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb public override TEntity Insert(TEntity entity, bool autoSave = false) { + SetIdIfNeeded(entity); Collection.Add(entity); return entity; } + private void SetIdIfNeeded(TEntity entity) + { + if (typeof(TPrimaryKey) == typeof(int) || typeof(TPrimaryKey) == typeof(long) || typeof(TPrimaryKey) == typeof(Guid)) + { + if (entity.IsTransient()) + { + entity.Id = Database.GenerateNextId(); + } + } + } + public override TEntity Update(TEntity entity) { return entity; diff --git a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs index 5684bfbb9f..9174e912c5 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs @@ -153,5 +153,28 @@ namespace Volo.Abp.AspNetCore.Mvc personInDb.ShouldNotBeNull(); personInDb.Phones.Any(p => p.Number == phoneNumberToAdd).ShouldBeTrue(); } + + [Fact] + public async Task GetPhones_Test() + { + var douglas = _personRepository.GetList().First(p => p.Name == "Douglas"); + + //Ideally should be [GET] /api/person/{id}/phones?type=office + var result = await GetResponseAsObjectAsync>("/api/services/app/person/GetPhones?id=" + douglas.Id); + result.Items.Count.ShouldBe(douglas.Phones.Count); + } + + [Fact] + public async Task DeletePhone_Test() + { + var douglas = _personRepository.GetList().First(p => p.Name == "Douglas"); + var firstPhone = douglas.Phones.First(); + + //Ideally should be [DELETE] /api/app/person/{id} + await Client.DeleteAsync("/api/services/app/person/DeletePhone?id=" + douglas.Id + "&phoneId=" + firstPhone.Id); + + douglas = _personRepository.GetList().First(p => p.Name == "Douglas"); + douglas.Phones.Any(p => p.Id == firstPhone.Id).ShouldBeFalse(); + } } } diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPersonAppService.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPersonAppService.cs index 6a44aa4d73..2643bcab6f 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPersonAppService.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPersonAppService.cs @@ -7,7 +7,6 @@ namespace Volo.Abp.TestApp.Application { public interface IPersonAppService : IAsyncCrudAppService { - //URL: [GET] /api/people/{id}?type=office Task> GetPhones(Guid id, GetPersonPhonesFilter filter); Task AddPhone(Guid id, PhoneDto phoneDto); diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs index d5b7eb8c3f..4bfec673bf 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs @@ -16,7 +16,15 @@ namespace Volo.Abp.TestApp public void Build() { - _personRepository.Insert(new Person(Guid.NewGuid(), "Douglas", 42)); + AddPeople(); + } + + private void AddPeople() + { + var douglas = new Person(Guid.NewGuid(), "Douglas", 42); + douglas.Phones.Add(new Phone(douglas.Id, "123456789")); + douglas.Phones.Add(new Phone(douglas.Id, "123456780", PhoneType.Home)); + _personRepository.Insert(douglas); } } } \ No newline at end of file