我有以下 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/