-
Hi, I am trying to make a Generic Request/Handler combination. What I am trying to achieve is to have a generic Request(GetById) where it can be invoked with different entities without having to write more code. For example, if you look below, I am trying to have a request like this. public class GetByIdRequest<TEntity, TRes> : IRequest<Result<TRes>>
where TEntity : class
where TRes : class
{
public int Id { get; set; }
public GetByIdRequest(int id)
{
Id = id;
}
};
public readonly struct Result<TValue>
{
private readonly ResultState _state;
public Result(TValue value)
{
Value = value;
}
[Pure]
public TValue? Value { get; init; }
} Where a request is named GetByIdRequest. Now in the call site, I would specify the exact Entity and an exact result, for example: _mediator.Send(new GetByIdRequest<ApplicationUser, UserDto>(id)); Handler for the request above looks like this: public class GetByIdHandler<TEntity,TRes>:
IRequestHandler<GetByIdRequest<TEntity,TRes>, Result<TRes>>
where TEntity : class, new()
where TRes : class
{
private readonly AppDbContext _context;
private readonly IMapper _mapper;
public GetByIdHandler(AppDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public async Task<Result<TRes>> Handle(GetByIdRequest<TEntity, TRes> request, CancellationToken ct)
{
var res = await
_context.Set<TEntity>()
.ProjectTo<TRes>(_mapper.ConfigurationProvider)
.FirstOrDefaultAsync(ct);
return new Result<TRes>(res);
}
} When I try to run API, I get the following error: System.InvalidOperationException: Error constructing handler for request of type
MediatR.IRequestHandler`2[GetByIdRequest`2[ApplicationUser,UserDto],Result`1[UserDto]].
Register your handlers with the container. See the samples in GitHub for examples.
...... I did run an automatic scan of the assembly. My question is, do I need to register this handler manually? I did try with code below but it does not work srv.AddTransient(typeof(IRequestHandler<,>),typeof(GetByIdHandler<,>)); |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Hi, Do you have this working? |
Beta Was this translation helpful? Give feedback.
-
@01Raja Yes with AutoFac. AutoFac can resolve this in runtime. // DI Register AutoFac modules
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new ApplicationServicesModule());
}); And then adding in ApplicationServicesModule following: public class ApplicationServicesModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(GetByIdHandler<,>)).AsImplementedInterfaces();
}
} |
Beta Was this translation helpful? Give feedback.
-
Thanks much.
…On Sat, Jan 7, 2023, 12:19 PM Vlada ***@***.***> wrote:
@01Raja <https://github.com/01Raja> Yes with AutoFac. AutoFac can resolve
this in runtime.
// DI Register AutoFac modulesbuilder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new ApplicationServicesModule());
});
And then adding in ApplicationServicesModule following:
public class ApplicationServicesModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(GetByIdHandler<,>)).AsImplementedInterfaces();
}
}
—
Reply to this email directly, view it on GitHub
<#778 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AX6U3Q5PDN3TTFKRMJYVHTTWRHFUZANCNFSM57ZP32AQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
@01Raja Yes with AutoFac. AutoFac can resolve this in runtime.
And then adding in ApplicationServicesModule following: