Improve UOW event order and add tests

pull/625/head
Halil ibrahim Kalkan 7 years ago
parent 08f50d0ff2
commit 6a8832a8ab

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

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

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

@ -23,9 +23,10 @@ namespace Volo.Abp.Uow
{
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();
@ -86,7 +87,7 @@ namespace Volo.Abp.Uow
var uow = _ambientUnitOfWork.UnitOfWork;
//Skip reserved unit of work
while (uow != null && uow.IsReserved)
while (uow != null && (uow.IsReserved || uow.IsDisposed || uow.IsCompleted))
{
uow = uow.Outer;
}

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

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

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

@ -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