MediatR 不处理逆变通知
MediatR doesn't handle contravariant notifications
在 MediatR 的文档中说:
Containers that support generic variance will dispatch accordingly. For example, you can have an INotificationHandler<INotification>
to handle all notifications.
但在我的情况下它不起作用。
我的问题是如何使其逆变工作,这样我就不必为每种通知类型创建特定的处理程序?
我有这样的模型层次结构:
abstract record AuditRequestBase : INotification {}
abstract record SpecificAuditRequestBase : AuditRequestBase {}
record CreateSpecificPurchaseOrderAuditRequest : SpecificAuditRequestBase {}
前两条记录在单独的库中,连接到工作项目,最后一条在工作项目中
和处理程序
class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
但是当我尝试像这样向中介发布通知时
_mediator.Publish(new CreateSpecificPurchaseOrderAuditRequest())
没有任何反应。我查看了 MediatR 的源代码,它无法解析依赖项 INotificationHandler<SpecificAuditRequestBase>
。
但是如果我创建两个处理程序而不是一个处理程序,例如
class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
class LogStorageHandler2 : INotificationHandler<CreateSpecificPurchaseOrderAuditRequest>
然后第一个处理程序(即 LogStorageHandler
)开始处理该通知(与 LogStorageHandler2
相同)。
启动文件原来是这样的
services.AddMediatR(typeof(TStartup));
但后来我也尝试添加另一个库,以防万一 - 它没有帮助
services.AddMediatR(typeof(TStartup), typeof(WatchGuardAuditRequestBase));
版本:
MediatR - 9.0.0
网络 5
Dependency Injection是嵌入式的。
这是您的容器的问题,而不是 MediatR 或 DI 扩展库的问题。如果您希望差异生效,您将需要注册一个开放的泛型。类似于:
class LogStorageHandler<T> : INotificationHandler<T>
where T : SpecificAuditRequestBase
现在,当容器查找 IEnumerable<INotificationHandler<T>>
时,它将尝试填写上面的 T
。您还需要在容器中注册开放泛型,MediatR 的 DI 扩展不会为您这样做:
services.TryAddTransient(typeof(LogStorageHandler<>));
您可以查看 MS DI 项目的单元测试,以了解它在这些更复杂的场景方面的支持。否则,我将容器隔离在与 MediatR 分开的单元测试中。 MediatR 只是遵从容器通过 IServiceProvider
.
注册依赖项
在 MediatR 的文档中说:
Containers that support generic variance will dispatch accordingly. For example, you can have an
INotificationHandler<INotification>
to handle all notifications.
但在我的情况下它不起作用。 我的问题是如何使其逆变工作,这样我就不必为每种通知类型创建特定的处理程序?
我有这样的模型层次结构:
abstract record AuditRequestBase : INotification {}
abstract record SpecificAuditRequestBase : AuditRequestBase {}
record CreateSpecificPurchaseOrderAuditRequest : SpecificAuditRequestBase {}
前两条记录在单独的库中,连接到工作项目,最后一条在工作项目中
和处理程序
class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
但是当我尝试像这样向中介发布通知时
_mediator.Publish(new CreateSpecificPurchaseOrderAuditRequest())
没有任何反应。我查看了 MediatR 的源代码,它无法解析依赖项 INotificationHandler<SpecificAuditRequestBase>
。
但是如果我创建两个处理程序而不是一个处理程序,例如
class LogStorageHandler : INotificationHandler<SpecificAuditRequestBase>
class LogStorageHandler2 : INotificationHandler<CreateSpecificPurchaseOrderAuditRequest>
然后第一个处理程序(即 LogStorageHandler
)开始处理该通知(与 LogStorageHandler2
相同)。
启动文件原来是这样的
services.AddMediatR(typeof(TStartup));
但后来我也尝试添加另一个库,以防万一 - 它没有帮助
services.AddMediatR(typeof(TStartup), typeof(WatchGuardAuditRequestBase));
版本:
MediatR - 9.0.0
网络 5
Dependency Injection是嵌入式的。
这是您的容器的问题,而不是 MediatR 或 DI 扩展库的问题。如果您希望差异生效,您将需要注册一个开放的泛型。类似于:
class LogStorageHandler<T> : INotificationHandler<T>
where T : SpecificAuditRequestBase
现在,当容器查找 IEnumerable<INotificationHandler<T>>
时,它将尝试填写上面的 T
。您还需要在容器中注册开放泛型,MediatR 的 DI 扩展不会为您这样做:
services.TryAddTransient(typeof(LogStorageHandler<>));
您可以查看 MS DI 项目的单元测试,以了解它在这些更复杂的场景方面的支持。否则,我将容器隔离在与 MediatR 分开的单元测试中。 MediatR 只是遵从容器通过 IServiceProvider
.