Skip to content

Commit

Permalink
Replace DomainEventDispatcher with MediatR (ardalis#120)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpaquette authored Jun 4, 2020
1 parent 18fa4b0 commit d1b89cc
Show file tree
Hide file tree
Showing 17 changed files with 88 additions and 153 deletions.
1 change: 1 addition & 0 deletions src/CleanArchitecture.Core/CleanArchitecture.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<ItemGroup>
<PackageReference Include="Ardalis.GuardClauses" Version="1.4.2" />
<PackageReference Include="MediatR" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
using Ardalis.GuardClauses;
using CleanArchitecture.Core.Events;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.SharedKernel.Interfaces;
using MediatR;

namespace CleanArchitecture.Core.Services
{
public class ItemCompletedEmailNotificationHandler : IHandle<ToDoItemCompletedEvent>
public class ItemCompletedEmailNotificationHandler : INotificationHandler<ToDoItemCompletedEvent>
{
private readonly IEmailSender _emailSender;

Expand All @@ -17,7 +18,7 @@ public ItemCompletedEmailNotificationHandler(IEmailSender emailSender)

// configure a test email server to demo this works
// https://ardalis.com/configuring-a-local-test-email-server
public async Task Handle(ToDoItemCompletedEvent domainEvent)
public async Task Handle(ToDoItemCompletedEvent domainEvent, CancellationToken cancellationToken)
{
Guard.Against.Null(domainEvent, nameof(domainEvent));

Expand Down
11 changes: 6 additions & 5 deletions src/CleanArchitecture.Infrastructure/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
using Ardalis.EFCore.Extensions;
using System.Reflection;
using JetBrains.Annotations;
using MediatR;

namespace CleanArchitecture.Infrastructure.Data
{
public class AppDbContext : DbContext
{
private readonly IDomainEventDispatcher _dispatcher;
private readonly IMediator _mediator;

//public AppDbContext(DbContextOptions options) : base(options)
//{
//}

public AppDbContext(DbContextOptions<AppDbContext> options, IDomainEventDispatcher dispatcher)
public AppDbContext(DbContextOptions<AppDbContext> options, IMediator mediator)
: base(options)
{
_dispatcher = dispatcher;
_mediator = mediator;
}

public DbSet<ToDoItem> ToDoItems { get; set; }
Expand All @@ -42,7 +43,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
int result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

// ignore events if no dispatcher provided
if (_dispatcher == null) return result;
if (_mediator == null) return result;

// dispatch events only if save was successful
var entitiesWithEvents = ChangeTracker.Entries<BaseEntity>()
Expand All @@ -56,7 +57,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
entity.Events.Clear();
foreach (var domainEvent in events)
{
await _dispatcher.Dispatch(domainEvent).ConfigureAwait(false);
await _mediator.Publish(domainEvent).ConfigureAwait(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Autofac;
using CleanArchitecture.Core;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.Services;
using CleanArchitecture.Infrastructure.Data;
using CleanArchitecture.Infrastructure.DomainEvents;
using CleanArchitecture.SharedKernel.Interfaces;
using MediatR;
using MediatR.Pipeline;
using System.Collections.Generic;
using System.Reflection;
using Module = Autofac.Module;
Expand Down Expand Up @@ -43,13 +45,35 @@ protected override void Load(ContainerBuilder builder)

private void RegisterCommonDependencies(ContainerBuilder builder)
{
builder.RegisterType<DomainEventDispatcher>().As<IDomainEventDispatcher>()
.InstancePerLifetimeScope();
builder.RegisterType<EfRepository>().As<IRepository>()
.InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(_assemblies.ToArray())
.AsClosedTypesOf(typeof(IHandle<>));
builder
.RegisterType<Mediator>()
.As<IMediator>()
.InstancePerLifetimeScope();

builder.Register<ServiceFactory>(context =>
{
var c = context.Resolve<IComponentContext>();
return t => c.Resolve(t);
});

var mediatrOpenTypes = new[]
{
typeof(IRequestHandler<,>),
typeof(IRequestExceptionHandler<,,>),
typeof(IRequestExceptionAction<,>),
typeof(INotificationHandler<>),
};

foreach (var mediatrOpenType in mediatrOpenTypes)
{
builder
.RegisterAssemblyTypes(_assemblies.ToArray())
.AsClosedTypesOf(mediatrOpenType)
.AsImplementedInterfaces();
}

builder.RegisterType<EmailSender>().As<IEmailSender>()
.InstancePerLifetimeScope();
Expand Down

This file was deleted.

5 changes: 3 additions & 2 deletions src/CleanArchitecture.SharedKernel/BaseDomainEvent.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using MediatR;
using System;

namespace CleanArchitecture.SharedKernel
{
public abstract class BaseDomainEvent
public abstract class BaseDomainEvent : INotification
{
public DateTime DateOccurred { get; protected set; } = DateTime.UtcNow;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MediatR" Version="8.0.1" />
</ItemGroup>

</Project>

This file was deleted.

10 changes: 0 additions & 10 deletions src/CleanArchitecture.SharedKernel/Interfaces/IHandle.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/CleanArchitecture.Web/CleanArchitecture.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Ardalis.ApiEndpoints" Version="0.9.4" />
<PackageReference Include="Ardalis.ListStartupServices" Version="1.1.3" />
<PackageReference Include="MediatR" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" Version="3.1.3" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" PrivateAssets="All" Version="3.1.2" />
Expand Down
3 changes: 2 additions & 1 deletion src/CleanArchitecture.Web/web.config
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" hostingModel="InProcess">
<aspNetCore processPath="%LAUNCHER_PATH%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" hostingModel="InProcess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
<environmentVariable name="COMPLUS_ForceENC" value="1" />
</environmentVariables>
</aspNetCore>
</system.webServer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System;
using Microsoft.AspNetCore.TestHost;
using System.Linq;
using MediatR;

namespace CleanArchitecture.FunctionalTests
{
Expand Down Expand Up @@ -50,7 +51,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
// options.UseInternalServiceProvider(serviceProvider);
//});

services.AddScoped<IDomainEventDispatcher, NoOpDomainEventDispatcher>();
services.AddScoped<IMediator, NoOpMediator>();

// Build the service provider.
var sp = services.BuildServiceProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using MediatR;

namespace CleanArchitecture.IntegrationTests.Data
{
Expand Down Expand Up @@ -30,9 +31,9 @@ protected static DbContextOptions<AppDbContext> CreateNewContextOptions()
protected EfRepository GetRepository()
{
var options = CreateNewContextOptions();
var mockDispatcher = new Mock<IDomainEventDispatcher>();
var mockMediator = new Mock<IMediator>();

_dbContext = new AppDbContext(options, mockDispatcher.Object);
_dbContext = new AppDbContext(options, mockMediator.Object);
return new EfRepository(_dbContext);
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using CleanArchitecture.Core.Services;
using Moq;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

Expand All @@ -23,13 +24,13 @@ public ItemCompletedEmailNotificationHandlerHandle()
[Fact]
public async Task ThrowsExceptionGivenNullEventArgument()
{
Exception ex = await Assert.ThrowsAsync<ArgumentNullException>(() => _handler.Handle(null));
Exception ex = await Assert.ThrowsAsync<ArgumentNullException>(() => _handler.Handle(null, CancellationToken.None));
}

[Fact]
public async Task SendsEmailGivenEventInstance()
{
await _handler.Handle(new ToDoItemCompletedEvent(new ToDoItem()));
await _handler.Handle(new ToDoItemCompletedEvent(new ToDoItem()), CancellationToken.None);

_emailSenderMock.Verify(sender => sender.SendEmailAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}
Expand Down
14 changes: 0 additions & 14 deletions tests/CleanArchitecture.UnitTests/NoOpDomainEventDispatcher.cs

This file was deleted.

Loading

0 comments on commit d1b89cc

Please sign in to comment.