深圳网站建设工资,知乎营销平台,wordpress 博客样式,深圳建网站企业结合 AOP 轻松处理事件发布处理日志Intro前段时间#xff0c;实现了 EventBus 以及 EventQueue 基于 Event 的事件处理#xff0c;但是没有做日志#xff08;EventLog#xff09;相关的部分#xff0c;原本想增加两个接口#xff0c; 处理事件发布日志和事件处理日志实现了 EventBus 以及 EventQueue 基于 Event 的事件处理但是没有做日志EventLog相关的部分原本想增加两个接口 处理事件发布日志和事件处理日志最近用了 AOP 的思想处理了 EntityFramework 的数据变更自动审计于是想着事件日志也用 AOP 的思想来实现而且可能用 AOP 来处理可能会更好一些最近自己造了一个 AOP 的轮子 —— FluentAspects下面的示例就以它来演示了你也可以换成自己喜欢的 AOP 组件思想是类似的事件日志示例事件发布日志事件发布日志只需要拦截事件发布的方法调用即可在发布事件时进行拦截在拦截器中根据需要进行日志记录即可事件发布者接口定义public interface IEventPublisher
{/// summary/// publish an event/// /summary/// typeparam nameTEventevent type/typeparam/// param nameeventevent data/param/// returnswhether the operation succeed/returnsbool PublishTEvent(TEvent event) where TEvent : class, IEventBase;/// summary/// publish an event async/// /summary/// typeparam nameTEventevent type/typeparam/// param nameeventevent data/param/// returnswhether the operation succeed/returnsTaskbool PublishAsyncTEvent(TEvent event) where TEvent : class, IEventBase;
}
事件发布日志拦截器public class EventPublishLogInterceptor : AbstractInterceptor
{public override async Task Invoke(IInvocation invocation, FuncTask next){Console.WriteLine(-------------------------------);Console.WriteLine($Event publish begin, eventData:{invocation.Arguments.ToJson()});var watch Stopwatch.StartNew();try{await next();}catch (Exception ex){Console.WriteLine($Event publish exception({ex}));}finally{watch.Stop();Console.WriteLine($Event publish complete, elasped:{watch.ElapsedMilliseconds} ms);}Console.WriteLine(-------------------------------);}
}
事件处理日志事件处理器接口定义public interface IEventHandler
{Task Handle(object eventData);
}
事件处理日志拦截器定义public class EventHandleLogInterceptor : IInterceptor
{public async Task Invoke(IInvocation invocation, FuncTask next){Console.WriteLine(-------------------------------);Console.WriteLine($Event handle begin, eventData:{invocation.Arguments.ToJson()});var watch Stopwatch.StartNew();try{await next();}catch (Exception ex){Console.WriteLine($Event handle exception({ex}));}finally{watch.Stop();Console.WriteLine($Event handle complete, elasped:{watch.ElapsedMilliseconds} ms);}Console.WriteLine(-------------------------------);}
}
AOP 配置Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(builder {builder.UseStartupStartup();}).UseFluentAspectServiceProviderFactory(options {// 拦截器配置// 拦截 IEventPublisher 日志注册事件发布日志拦截器options.InterceptTypeIEventPublisher().WithEventPublishLogInterceptor();// 拦截 IEventHandler注册事件处理日志拦截器options.InterceptTypeIEventHandler().WithEventHandleLogInterceptor();}, builder {// 默认使用默认实现来生成代理现在提供了 Castle 和 AspectCore 的扩展也可以自己扩展实现自定义代理生成方式// 取消注释使用 Castle 来生成代理//builder.UseCastleProxy();}, t t.Namespace?.StartsWith(WeihanLi) false // 要忽略的类型断言).Build().Run();
More事件发布示例定义了一个发布事件的中间件// pageView middleware
app.Use((context, next)
{var eventPublisher context.RequestServices.GetRequiredServiceIEventPublisher();eventPublisher.Publish(new PageViewEvent(){Path context.Request.Path.Value,});return next();
});
事件处理示例是用一个消息队列的模式来处理的示例和前面的事件的文章类似EventConsumer 是一个后台任务完整代码示例如下public class EventConsumer : BackgroundService
{private readonly IEventQueue _eventQueue;private readonly IEventHandlerFactory _eventHandlerFactory;public EventConsumer(IEventQueue eventQueue, IEventHandlerFactory eventHandlerFactory){_eventQueue eventQueue;_eventHandlerFactory eventHandlerFactory;}protected override async Task ExecuteAsync(CancellationToken stoppingToken){while (!stoppingToken.IsCancellationRequested){var queues await _eventQueue.GetQueuesAsync();if (queues.Count 0){await queues.Select(async q {var event await _eventQueue.DequeueAsync(q);if (null ! event){var handlers _eventHandlerFactory.GetHandlers(event.GetType());if (handlers.Count 0){await handlers.Select(h h.Handle(event)).WhenAll();}}}).WhenAll();}await Task.Delay(1000, stoppingToken);}}
}
完整的示例代码可以从https://github.com/WeihanLi/WeihanLi.Common/blob/dev/samples/AspNetCoreSample 获取OverMore之前在微软的 EShopOnContainers 项目里又看到类似下面这样的代码在发布事件的时候包装一层 try ... catch 来记录事件发布日志相比之下本文示例中的这种方式更为简洁代码更清爽Referencehttps://www.cnblogs.com/weihanli/p/12941919.htmlhttps://www.cnblogs.com/weihanli/p/implement-event-queue.htmlhttps://github.com/WeihanLi/WeihanLi.Commonhttps://github.com/WeihanLi/WeihanLi.Common/blob/dev/samples/AspNetCoreSample/Startup.cs