public interface IMediator
{
Task Publish<T>(T notification, CancellationToken cancellationToken = default) where T : class, INotification;
}
public class Mediator : IMediator
{
private IServiceProvider _serviceProvider;
private static ConcurrentDictionary<Type, Func<INotification, CancellationToken, Task>> _handle = new ConcurrentDictionary<Type, Func<INotification, CancellationToken, Task>>();
public Mediator(
IServiceProvider serviceProvider
)
{
_serviceProvider = serviceProvider;
}
public Task Publish<T>(T notification, CancellationToken cancellationToken = default) where T : class, INotification
{
notification.IsNull("notification is null");
var notificationType = notification.GetType();
var func = _handle.GetOrAdd(notificationType, type =>
{
Func<INotification, CancellationToken, Task> handle = null;
var handles = _serviceProvider.GetServices(typeof(INotificationHandler<T>));
foreach (var item in handles)
{
var generic = item.GetType().GetInterface($"{nameof(INotificationHandler<INotification>)}`1").GetGenericArguments().First();
if (!generic.Name.Equals(type.Name)) continue;
if (item is INotificationHandler<T> h )
{
handle += (x, y) => {
return h.Handle((T)x,y);
};
}
}
return handle;
});
if (func == null) throw new Exception(message: $"对应的 INotificationHandler<{notificationType.Name}>的实现没有注入");
return func((INotification)notification, cancellationToken);
}
}
public interface INotification
{
}
- INotificationHandler<T>接口
public interface INotificationHandler<T> where T : INotification
{
Task Handle(T notification, CancellationToken cancellationToken=default(CancellationToken));
}
public static class CheckNull
{
public static void IsNull<T>(this T t, string message="")
{
if (t == null)
{
throw new ArgumentNullException(nameof(t), message);
}
}
}
service.AddSingleton<IMediator, Mediator>();
service.AddSingleton<INotificationHandler<MsgMonitorEvent>, MsgMonitorEventHandler>();
service.AddSingleton<INotificationHandler<MsgMonitorEvent>, MsgMonitorNoticeHandler>();
public class
MsgMonitorNoticeHandler:INotificationHandler<MsgMonitorEvent>
{
public async Task Handle(MsgMonitorEvent notification, CancellationToken cancellationToken = default)
{
Console.WriteLine("测试赛");
await Task.CompletedTask;
}
}
public class MsgMonitorEvent:INotification
{
public List<PerformancMonitorDto<MsgMonitorDto>> MonitorDtos { get; set; }
}
- 使用和MediatR完全一样,这样做的目的是不想代码中有太多依赖,可以在任意版本中切换重新编译可立即使用,2.1 3.1 5 6