首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MediatR泛型处理程序

MediatR泛型处理程序
EN

Stack Overflow用户
提问于 2022-09-18 07:27:47
回答 1查看 385关注 0票数 1

我在我的Asp .Net核心6应用程序中使用了一个.Net库。对于一组请求,我有相同的逻辑,所以我想对所有请求使用相同的处理程序。这个问题并不是新问题,但我发现的解决办法并没有帮助我。我有自己的解决办法来解决这个问题,但我不喜欢它,希望有人知道更好的方法来解决这个问题。

本例如下所示:

代码语言:javascript
复制
public class HandlerRequest<T> : IRequest
{
    public T Data { get; set; }
}

public class Handler<T> : IRequestHandler<HandlerRequest<T>>
{
    public Task<Unit> Handle(HandlerRequest<T> request, CancellationToken cancellationToken)
    {
        // the logic is here
        return Task.FromResult(new Unit());
    }
}

MediatR的注册情况如下:

代码语言:javascript
复制
builder.Services.AddMediatR(typeof(BusinessLayer));

例如,当我试图调用mediatr时:

代码语言:javascript
复制
await _mediator.Send(new HandlerRequest<int>{Data = 5});
await _mediator.Send(new HandlerRequest<string>{Data = "TEST"});

我有个例外:

为MediatR.IRequestHandler2[AT.Messenger.Credentials.Business.Requests.V1.Modeles.HandlerRequest1System.Int32,MediatR.Unit类型的请求构造处理程序时出错]。向容器注册处理程序。有关示例,请参阅GitHub中的示例。

出现此问题是因为MediatR无法注册泛型处理程序。我还尝试将处理程序注册为作用域或单例服务,因为我在互联网上看到了这种建议,但这并没有帮助。

我找到的唯一解决方案是从我的处理程序继承一个新的类:

代码语言:javascript
复制
public class HandlerInt : Handler<int>
{
}

public class HandlerString : Handler<string>
{
}

如果采用这种方法,所有的方法都能工作,但我不喜欢这个解决方案。如果有人知道更好的解决这个问题的方法,请给我一个建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-18 07:47:12

您有以下选项,首先,像这样显式地注册您需要的内容。

代码语言:javascript
复制
services.AddTransient<IRequestHandler<HandlerRequest<int>, Unit>>, Handler<int>>();
//so on and so forth

通过这种方式,您已经为已知类型注册了处理程序。

如果您有开放绑定的泛型,您可以查看我的按下,它为您提供了

代码语言:javascript
复制
services.RegisterGenericMediatRHandlers(typeof(GenericHandlerBase).Assembly);

使用上面提供的方法自动注册从约束接口继承的类。

最后,您可以选择使用Autofac并注册如下所有处理程序:

代码语言:javascript
复制
        var mediatrOpenTypes = new[]
        {
                typeof(IRequestHandler<,>),
                typeof(IRequestExceptionHandler<,,>),
                typeof(IRequestExceptionAction<,>),
                typeof(INotificationHandler<>),
        };

        foreach (var mediatrOpenType in mediatrOpenTypes)
        {
            builder
                .RegisterAssemblyTypes(_assemblies.ToArray())
                .AsClosedTypesOf(mediatrOpenType)
                .AsImplementedInterfaces();
        }

//also by simply
  //builder.RegisterGeneric(typeof(Handler<>)).AsImplementedInterfaces();

这还将注册所有泛型处理程序,甚至不必在DI中显式注册它。

顺便说一句,用于处理泛型注册的方法是docs中描述的方法。

如果没有上面列出的开放泛型,则需要显式注册它。例如,如果您有一个开放的泛型请求处理程序,那么显式地注册开放的泛型类型:

代码语言:javascript
复制
services.AddTransient(typeof(IRequestHandler<,>), typeof(GenericHandlerBase<,>));

这将不适用于泛型约束,所以最好创建一个抽象基类和填充正确类型的具体封闭泛型类。

来源:docs链接

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73760859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档