c# - 在 DI 注入(inject)容器中注册受约束的 MediatR 管道行为

标签 c# asp.net-core dependency-injection mediatr

我有以下 MediatR 行为:

public class FailFastRequestBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
    where TResponse : BaseResponse

并在默认的 ASP.NET Core DI 容器中注册,如下所示:

services.AddScoped(
    typeof(IPipelineBehavior<,>),
    typeof(FailFastRequestBehavior<,>));

它处理这样的命令:

public class Command: IRequest<BaseResponse>

这很好用,但是BaseResponse类有一个可以包含命令结果的属性,这样它就被键入为object,这不太好。

我想将 BaseResponse 设为通用,因此命令将类似于:

public class Command: IRequest<BaseResponse<MyObject>>

如何更改行为签名以支持此操作,然后正确注册它?如果可能的话...

我尝试了几种方法,但对我来说更合理的是:

public class FailFastRequestBehavior<TRequest, TResponse, TValue>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
    where TResponse : BaseResponse<TValue>

但是我的行为有 3 个通用参数,而 MediatR 接口(interface)只有 2 个,我无法将其注册到 DI 容器中。

有什么建议吗?

最佳答案

But then my behavior has 3 generic parameters and the MediatR interface has only 2, and I cannot register it in the DI container.

这是 MS.DI 无法实现的。 MS.DI 有一个限制,即它要求实现具有与实现的接口(interface)完全相同的顺序的精确泛型类型参数。

这意味着它有效:

  • X<A> : I<A>
  • X<A, B> : I<A, B>
  • X<A, B, C> : I<A, B, C>

这无法解决:

  • X<A> : I<IFoo<A>>
  • X<A, B> : I<B, A>
  • X<A, B, C> : I<B, A>

其他一些 DI 容器确实对这些类型的通用结构有更好的支持,但对于 MS.DI,每个通用实现必须可按如下方式构造:

Type typeDefinitionImplementation; // e.g. X<T1, T1>
Type closedGenericInterface; // e.g. IX<Foo, Bar>

// Arguments in the order of the interface definition.
// e.g. IX<Foo, Bar> results in { Foo, Bar }
Type[] typeArgs = closedGenericInterface.GetGenericArguments();

// close type must be constructable using the typeArgs array.
// e.g. X<T1, T1> + { Foo, Bar } = X<Foo, Bar>
Type closedImpl = typeDefinitionImplementation.MakeGenericType(typeArgs);

由于其design as Least-Common Denominator ,您不必期望将来会添加此类功能。

关于c# - 在 DI 注入(inject)容器中注册受约束的 MediatR 管道行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73796864/

相关文章:

c# - 将 IsClosedTypeOf 从 autofac 转换为 simple.injector

c# - Lambda 内部的 Lambda

c# - 包括导致 InvalidCastException

c# - 在查询开始和结束时调用 'where' 函数在性能上有区别吗?

c# - Asp.Net WebApi Core 2.0 身份与 JWTBearer 没有 cookie

c# - 使用 FakeItEasy 创建类并自动初始化依赖项

java - Guice Assisted : No implementation for java. lang.String 注释为 @com.google.inject.assisted.Assisted(value=prefix) 已绑定(bind)

C# MySQLDriverCS - 插入/更新中的“字符”

c# - 值转换器。强制 WPF 只调用一次

c# - 传递 UInt32 作为参数 TestCase NUnit