Unverified Commit feea8d61 authored by Steve Smith's avatar Steve Smith Committed by GitHub

Converted domain events to async (#81)

parent 005493c9
using Ardalis.GuardClauses;
using System.Threading.Tasks;
using Ardalis.GuardClauses;
using CleanArchitecture.Core.Events;
using CleanArchitecture.Core.Interfaces;
......@@ -6,11 +7,13 @@ namespace CleanArchitecture.Core.Services
{
public class ItemCompletedEmailNotificationHandler : IHandle<ToDoItemCompletedEvent>
{
public void Handle(ToDoItemCompletedEvent domainEvent)
public Task Handle(ToDoItemCompletedEvent domainEvent)
{
Guard.Against.Null(domainEvent, nameof(domainEvent));
// Do Nothing
return Task.CompletedTask;
}
}
}
using CleanArchitecture.Core.SharedKernel;
using System.Threading.Tasks;
using CleanArchitecture.Core.SharedKernel;
namespace CleanArchitecture.Core.Interfaces
{
public interface IDomainEventDispatcher
{
void Dispatch(BaseDomainEvent domainEvent);
Task Dispatch(BaseDomainEvent domainEvent);
}
}
\ No newline at end of file
using CleanArchitecture.Core.SharedKernel;
using System.Threading.Tasks;
using CleanArchitecture.Core.SharedKernel;
namespace CleanArchitecture.Core.Interfaces
{
public interface IHandle<T> where T : BaseDomainEvent
public interface IHandle<in T> where T : BaseDomainEvent
{
void Handle(T domainEvent);
Task Handle(T domainEvent);
}
}
\ No newline at end of file
using CleanArchitecture.Core.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.Core.SharedKernel;
using Ardalis.EFCore.Extensions;
......@@ -35,9 +37,9 @@ namespace CleanArchitecture.Infrastructure.Data
//modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
public override int SaveChanges()
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
int result = base.SaveChanges();
int result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
// ignore events if no dispatcher provided
if (_dispatcher == null) return result;
......@@ -54,11 +56,16 @@ namespace CleanArchitecture.Infrastructure.Data
entity.Events.Clear();
foreach (var domainEvent in events)
{
_dispatcher.Dispatch(domainEvent);
await _dispatcher.Dispatch(domainEvent).ConfigureAwait(false);
}
}
return result;
}
public override int SaveChanges()
{
return SaveChangesAsync().GetAwaiter().GetResult();
}
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CleanArchitecture.Infrastructure.DomainEvents
{
......@@ -19,7 +20,7 @@ namespace CleanArchitecture.Infrastructure.DomainEvents
_container = container;
}
public void Dispatch(BaseDomainEvent domainEvent)
public async Task Dispatch(BaseDomainEvent domainEvent)
{
Type handlerType = typeof(IHandle<>).MakeGenericType(domainEvent.GetType());
Type wrapperType = typeof(DomainEventHandler<>).MakeGenericType(domainEvent.GetType());
......@@ -29,13 +30,13 @@ namespace CleanArchitecture.Infrastructure.DomainEvents
foreach (DomainEventHandler handler in wrappedHandlers)
{
handler.Handle(domainEvent);
await handler.Handle(domainEvent).ConfigureAwait(false);
}
}
private abstract class DomainEventHandler
{
public abstract void Handle(BaseDomainEvent domainEvent);
public abstract Task Handle(BaseDomainEvent domainEvent);
}
private class DomainEventHandler<T> : DomainEventHandler
......@@ -48,9 +49,9 @@ namespace CleanArchitecture.Infrastructure.DomainEvents
_handler = handler;
}
public override void Handle(BaseDomainEvent domainEvent)
public override Task Handle(BaseDomainEvent domainEvent)
{
_handler.Handle((T)domainEvent);
return _handler.Handle((T)domainEvent);
}
}
}
......
......@@ -2,6 +2,7 @@
using CleanArchitecture.Core.Events;
using CleanArchitecture.Core.Services;
using System;
using System.Threading.Tasks;
using Xunit;
namespace CleanArchitecture.UnitTests.Core.Entities
......@@ -9,19 +10,19 @@ namespace CleanArchitecture.UnitTests.Core.Entities
public class ItemCompletedEmailNotificationHandlerHandle
{
[Fact]
public void ThrowsExceptionGivenNullEventArgument()
public async Task ThrowsExceptionGivenNullEventArgument()
{
var handler = new ItemCompletedEmailNotificationHandler();
Exception ex = Assert.Throws<ArgumentNullException>(() => handler.Handle(null));
Exception ex = await Assert.ThrowsAsync<ArgumentNullException>(() => handler.Handle(null));
}
[Fact]
public void DoesNothingGivenEventInstance()
public async Task DoesNothingGivenEventInstance()
{
var handler = new ItemCompletedEmailNotificationHandler();
handler.Handle(new ToDoItemCompletedEvent(new ToDoItem()));
await handler.Handle(new ToDoItemCompletedEvent(new ToDoItem()));
}
}
}
using CleanArchitecture.Core.Interfaces;
using System.Threading.Tasks;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.SharedKernel;
namespace CleanArchitecture.UnitTests
{
public class NoOpDomainEventDispatcher : IDomainEventDispatcher
{
public void Dispatch(BaseDomainEvent domainEvent) { }
public Task Dispatch(BaseDomainEvent domainEvent)
{
return Task.CompletedTask;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment