Skip to content

Instantly share code, notes, and snippets.

@hudo
Last active February 6, 2017 16:32
Show Gist options
  • Select an option

  • Save hudo/0e9fb466c3fac5a04aa1b77cc95490e5 to your computer and use it in GitHub Desktop.

Select an option

Save hudo/0e9fb466c3fac5a04aa1b77cc95490e5 to your computer and use it in GitHub Desktop.
MediatR and StructureMap
using System;
using System.Reflection;
using System.Threading.Tasks;
using MediatR;
using StructureMap;
using StructureMap.Graph;
using StructureMap.Graph.Scanning;
using Xunit;
namespace MediatrSmTest
{
public class MediatRTests
{
private readonly IContainer _container;
public MediatRTests()
{
_container = new Container(cfg =>
{
cfg.Scan(scanner =>
{
scanner.TheCallingAssembly();
scanner.IncludeNamespaceContainingType<Entity>();
scanner.With(new AddRequestHandlersWithGenericParametersToRegistry());
scanner.WithDefaultConventions();
});
cfg.For<SingleInstanceFactory>().Use<SingleInstanceFactory>(ctx => t => ctx.GetInstance(t));
cfg.For<MultiInstanceFactory>().Use<MultiInstanceFactory>(ctx => t => ctx.GetAllInstances(t));
cfg.For<IMediator>().Use<Mediator>();
});
}
[Fact]
public void Test()
{
var mediator = _container.GetInstance<IMediator>();
var command = mediator.Send(new Command<Product> {Item = new Product()}).Result;
Assert.NotNull(command);
var query = mediator.Send(new Query<Item>()).Result;
Assert.NotNull(query);
}
}
public class AddRequestHandlersWithGenericParametersToRegistry : IRegistrationConvention
{
public void ScanTypes(TypeSet types, Registry registry)
{
foreach (var concreteClass in types.FindTypes(TypeClassification.Concretes))
{
if (typeof(Entity).IsAssignableFrom(concreteClass))
{
Register(registry, typeof(Command<>), typeof(CommandHandler<>), concreteClass);
Register(registry, typeof(Query<>), typeof(QueryHandler<>), concreteClass);
}
}
}
private void Register(Registry registry, Type genericRequest, Type genericHandler, Type concreteClass)
{
var genericCommand = genericRequest.MakeGenericType(concreteClass);
var interfaceHandlerType = typeof(IAsyncRequestHandler<,>).MakeGenericType(genericCommand, concreteClass);
var concreteHandlerType = genericHandler.MakeGenericType(concreteClass);
registry.For(interfaceHandlerType).Use(concreteHandlerType);
}
}
public abstract class Entity { }
public class Product : Entity { }
public class Item : Entity { }
public class Command<T> : IRequest<T> where T : Entity
{
public T Item { get; set; }
}
public class CommandHandler<T> : IAsyncRequestHandler<Command<T>, T> where T:Entity
{
public Task<T> Handle(Command<T> message)
{
return Task.FromResult(message.Item);
}
}
public class Query<T> : IRequest<T> where T : Entity
{
}
public class QueryHandler<T> : IAsyncRequestHandler<Query<T>, T> where T : Entity
{
public Task<T> Handle(Query<T> message)
{
return Task.FromResult(Activator.CreateInstance<T>());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment