How to register IRequestHandler<,> to multiple Implementations with type constraints.
See original GitHub issueHello I’ve been following the addition of @jbogard to .net 5.0 dependency injection and was wondering if it is all sorted out now.
I am trying to register a generic Handler for generic requests…
I am currently using asp.net core 3.1 and MediatR 8.1
//generic command
public class AddNoteCommand<TEntity>
where TEntity : class, INoteEntity
{
public int ParentId { get; set; }
public int CurrentUserProfileId { get; set; }
public string NoteContent { get; set; }
}
//generic handler
public class AddNoteCommandHandler<TEntity> : IRequestHandler<AddNoteCommand<TEntity>>
where TEntity : class, INoteEntity, new()
{
private readonly INoteRepository<TEntity> _repo;
private readonly ITime _time;
public AddNoteCommandHandler(INoteRepository<TEntity> repo, ITime time)
{
_repo = repo;
_time = time;
}
public async Task<Unit> Handle(AddNoteCommand<TEntity> request, CancellationToken cancellationToken)
{
await _repo.Insert(new TEntity
{
CreatedByUserId = request.CurrentUserProfileId,
CreatedDate = _time.Current,
NoteContent = request.NoteContent,
ParentId = request.ParentId
});
await _repo.SaveChanges();
return Unit.Value;
}
}
//another implementation
//command
public class FetchAllNotesForParentQuery<TEntity>
where TEntity : class, INoteEntity
{
public int ParentId { get; set; }
}
//handler
public class FetchAllNotesForParentQueryHandler<TEntity> : IRequestHandler<FetchAllNotesForParentQuery<TEntity>, List<TEntity>>
where TEntity : class, INoteEntity
{
private readonly INoteRepository<TEntity> _repo;
public FetchAllNotesForParentQueryHandler(INoteRepository<TEntity> repo)
{
_repo = repo;
}
public Task<List<TEntity>> Handle(FetchAllNotesForParentQuery<TEntity> request, CancellationToken cancellationToken)
{
return _repo.FetchByParentId(request.ParentId);
}
}
//usage **MyNoteClass implements INoteEntity
await _mediator.Send(new AddNoteCommand<MyNoteClass>
{
//properties here...
});
var notesList = await _mediator.Send(new FetchAllNotesForParentQuery<MyNoteClass>
{
ParentId = parentId
});
//asp.net core DI registration
services
.AddTransient(typeof(IRequestHandler<,>), typeof(AddNoteCommandHandler<,>))
.AddTransient(typeof(IRequestHandler<,>), typeof(FetchAllNotesForParentQueryHandler<,>);
Will this work somehow?
I’ve tried this and it seems to try and get the last implementation I register at runtime and fails letting me know that the type parameter violates the constraints of the implementation it tries to use.
It always seems to try and use the last implementation that I register.
Will this be solved by upgrading to .net 5.0? or maybe mediator 9+ ?
Any help would be appreciated. Thank you!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:5
Top Results From Across the Web
Registering commands and handlers with generic interfaces
I'm studying about the mediator pattern. I would like to register a handler to handle a command that has a generic type, where...
Read more >CQRS and MediatR in ASP.NET Core
We first define a LoggingBehavior class, taking two types of parameters TRequest and TResponse , and implementing the IPipelineBehavior<TRequest ...
Read more >Diagnosing and Fixing MediatR Container Issues
These types are all resolved from a container at runtime as MediatR ... add a registration for the requested service/implementation types:
Read more >Registering Mediatr handlers with open generic request types
Solution 1: Register each type explicitly ... One way we can register the generic class without having to define concrete classes is by ......
Read more >Command & Query: Domain - Request handler mediator
Request handler mediator explanation and implementation. ... Type of request argument changed to IRequest<TResponse> — to keep the same type constraint.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@abuzaforfagun
This sample is registered without having to explicitly register the handlers by using the default AddMediatr extension method. Since they are concrete handlers derived from a closed generic base class, Mediatr is able to find the correct handler without any explicit service registration.
The best way in my opinion is to not worry about any of that… Just simply create your generic commands / handlers and then register them using autofac.
@zachpainter77
This worked for me to register multiple generic request handlers. But need to do the implicitly. Is anyone having any idea to register the DI in a generic way?