Resolve MediatR generic handler using autofac

2,249 views
Skip to first unread message

Mike

unread,
Sep 27, 2016, 5:55:28 AM9/27/16
to Autofac
 Hi, 
I am using MediatR library for my Command-Query-Separation pattern and I having trouble on how to resolve generic type using autofac.
here is my code:
Autofac Setup :
builder.RegisterAssemblyTypes(typeof(IMediator).Assembly).AsImplementedInterfaces();builder.Register<SingleInstanceFactory>(context =>
{
 
var c = context.Resolve<IComponentContext>();
 
return t => c.Resolve(t);
});

builder
.Register<MultiInstanceFactory>(context =>
{
 
var c = context.Resolve<IComponentContext>();
 
return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
});

Repository Service : 
public class EntityRepository
{
public class Save<T> : MediatR.IRequest where T : class
{
 
public int Id {get; set;}
 
public string FirstName {get; set;}
 
public string LastName {get; set;}
 
//other properties goes here......
}

public class SaveHandler<T> : RequestHandler<Save<T>> where T : class
{
protected override void HandleCore(Save<T> message)
{
//Save function goes here.....
}
}
}




Usage:
Public class PersonController:Controller
{
public ActioResult Index()
{
var save = new EntityRepository.Save<Person>(x=>x.Id == 1);
//Calling Save() method with Person type.
//_mediator is an instance of Mediator class from MediatR library. Calling the Send() method will call the EntityRepository.SaveHandler<T> class. Autofac cannot resolve the T.
var result = _mediator.Send(save); //Throws exception. Could not resolve generic type from handler. 
}
}



Any help will be appreciated.
Thanks,
Mike

Alex Meyer-Gleaves

unread,
Sep 29, 2016, 3:54:42 AM9/29/16
to Autofac
Hi Mike,

I haven't used MediatR before but a quick look at the examples indicates that out-of-the-box handlers aren't expected to be open generic types.

It looks like you will need to register your open generic handler type allowing Autofac to return the closed type when requested.

builder.RegisterGeneric(typeof(EntityRepository.SaveHandler<>)).AsImplementedInterfaces();

Make sure you add AsImplementedInterfaces so the service is registered as the inherited handler interfaces.

Cheers,

Alex.
Reply all
Reply to author
Forward
0 new messages