Created
May 8, 2017 10:08
-
-
Save tombatron/e3ac126664862701d295e2af8bca3834 to your computer and use it in GitHub Desktop.
MediatR with Decorators.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Autofac.Features.Variance; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Threading.Tasks; | |
using Xunit; | |
using System; | |
namespace MediatR.Decorator.Example | |
{ | |
#region MediatR Query and Handler | |
public class Example : IRequest<string> | |
{ | |
public string Message { get; set; } | |
} | |
public interface IDecorated { } | |
public class ExampleHandler : IRequestHandler<Example, string>, IDecorated | |
{ | |
public string Handle(Example message) | |
{ | |
return message.Message; | |
} | |
} | |
public interface IRequestHandlerDecorator<TQuery, TResult> : IRequestHandler<TQuery, TResult> where TQuery : IRequest<TResult> { } | |
public class ExampleDecorator : IRequestHandlerDecorator<Example, string> | |
{ | |
private readonly IRequestHandler<Example, string> _inner; | |
public ExampleDecorator(IRequestHandler<Example, string> inner) | |
{ | |
_inner = inner; | |
} | |
public string Handle(Example message) | |
{ | |
var innerResult = _inner.Handle(message); | |
return $"({innerResult})"; | |
} | |
} | |
#endregion | |
#region MediatR Handler - No Decorator | |
public class MediatRNoDecorators | |
{ | |
[Fact] | |
public async Task ItCanExecuteHandlerWithNoDecorator() | |
{ | |
var builder = new ContainerBuilder(); | |
Helpers.BootstrapAutofac(builder); | |
using (var container = builder.Build()) | |
{ | |
var mediator = container.Resolve<IMediator>(); | |
var query = new Example { Message = "Hello World" }; | |
var result = await mediator.Send(query); | |
Assert.Equal("Hello World", result); | |
} | |
} | |
} | |
#endregion | |
#region MediatR Handler - Open Decorator | |
public class MediatROpenDecorator | |
{ | |
[Fact] | |
public async Task ItCanExecuteHandlerWithOpenDecorator() | |
{ | |
var builder = new ContainerBuilder(); | |
Helpers.BootstrapAutofac(builder); | |
builder.RegisterType<ExampleHandler>().Named<IRequestHandler<Example, string>>("example"); | |
builder.RegisterDecorator<IRequestHandler<Example, string>>( | |
(c, inner) => new ExampleDecorator(c.ResolveNamed<IRequestHandler<Example, string>>("example")), fromKey: "example" | |
); | |
using (var container = builder.Build()) | |
{ | |
var mediator = container.Resolve<IMediator>(); | |
var query = new Example { Message = "Hello World" }; | |
var result = await mediator.Send(query); | |
Assert.Equal("(Hello World)", result); | |
} | |
} | |
} | |
#endregion | |
#region Helpers | |
public static class Helpers | |
{ | |
public static void BootstrapAutofac(ContainerBuilder builder) | |
{ | |
builder.RegisterSource(new ContravariantRegistrationSource()); | |
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces(); | |
//builder.RegisterType<ExampleHandler>(); | |
builder.RegisterAssemblyTypes(typeof(Example).GetTypeInfo().Assembly).Where(t => | |
!t.GetInterfaces().Any(i => i.IsClosedTypeOf(typeof(IRequestHandlerDecorator<,>))) | |
&& | |
t.GetInterfaces().Any(i => i.IsClosedTypeOf(typeof(IRequestHandler<,>)) | |
|| i.IsClosedTypeOf(typeof(IAsyncRequestHandler<,>)) | |
|| i.IsClosedTypeOf(typeof(ICancellableAsyncRequestHandler<,>)) | |
|| i.IsClosedTypeOf(typeof(INotificationHandler<>)) | |
|| i.IsClosedTypeOf(typeof(IAsyncNotificationHandler<>)) | |
|| i.IsClosedTypeOf(typeof(ICancellableAsyncNotificationHandler<>)) | |
) | |
) | |
.AsImplementedInterfaces(); | |
builder.Register<SingleInstanceFactory>(ctx => | |
{ | |
var c = ctx.Resolve<IComponentContext>(); | |
return t => | |
{ | |
object o; | |
return c.TryResolve(t, out o) ? o : null; | |
}; | |
}); | |
builder.Register<MultiInstanceFactory>(ctx => | |
{ | |
var c = ctx.Resolve<IComponentContext>(); | |
return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t)); | |
}); | |
} | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment