现在的情况
所以现在你的代码看起来像这样:
public class SampleEvent : IEvent
{
}
public class SampleEventHandler : IEventHandler<SampleEvent>
{
public Task Handle(SampleEvent input) => Task.CompletedTask;
}
使事件与 MediatR 兼容
我们需要有 MediatR 识别的事件,这意味着它们需要实现INotification
.
第一种方法是让你的IEvent
接口实现INotification
。这样做的好处是几乎没有代码更改,它使您所有当前和新事件都与 MediatR 兼容。可能不太好的事情是,您当前的IEvent
live 实现的程序集需要依赖 MediatR。
public interface IEvent : INotification
{
}
如果这不可行,我看到的第二种方法是创建新的、特定于 MediatR 的类,这些类继承自现有的并实现INotification
. 这意味着您需要为每个现有类创建一个适配器类,但是您将现有项目从 MediatR 依赖项中释放出来。
// Lives in AssemblyA
public class ExistingEvent : IEvent
{
}
// Lives in AssemblyB that has a dependency on both
// AssemblyA and MediatR
public class MediatrExistingEvent : ExistingEvent, INotification
{
}
接线处理程序
无论您在上一步中采用哪种方式,您现在都处于这样一种状态,即您拥有同时实现IEvent
和的类INotification
,并且您拥有实现 的处理程序IEventHandler<in T> where T : IEvent
。
我们可以创建一个满足 MediatR API 的适配器类并将工作委托给您现有的处理程序:
public class MediatrAdapterHandler<T> : INotificationHandler<T>
where T : IEvent, INotification
{
private readonly IEventHandler<T> _inner;
public MediatrAdapterHandler(IEventHandler<T> inner)
{
_inner = inner;
}
public Task Handle(T notification) => _inner.Handle(notification);
}
最后一件事是在 Autofac 容器中注册这个类。鉴于您现有的处理程序已注册为IEventHandler<T>
,它很容易完成:
builder
.RegisterGeneric(typeof(MediatrAdapterHandler<>))
.As(typeof(INotificationHandler<>));
每次您现在向容器询问 的实例时INotificationHandler<T>
,它都会创建一个实例MediatrAdapterHandler<T>
,您的原始实现IEventHandler<T>
将被注入其中。