Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
Some of UseUow and CorrelatingBy added to StoveComponentBase
Browse files Browse the repository at this point in the history
  • Loading branch information
trendyol-bot committed Jan 30, 2018
1 parent 82d3f5b commit 31de56b
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 55 deletions.
2 changes: 1 addition & 1 deletion common.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.3.1</VersionPrefix>
<VersionPrefix>2.3.2</VersionPrefix>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>https://raw.githubusercontent.com/osoykan/Stove/master/stove.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/osoykan/Stove</PackageProjectUrl>
Expand Down
114 changes: 102 additions & 12 deletions src/Stove/StoveComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Stove.Log;
using Stove.MQ;
using Stove.ObjectMapping;
using Stove.Threading.Extensions;

namespace Stove
{
Expand Down Expand Up @@ -68,7 +69,7 @@ public IUnitOfWorkManager UnitOfWorkManager
public IMessageBus MessageBus { get; set; }

/// <summary>
/// The <see cref="CommandContext" /> accessor
/// The <see cref="CommandContext" /> accessor
/// </summary>
public IStoveCommandContextAccessor CommandContextAccessor { get; set; }

Expand All @@ -80,6 +81,14 @@ protected void CorrelatingBy(Action act, string correlationId)
}
}

protected TResponse CorrelatingBy<TResponse>(Func<TResponse> func, string correlationId)
{
using (CommandContextAccessor.Use(correlationId))
{
return func();
}
}

protected Task CorrelatingBy(Func<Task> func, string correlationId)
{
using (CommandContextAccessor.Use(correlationId))
Expand All @@ -88,6 +97,14 @@ protected Task CorrelatingBy(Func<Task> func, string correlationId)
}
}

protected Task<TResponse> CorrelatingBy<TResponse>(Func<Task<TResponse>> func, string correlationId)
{
using (CommandContextAccessor.Use(correlationId))
{
return func();
}
}

protected void UseUow(Action act, Action<UnitOfWorkOptions> optsCallback = null)
{
var options = new UnitOfWorkOptions();
Expand All @@ -102,21 +119,51 @@ protected void UseUow(Action act, Action<UnitOfWorkOptions> optsCallback = null)
}
}

protected Task UseUow(Func<Task> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
protected TResponse UseUow<TResponse>(Func<TResponse> func, Action<UnitOfWorkOptions> optsCallback = null)
{
var options = new UnitOfWorkOptions();

optsCallback?.Invoke(options);

TResponse response;
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
response = func();

uow.Complete();
}

return response;
}

protected async Task UseUow(Func<Task> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
{
var options = new UnitOfWorkOptions();

optsAction?.Invoke(options);

Task task;
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
task = func();
await func().NotOnCapturedContext();

uow.CompleteAsync(cancellationToken);
await uow.CompleteAsync(cancellationToken).NotOnCapturedContext();
}
}

protected async Task<TResponse> UseUow<TResponse>(Func<Task<TResponse>> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
{
var options = new UnitOfWorkOptions();
optsAction?.Invoke(options);

return task;
TResponse response;
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
response = await func().NotOnCapturedContext();

await uow.CompleteAsync(cancellationToken).NotOnCapturedContext();
}

return response;
}

protected void UseUowIfNot(Action act, Action<UnitOfWorkOptions> optsAction = null)
Expand All @@ -139,27 +186,70 @@ protected void UseUowIfNot(Action act, Action<UnitOfWorkOptions> optsAction = nu
}
}

protected Task UseUowIfNot(Func<Task> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
protected TResponse UseUowIfNot<TResponse>(Func<TResponse> func, Action<UnitOfWorkOptions> optsAction = null)
{
var options = new UnitOfWorkOptions();
optsAction?.Invoke(options);

TResponse response;
if (UnitOfWorkManager.Current == null)
{
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
response = func();

uow.Complete();
}
}
else
{
response = func();
}

return response;
}

protected async Task UseUowIfNot(Func<Task> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
{
var options = new UnitOfWorkOptions();
optsAction?.Invoke(options);

if (UnitOfWorkManager.Current == null)
{
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
await func().NotOnCapturedContext();

await uow.CompleteAsync(cancellationToken).NotOnCapturedContext();
}
}
else
{
await func().NotOnCapturedContext();
}
}

protected async Task<TResponse> UseUowIfNot<TResponse>(Func<Task<TResponse>> func, Action<UnitOfWorkOptions> optsAction = null, CancellationToken cancellationToken = default)
{
var options = new UnitOfWorkOptions();
optsAction?.Invoke(options);

Task task;
TResponse response;
if (UnitOfWorkManager.Current == null)
{
using (IUnitOfWorkCompleteHandle uow = UnitOfWorkManager.Begin(options))
{
task = func();
response = await func().NotOnCapturedContext();

uow.CompleteAsync(cancellationToken);
await uow.CompleteAsync(cancellationToken).NotOnCapturedContext();
}
}
else
{
task = func();
response = await func().NotOnCapturedContext();
}

return task;
return response;
}

protected void OnUowCompleted(Action action)
Expand Down
27 changes: 27 additions & 0 deletions src/Stove/Threading/Extensions/TaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace Stove.Threading.Extensions
{
/// <summary>
/// Represents extensions on Tasks.
/// </summary>
public static class TaskExtensions
{
/// <summary>
/// ConfigureAwait(false)
/// </summary>
public static ConfiguredTaskAwaitable NotOnCapturedContext(this Task task)
{
return task.ConfigureAwait(false);
}

/// <summary>
/// ConfigureAwait(false)
/// </summary>
public static ConfiguredTaskAwaitable<T> NotOnCapturedContext<T>(this Task<T> task)
{
return task.ConfigureAwait(false);
}
}
}
51 changes: 10 additions & 41 deletions test/Stove.Tests.SampleApplication/Domain/SomeDomainService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,15 @@ public SomeDomainService(IRepository<User> repository, IRepository<Message> mess
public User GetUserByName(string name)
{
User user = null;
UseUow(() =>
{
user = _repository.FirstOrDefault(x => x.Name == name);
});
UseUow(() => { user = _repository.FirstOrDefault(x => x.Name == name); });

return user;
}

public async Task<User> GetUserByName_async(string name)
{
User user = null;
await UseUow(async () =>
{
user = await _repository.FirstOrDefaultAsync(x => x.Name == name);
}, options => { }, CancellationToken.None);
await UseUow(async () => { user = await _repository.FirstOrDefaultAsync(x => x.Name == name); }, options => { }, CancellationToken.None);

return user;
}
Expand All @@ -45,10 +39,7 @@ public async Task<User> GetUserByName_async_With_IsolationLevel(string name)
{
User user = null;

await UseUow(async () =>
{
user = await _repository.FirstOrDefaultAsync(x => x.Name == name);
}, options => { options.IsolationLevel = IsolationLevel.ReadCommitted; });
await UseUow(async () => { user = await _repository.FirstOrDefaultAsync(x => x.Name == name); }, options => { options.IsolationLevel = IsolationLevel.ReadCommitted; });

return user;
}
Expand All @@ -57,10 +48,7 @@ public User GetUserByName_with_isolationlevel(string name)
{
User user = null;

UseUow(() =>
{
user = _repository.FirstOrDefault(x => x.Name == name);
}, options => { options.IsolationLevel = IsolationLevel.Chaos; });
UseUow(() => { user = _repository.FirstOrDefault(x => x.Name == name); }, options => { options.IsolationLevel = IsolationLevel.Chaos; });

return user;
}
Expand All @@ -69,45 +57,26 @@ public User GetUserByName_isTransactional(string name)
{
User user = null;

UseUow(() =>
{
user = _repository.FirstOrDefault(x => x.Name == name);
});
UseUow(() => { user = _repository.FirstOrDefault(x => x.Name == name); });

return user;
}

public async Task<User> GetUserByName_async_isTransactional(string name)
public Task<User> GetUserByName_async_isTransactional(string name)
{
User user = null;

await UseUow(async () =>
{
user = await _repository.FirstOrDefaultAsync(x => x.Name == name);
});

return user;
return UseUow<User>(() => { return _repository.FirstOrDefaultAsync(x => x.Name == name); });
}

public async Task<Message> CreateMessageAndGet(string message)
{
Message msg = null;
await UseUowIfNot(async () =>
{
msg = await _messageRepository.InsertAsync(new Message(message));
});

return msg;
return await UseUowIfNot<Message>(async () => await _messageRepository.InsertAsync(new Message(message)));
}

public Task CreateUserByCorrelating(string name, string surname, string email, string correlationId)
public Task<User> CreateUserByCorrelating(string name, string surname, string email, string correlationId)
{
return CorrelatingBy(() =>
{
return UseUow(() =>
{
return _repository.InsertAsync(User.Create(name, surname, email));
});
return UseUow<User>(() => _repository.InsertAsync(User.Create(name, surname, email)));
}, correlationId);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public async Task UseUow_and_correlatingBy_should_work()
string correlationId = Guid.NewGuid().ToString();
The<IEventBus>().Register<UserCreatedEvent>((@event, headers) =>
{
headers[StoveConsts.Events.CorrelationId].ShouldBe(correlationId);
headers[StoveConsts.Events.CausationId].ShouldBe(correlationId);
});

await The<SomeDomainService>().CreateUserByCorrelating("oguzhan", "soykan", "[email protected]", correlationId);
Expand Down

0 comments on commit 31de56b

Please sign in to comment.