Browse Source

Improve UOW event order and add tests

pull/625/head
Halil ibrahim Kalkan 8 years ago
parent
commit
6a8832a8ab
  1. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs
  2. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs
  3. 22
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
  4. 7
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs
  5. 7
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs
  6. 9
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs
  7. 9
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs
  8. 40
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Uow_Completed_Tests.cs

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs

@ -15,6 +15,10 @@ namespace Volo.Abp.Uow
public bool IsReserved => _parent.IsReserved; public bool IsReserved => _parent.IsReserved;
public bool IsDisposed => _parent.IsDisposed;
public bool IsCompleted => _parent.IsCompleted;
public string ReservationName => _parent.ReservationName; public string ReservationName => _parent.ReservationName;
public event EventHandler<UnitOfWorkFailedEventArgs> Failed; public event EventHandler<UnitOfWorkFailedEventArgs> Failed;

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs

@ -20,6 +20,10 @@ namespace Volo.Abp.Uow
bool IsReserved { get; } bool IsReserved { get; }
bool IsDisposed { get; }
bool IsCompleted { get; }
string ReservationName { get; } string ReservationName { get; }
void SetOuter([CanBeNull] IUnitOfWork outer); void SetOuter([CanBeNull] IUnitOfWork outer);

22
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs

@ -18,6 +18,10 @@ namespace Volo.Abp.Uow
public bool IsReserved { get; set; } public bool IsReserved { get; set; }
public bool IsDisposed { get; private set; }
public bool IsCompleted { get; private set; }
public string ReservationName { get; set; } public string ReservationName { get; set; }
protected List<Func<Task>> CompletedHandlers { get; } = new List<Func<Task>>(); protected List<Func<Task>> CompletedHandlers { get; } = new List<Func<Task>>();
@ -32,8 +36,7 @@ namespace Volo.Abp.Uow
private readonly UnitOfWorkDefaultOptions _defaultOptions; private readonly UnitOfWorkDefaultOptions _defaultOptions;
private Exception _exception; private Exception _exception;
private bool _isCompleted; private bool _isCompleting;
private bool _isDisposed;
private bool _isRolledback; private bool _isRolledback;
public UnitOfWork(IServiceProvider serviceProvider, IOptions<UnitOfWorkDefaultOptions> options) public UnitOfWork(IServiceProvider serviceProvider, IOptions<UnitOfWorkDefaultOptions> options)
@ -101,8 +104,10 @@ namespace Volo.Abp.Uow
try try
{ {
_isCompleting = true;
SaveChanges(); SaveChanges();
CommitTransactions(); CommitTransactions();
IsCompleted = true;
OnCompleted(); OnCompleted();
} }
catch (Exception ex) catch (Exception ex)
@ -123,8 +128,10 @@ namespace Volo.Abp.Uow
try try
{ {
_isCompleting = true;
await SaveChangesAsync(cancellationToken); await SaveChangesAsync(cancellationToken);
await CommitTransactionsAsync(); await CommitTransactionsAsync();
IsCompleted = true;
await OnCompletedAsync(); await OnCompletedAsync();
} }
catch (Exception ex) catch (Exception ex)
@ -250,16 +257,16 @@ namespace Volo.Abp.Uow
public virtual void Dispose() public virtual void Dispose()
{ {
if (_isDisposed) if (IsDisposed)
{ {
return; return;
} }
_isDisposed = true; IsDisposed = true;
DisposeTransactions(); DisposeTransactions();
if (!_isCompleted || _exception != null) if (!IsCompleted || _exception != null)
{ {
OnFailed(); OnFailed();
} }
@ -283,15 +290,12 @@ namespace Volo.Abp.Uow
private void PreventMultipleComplete() private void PreventMultipleComplete()
{ {
if (_isCompleted) if (IsCompleted || _isCompleting)
{ {
throw new AbpException("Complete is called before!"); throw new AbpException("Complete is called before!");
} }
_isCompleted = true;
} }
protected virtual void RollbackAll() protected virtual void RollbackAll()
{ {
foreach (var databaseApi in _databaseApis.Values) foreach (var databaseApi in _databaseApis.Values)

7
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs

@ -23,9 +23,10 @@ namespace Volo.Abp.Uow
{ {
Check.NotNull(options, nameof(options)); Check.NotNull(options, nameof(options));
if (!requiresNew && _ambientUnitOfWork.UnitOfWork != null && !_ambientUnitOfWork.UnitOfWork.IsReserved) var currentUow = Current;
if (currentUow != null && !requiresNew)
{ {
return new ChildUnitOfWork(_ambientUnitOfWork.UnitOfWork); return new ChildUnitOfWork(currentUow);
} }
var unitOfWork = CreateNewUnitOfWork(); var unitOfWork = CreateNewUnitOfWork();
@ -86,7 +87,7 @@ namespace Volo.Abp.Uow
var uow = _ambientUnitOfWork.UnitOfWork; var uow = _ambientUnitOfWork.UnitOfWork;
//Skip reserved unit of work //Skip reserved unit of work
while (uow != null && uow.IsReserved) while (uow != null && (uow.IsReserved || uow.IsDisposed || uow.IsCompleted))
{ {
uow = uow.Outer; uow = uow.Outer;
} }

7
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs

@ -1,9 +1,4 @@
using System; namespace Volo.Abp.EntityFrameworkCore
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.EntityFrameworkCore
{ {
public abstract class EntityFrameworkCoreTestBase : AbpIntegratedTest<AbpEntityFrameworkCoreTestModule> public abstract class EntityFrameworkCoreTestBase : AbpIntegratedTest<AbpEntityFrameworkCoreTestModule>
{ {

9
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.EntityFrameworkCore.Uow
{
public class Uow_Completed_Tests : Uow_Completed_Tests<AbpEntityFrameworkCoreTestModule>
{
}
}

9
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MongoDB.Uow
{
public class Uow_Completed_Tests : Uow_Completed_Tests<AbpMongoDbTestModule>
{
}
}

40
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Uow_Completed_Tests.cs

@ -0,0 +1,40 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.Uow;
using Xunit;
namespace Volo.Abp.TestApp.Testing
{
public abstract class Uow_Completed_Tests<TStartupModule> : TestAppTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly ICityRepository _cityRepository;
protected Uow_Completed_Tests()
{
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>();
_cityRepository = GetRequiredService<ICityRepository>();
}
[Fact]
public async Task Should_Be_Able_To_Perform_Database_Operation_On_Uow_Complete()
{
using (var uow = _unitOfWorkManager.Begin())
{
//Perform an arbitrary database operation
await _cityRepository.InsertAsync(new City(Guid.NewGuid(), Guid.NewGuid().ToString()));
uow.OnCompleted(async () =>
{
//Perform another database operation inside the OnCompleted handler
await _cityRepository.InsertAsync(new City(Guid.NewGuid(), Guid.NewGuid().ToString()));
});
await uow.CompleteAsync();
}
}
}
}
Loading…
Cancel
Save