Refactored and improved UOW. Added simple UOW middleware. Created a unit test for UOW.

pull/112/head
Halil İbrahim Kalkan 8 years ago
parent f7a8c8cb14
commit 790ed478da

@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.Uow;
namespace Volo.Abp.AspNetCore.Mvc.Uow
{
class AbpUnitOfWorkMiddleware
{
private readonly RequestDelegate _next;
public AbpUnitOfWorkMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext, IUnitOfWorkManager unitOfWorkManager)
{
using (var uow = unitOfWorkManager.Begin())
{
await _next(httpContext);
await uow.CompleteAsync();
}
}
}
}

@ -6,18 +6,18 @@ namespace Volo.Abp.Uow
[ExposeServices(typeof(IAmbientUnitOfWork), typeof(IUnitOfWorkAccessor))]
public class AmbientUnitOfWork : IAmbientUnitOfWork, ISingletonDependency
{
public IUnitOfWork UnitOfWork => _currentUowInfo.Value;
public IUnitOfWork UnitOfWork => _currentUow.Value;
private readonly AsyncLocal<IUnitOfWork> _currentUowInfo;
private readonly AsyncLocal<IUnitOfWork> _currentUow;
public AmbientUnitOfWork()
{
_currentUowInfo = new AsyncLocal<IUnitOfWork>();
_currentUow = new AsyncLocal<IUnitOfWork>();
}
public void SetUnitOfWork(IUnitOfWork unitOfWork)
{
_currentUowInfo.Value = unitOfWork;
_currentUow.Value = unitOfWork;
}
}
}

@ -7,6 +7,8 @@ namespace Volo.Abp.Uow
{
internal class ChildUnitOfWork : IUnitOfWork
{
public Guid Id => _parent.Id;
public event EventHandler Completed;
public event EventHandler<UnitOfWorkFailedEventArgs> Failed;
public event EventHandler Disposed;
@ -60,5 +62,10 @@ namespace Volo.Abp.Uow
{
}
public override string ToString()
{
return $"[UnitOfWork {Id}]";
}
}
}

@ -7,6 +7,8 @@ namespace Volo.Abp.Uow
//TODO: Find a better naming :(
public interface IBasicUnitOfWork : IDisposable
{
Guid Id { get; }
event EventHandler Completed;
event EventHandler<UnitOfWorkFailedEventArgs> Failed;

@ -10,6 +10,6 @@ namespace Volo.Abp.Uow
IDatabaseApi FindDatabaseApi([NotNull] string id);
[NotNull]
IDatabaseApi GetOrAddDatabaseApi(string id, Func<IDatabaseApi> factory);
IDatabaseApi GetOrAddDatabaseApi([NotNull] string id, [NotNull] Func<IDatabaseApi> factory);
}
}

@ -8,6 +8,8 @@ namespace Volo.Abp.Uow
{
public class UnitOfWork : IUnitOfWork, ITransientDependency
{
public Guid Id { get; } = Guid.NewGuid();
public event EventHandler Completed;
public event EventHandler<UnitOfWorkFailedEventArgs> Failed;
public event EventHandler Disposed;
@ -27,23 +29,6 @@ namespace Volo.Abp.Uow
_databaseApis = new Dictionary<string, IDatabaseApi>();
}
public void Dispose()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
if (!_isCompleted || _exception != null)
{
OnFailed(_exception);
}
OnDisposed();
}
public void SaveChanges()
{
foreach (var databaseApi in _databaseApis.Values)
@ -122,6 +107,23 @@ namespace Volo.Abp.Uow
Disposed.InvokeSafely(this);
}
public void Dispose()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
if (!_isCompleted || _exception != null)
{
OnFailed(_exception);
}
OnDisposed();
}
private void PreventMultipleComplete()
{
if (_isCompleted)
@ -131,5 +133,10 @@ namespace Volo.Abp.Uow
_isCompleted = true;
}
public override string ToString()
{
return $"[UnitOfWork {Id}]";
}
}
}

@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
@ -41,27 +40,13 @@ namespace Volo.Abp.Uow
_ambientUnitOfWork.SetUnitOfWork(unitOfWork);
Debug.Assert(
_ambientUnitOfWork.UnitOfWork != null,
"_ambientUnitOfWork.UnitOfWork can not be null since it's set by _ambientUnitOfWork.SetUnitOfWork method!"
);
unitOfWork.Completed += (sender, args) =>
{
_ambientUnitOfWork.SetUnitOfWork(parentUow);
};
unitOfWork.Failed += (sender, args) =>
{
_ambientUnitOfWork.SetUnitOfWork(parentUow);
};
unitOfWork.Disposed += (sender, args) =>
{
_ambientUnitOfWork.SetUnitOfWork(parentUow);
scope.Dispose();
};
return _ambientUnitOfWork.UnitOfWork;
return unitOfWork;
}
}
}

@ -0,0 +1,43 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Modularity;
using Volo.Abp.TestBase;
using Xunit;
namespace Volo.Abp.Uow
{
public class UnitOfWork_Ambient_Scope_Tests : AbpIntegratedTest<IndependentEmptyModule>
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
public UnitOfWork_Ambient_Scope_Tests()
{
_unitOfWorkManager = ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
}
[Fact]
public async Task UnitOfWorkManager_Current_Should_Set_Correctly()
{
_unitOfWorkManager.Current.ShouldBeNull();
using (var uow1 = _unitOfWorkManager.Begin())
{
_unitOfWorkManager.Current.ShouldNotBeNull();
_unitOfWorkManager.Current.ShouldBe(uow1);
using (var uow2 = _unitOfWorkManager.Begin())
{
_unitOfWorkManager.Current.ShouldNotBeNull();
_unitOfWorkManager.Current.Id.ShouldBe(uow1.Id);
await uow2.CompleteAsync();
}
await uow1.CompleteAsync();
}
_unitOfWorkManager.Current.ShouldBeNull();
}
}
}
Loading…
Cancel
Save