MediatR 不处理逆变通知

Dmi*_*kiy 3 .net c# dependency-injection mediatr

MediatR 的文档中说:

支持通用差异的容器将相应地调度。例如,您可以使用INotificationHandler<INotification>来处理所有通知。

但就我而言,它不起作用。我的问题是如何使其工作逆变,这样我就不必为每种通知类型创建特定的处理程序?

我有这样的模型层次结构:

abstract record AuditRequestBase : INotification {}
abstract record SpecificAuditRequestBase : AuditRequestBase {}
record CreateSpecificPurchaseOrderAuditRequest : SpecificAuditRequestBase {}
Run Code Online (Sandbox Code Playgroud)

其中前两条记录位于单独的库中,连接到工作项目,最后一条记录位于工作项目中

和处理程序

class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
Run Code Online (Sandbox Code Playgroud)

但是当我尝试像这样向调解员发布通知时

class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
Run Code Online (Sandbox Code Playgroud)

什么都没发生。我查看了 MediatR 的源代码,它无法解决依赖关系INotificationHandler<SpecificAuditRequestBase>

但是,如果我创建两个处理程序而不是一个处理程序,例如

_mediator.Publish(new CreateSpecificPurchaseOrderAuditRequest())
Run Code Online (Sandbox Code Playgroud)

然后第一个处理程序(即LogStorageHandler)开始处理该通知(与 相同LogStorageHandler2)。

启动文件原来是这样的

services.AddMediatR(typeof(TStartup));
Run Code Online (Sandbox Code Playgroud)

但后来我也尝试添加另一个库,以防万一 - 它没有帮助

services.AddMediatR(typeof(TStartup), typeof(WatchGuardAuditRequestBase));
Run Code Online (Sandbox Code Playgroud)

版本: MediatR - 9.0.0
dotnet 5

依赖注入是嵌入式的一种。

Jim*_*ard 6

这是您的容器的问题,而不是 MediatR 或 DI 扩展库的问题。如果您希望差异发挥作用,您需要注册一个开放仿制药。例如:

class LogStorageHandler<T> : INotificationHandler<T> 
    where T : SpecificAuditRequestBase
Run Code Online (Sandbox Code Playgroud)

现在,当容器查找时,IEnumerable<INotificationHandler<T>>它会尝试填充T上面的内容。您还需要在容器中注册开放通用,MediatR 的 DI 扩展不会为您执行此操作:

class LogStorageHandler<T> : INotificationHandler<T> 
    where T : SpecificAuditRequestBase
Run Code Online (Sandbox Code Playgroud)

您可以查看 MS DI 项目的单元测试,以了解它在这些更复杂的场景中支持什么。否则,我会在单独的单元测试中将容器与 MediatR 隔离。MediatR 只是遵循容器通过IServiceProvider.