内容目录
空接口,发布者订阅者通讯,需要一个实现了 IEventData 的类。
/// <summary>
/// 事件数据
/// </summary>
public interface IEventData
{
}
事件,订阅者需要实现这个类型,当发布者发布一个 IEventData 类型的数据时,此事件会被触发。
当然,你也可以创建一个同步事件。
/// <summary>
/// 异步事件
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAsyncEventHandler<in T> where T : IEventData
{
Task HandleEventAsync(T eventData);
}
事件总线接口,订阅者可以通过此此接口订阅 IEventData,发布者也可以通过此发布 IEventData。
public interface IEventBus
{
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TEventData"></typeparam>
/// <param name="eventData"></param>
/// <returns></returns>
Task PublishAsync<TEventData>(TEventData eventData) where TEventData : IEventData;
/// <summary>
/// 订阅事件
/// </summary>
/// <typeparam name="TEvent"></typeparam>
void Register<TEvent>() where TEvent : IAsyncEventHandler<IEventData>;
/// <summary>
/// 取消订阅事件
/// </summary>
/// <typeparam name="TEvent"></typeparam>
void Unregister<TEvent>() where TEvent : IAsyncEventHandler<IEventData>;
}
实现事件总线:
public class EventBus : IEventBus
{
private readonly IServiceProvider _services;
private readonly ILogger _logger;
public EventBus(IServiceProvider services, ILogger logger)
{
_services = services;
_logger = logger;
}
static EventBus()
{
_handlerFactories = new ConcurrentDictionary<Type, List<Type>>();
}
private readonly static ConcurrentDictionary<Type, List<Type>> _handlerFactories;
public async Task PublishAsync<TEventData>(TEventData eventData) where TEventData : IEventData
{
try
{
if (!_handlerFactories.TryGetValue(eventData.GetType(), out var list))
{
return;
}
_logger.LogInformation($"Eventbus : {typeof(TEventData)} , Registers : {string.Join(",", list.Select(x => x.Name))}");
List<Task> tasks = new List<Task>();
foreach (var item in list)
{
var obj = _services.GetRequiredService(item);
var eventObj = (IAsyncEventHandler<IEventData>)obj;
tasks.Add(eventObj.HandleEventAsync(eventData));
}
await Task.WhenAll();
}
catch (Exception ex)
{
_logger.LogError(ex, $"Eventbus : {typeof(TEventData).Name}", eventData);
}
}
public void Register<TEvent>() where TEvent : IAsyncEventHandler<IEventData>
{
try
{
// 获取事件参数
if (!typeof(TEvent).IsGenericType) return;
var iEventDataType = ((System.Reflection.TypeInfo)typeof(TEvent)).GenericTypeParameters.FirstOrDefault();
if (_handlerFactories.TryGetValue(iEventDataType, out var list)) { }
else
{
list = new List<Type>();
_ = _handlerFactories.TryAdd(iEventDataType, list);
}
list.Add(typeof(TEvent));
}
catch (Exception ex)
{
_logger.LogError(ex, $"Eventbus : {typeof(TEvent).Name}");
}
}
public void Unregister<TEvent>() where TEvent : IAsyncEventHandler<IEventData>
{
try
{
// 获取事件参数
if (!typeof(TEvent).IsGenericType) return;
var iEventDataType = ((System.Reflection.TypeInfo)typeof(TEvent)).GenericTypeParameters.FirstOrDefault();
if (_handlerFactories.TryGetValue(iEventDataType, out var list))
{
}
else
{
list = new List<Type>();
_ = _handlerFactories.TryAdd(iEventDataType, list);
}
list.Remove(typeof(TEvent));
}
catch (Exception ex)
{
_logger.LogError(ex, $"Eventbus : {typeof(TEvent).Name}");
}
}
}
由于每一个事件都实现 IAsyncEventHandler
,其中事件也可以使用依赖注入,因此需要将所有实现了 IAsyncEventHandler
的事件都放到依赖注入中,这些才有意义。
文章评论