更新事件总线实现

This commit is contained in:
utilcore
2017-10-06 14:02:59 +08:00
parent 31277f8c50
commit efbcaec56b
22 changed files with 241 additions and 173 deletions
@@ -1,5 +1,4 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Util.Dependency;
using Util.Domains.Sessions;
@@ -1,56 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Util.Datas.Queries;
using Util.Dependency;
using Util.Events;
using Util.Events.Handlers;
using Util.Logs;
using Util.Logs.Extensions;
using Util.Reflections;
namespace Util.Samples.Webs.Controllers {
public class HomeController : Controller {
private IEventBus _eventBus;
public HomeController( IEventBus eventBus ) {
_eventBus = eventBus;
public HomeController() {
}
public IActionResult Index() {
_eventBus.Publish( Event.Create( new TestEventData { Name = "World" } ) );
return View();
}
}
public class TestEventData {
public string Name { get; set; }
}
public class TestEventData2 {
public string Name { get; set; }
}
public class TestHandler : IEventHandler<TestEventData> {
private ILog _log;
public TestHandler( ILog log ) {
_log = log;
}
public void Handle( Event<TestEventData> @event ) {
_log.Caption( $"Hello,{@event.Data.Name}" ).Fatal();
}
}
public class TestHandler2 : IEventHandler<TestEventData2> {
private ILog _log;
public TestHandler2( ILog log ) {
_log = log;
}
public void Handle( Event<TestEventData2> @event ) {
_log.Caption( $"Hello,{@event.Data.Name}-2" ).Info();
}
}
}
@@ -3,15 +3,15 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:2264/",
"sslPort": 44365
"applicationUrl": "http://localhost:5210/",
"sslPort": 44394
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "https://localhost:44365/",
"launchUrl": "https://localhost:44394/",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
@@ -25,4 +25,4 @@
"applicationUrl": "http://localhost:2265/"
}
}
}
}
+2 -2
View File
@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Util.Events.Memory;
using Util.Events.Default;
using Util.Logs.Extensions;
namespace Util.Samples.Webs {
@@ -40,7 +40,7 @@ namespace Util.Samples.Webs {
// config.ApiKey = "oGBxMBfTQhdRJm1npjGgN1kNJvR6eYSWIpws8pvm";
//} );
//添加默认事件总线服务
//添加事件总线服务
services.AddEventBus();
//添加Util基础设施服务
@@ -3,10 +3,10 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<UserSecretsId>aspnet-Util.Samples.Webs-D0551EBC-0589-40AD-ADC2-A88CA4609632</UserSecretsId>
<Authors>何镇汐;dotnetcore</Authors>
<Company>何镇汐;dotnetcore</Company>
<PackageReleaseNotes>Util应用框架以MIT开源发布,可随意使用</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/dotnetcore/Util</PackageProjectUrl>
<Authors>何镇汐</Authors>
<Company>何镇汐</Company>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageProjectUrl></PackageProjectUrl>
<Description>Util应用框架Web示例项目</Description>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
@@ -72,8 +72,7 @@
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="必须安装Node.js" />
<Message Importance="high" Text="Webpack开始打包" />
<Exec Command="npm install" />
<Exec Command="npm start" />
<!--<Exec Command="npm start" />-->
<!--<Exec Command="node node_modules/webpack/bin/webpack.js" />-->
</Target>
@@ -3,5 +3,9 @@
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
<ToolsVersionPromptShown>0.0</ToolsVersionPromptShown>
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
+25
View File
@@ -0,0 +1,25 @@
using System;
using DotNetCore.CAP;
using Microsoft.Extensions.DependencyInjection;
using Util.Events.Default;
using Util.Events.Handlers;
using Util.Events.Messages;
namespace Util.Events.Cap {
/// <summary>
/// 事件总线扩展
/// </summary>
public static class Extensions {
/// <summary>
/// 注册事件总线服务
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="action">配置操作</param>
public static void AddEventBus( this IServiceCollection services,Action<CapOptions> action ) {
services.AddCap( action );
services.AddSingleton<IMessageEventBus, MessageEventBus>();
services.AddSingleton<IEventHandlerManager, EventHandlerManager>();
services.AddSingleton<IEventBus, Util.Events.Default.EventBus>();
}
}
}
@@ -1,29 +1,31 @@
using DotNetCore.CAP;
using System;
using DotNetCore.CAP;
using Util.Events.Messages;
namespace Util.Events.Cap {
/// <summary>
/// Cap事件总线
/// Cap消息事件总线
/// </summary>
public class EventBus : IEventBus {
public class MessageEventBus : IMessageEventBus {
/// <summary>
/// Cap事件发布器
/// </summary>
private readonly ICapPublisher _publisher;
/// <summary>
/// 初始化Cap事件总线
/// 初始化Cap消息事件总线
/// </summary>
/// <param name="publisher">Cap事件发布器</param>
public EventBus( ICapPublisher publisher ) {
_publisher = publisher;
public MessageEventBus( ICapPublisher publisher ) {
_publisher = publisher ?? throw new ArgumentNullException( nameof( publisher ) );
}
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
/// <typeparam name="TEvent">事件类型</typeparam>
/// <param name="event">事件</param>
public void Publish<TData>( Event<TData> @event ) {
public void Publish<TEvent>( TEvent @event ) where TEvent : IMessageEvent {
_publisher.Publish( @event.Target, @event.Data, @event.Callback );
}
}
+60
View File
@@ -0,0 +1,60 @@
using Util.Events.Handlers;
using Util.Events.Messages;
using Util.Logs.Aspects;
namespace Util.Events.Default {
/// <summary>
/// 事件总线
/// </summary>
public class EventBus : IEventBus {
/// <summary>
/// 初始化事件总线
/// </summary>
/// <param name="manager">事件处理器服务</param>
/// <param name="messageEventBus">消息事件总线</param>
public EventBus( IEventHandlerManager manager, IMessageEventBus messageEventBus = null ) {
Manager = manager;
MessageEventBus = messageEventBus;
}
/// <summary>
/// 事件处理器服务
/// </summary>
public IEventHandlerManager Manager { get; set; }
/// <summary>
/// 消息事件总线
/// </summary>
public IMessageEventBus MessageEventBus { get; set; }
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TEvent">事件类型</typeparam>
/// <param name="event">事件</param>
[TraceLog]
public void Publish<TEvent>( TEvent @event ) where TEvent : IEvent {
SyncHandle( @event );
if( @event is IMessageEvent messageEvent )
AsyncHandle( messageEvent );
}
/// <summary>
/// 同步处理 - 在当前线程处理
/// </summary>
private void SyncHandle<TEvent>( TEvent @event ) where TEvent : IEvent {
var handlers = Manager.GetHandlers<TEvent>();
if( handlers == null )
return;
foreach( var handler in handlers )
handler.Handle( @event );
}
/// <summary>
/// 异步处理 - 发送到消息中间件
/// </summary>
private void AsyncHandle( IMessageEvent messageEvent ) {
MessageEventBus?.Publish( messageEvent );
}
}
}
@@ -2,7 +2,7 @@
using Util.Events.Handlers;
using Util.Helpers;
namespace Util.Events.Memory {
namespace Util.Events.Default {
/// <summary>
/// 事件处理器服务
/// </summary>
@@ -10,9 +10,9 @@ namespace Util.Events.Memory {
/// <summary>
/// 获取事件处理器列表
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
public List<IEventHandler<TData>> GetHandlers<TData>() {
return Ioc.CreateList<IEventHandler<TData>>();
/// <typeparam name="TEvent">事件类型</typeparam>
public List<IEventHandler<TEvent>> GetHandlers<TEvent>() where TEvent : IEvent {
return Ioc.CreateList<IEventHandler<TEvent>>();
}
}
}
@@ -1,18 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
using Util.Events.Handlers;
namespace Util.Events.Memory {
namespace Util.Events.Default {
/// <summary>
/// 事件总线扩展
/// </summary>
public static class Extensions {
/// <summary>
/// 注册事件总线服务 - 内存同步事件
/// 注册事件总线服务
/// </summary>
/// <param name="services">服务集合</param>
public static void AddEventBus( this IServiceCollection services ) {
services.AddSingleton<IEventHandlerManager, EventHandlerManager>();
services.AddSingleton<IEventBus, EventBus>();
services.AddSingleton<IEventBus, Util.Events.Default.EventBus>();
}
}
}
-36
View File
@@ -1,36 +0,0 @@
using Util.Events.Handlers;
using Util.Logs.Aspects;
namespace Util.Events.Memory {
/// <summary>
/// 事件总线
/// </summary>
public class EventBus : IEventBus {
/// <summary>
/// 初始化事件总线
/// </summary>
/// <param name="manager">事件处理器服务</param>
public EventBus( IEventHandlerManager manager ) {
Manager = manager;
}
/// <summary>
/// 事件处理器服务
/// </summary>
public IEventHandlerManager Manager { get; set; }
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
/// <param name="event">事件</param>
[TraceLog]
public void Publish<TData>( Event<TData> @event ) {
var handlers = Manager.GetHandlers<TData>();
if( handlers == null )
return;
foreach( var handler in handlers )
handler.Handle( @event );
}
}
}
+13 -43
View File
@@ -5,64 +5,34 @@ namespace Util.Events {
/// <summary>
/// 事件
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
public class Event<TData> {
public class Event : IEvent {
/// <summary>
/// 初始化事件
/// </summary>
public Event( TData data ) {
Timestamp = DateTime.Now;
Data = data;
public Event() {
Id = Guid.NewGuid().ToString();
Time = DateTime.Now;
}
/// <summary>
/// 事件标识
/// </summary>
public string Id { get; set; }
/// <summary>
/// 事件时间
/// </summary>
public DateTime Timestamp { get; }
/// <summary>
/// 事件数据
/// </summary>
public TData Data { get; set; }
/// <summary>
/// 发送目标
/// </summary>
public string Target { get; set; }
/// <summary>
/// 回调
/// </summary>
public string Callback { get; set; }
public DateTime Time { get; }
/// <summary>
/// 输出日志
/// </summary>
public override string ToString() {
StringBuilder result = new StringBuilder();
result.AppendLine( $"事件时间:{Timestamp.ToMillisecondString()}" );
if( string.IsNullOrWhiteSpace( Target ) == false )
result.AppendLine( $"发送目标:{Target}" );
if( string.IsNullOrWhiteSpace( Callback ) == false )
result.AppendLine( $"回调:{Callback}" );
result.Append( $"事件数据:{Util.Helpers.Json.ToJson( Data )}" );
result.AppendLine( $"事件标识: {Id}" );
result.AppendLine( $"事件时间: {Time.ToMillisecondString()}" );
result.Append( $"事件数据:{Util.Helpers.Json.ToJson( this )}" );
return result.ToString();
}
}
/// <summary>
/// 事件
/// </summary>
public static class Event {
/// <summary>
/// 创建事件
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
/// <param name="data">事件数据</param>
/// <param name="target">发送目标</param>
/// <param name="callback">回调</param>
public static Event<TData> Create<TData>( TData data, string target = null, string callback = null ) {
return new Event<TData>( data ) { Target = target, Callback = callback };
}
}
}
+3 -3
View File
@@ -8,12 +8,12 @@
/// <summary>
/// 事件处理器
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
public interface IEventHandler<TData> : IEventHandler {
/// <typeparam name="TEvent">事件类型</typeparam>
public interface IEventHandler<in TEvent> : IEventHandler where TEvent : IEvent {
/// <summary>
/// 处理事件
/// </summary>
/// <param name="event">事件</param>
void Handle( Event<TData> @event );
void Handle( TEvent @event ) ;
}
}
@@ -8,7 +8,7 @@ namespace Util.Events.Handlers {
/// <summary>
/// 获取事件处理器列表
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
List<IEventHandler<TData>> GetHandlers<TData>();
/// <typeparam name="TEvent">事件类型</typeparam>
List<IEventHandler<TEvent>> GetHandlers<TEvent>() where TEvent : IEvent;
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
namespace Util.Events {
/// <summary>
/// 事件
/// </summary>
public interface IEvent {
/// <summary>
/// 事件标识
/// </summary>
string Id { get; set; }
/// <summary>
/// 事件时间
/// </summary>
DateTime Time { get; }
}
}
+2 -2
View File
@@ -6,8 +6,8 @@
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
/// <typeparam name="TEvent">事件类型</typeparam>
/// <param name="event">事件</param>
void Publish<TData>( Event<TData> @event );
void Publish<TEvent>( TEvent @event ) where TEvent : IEvent;
}
}
+21
View File
@@ -0,0 +1,21 @@
namespace Util.Events.Messages {
/// <summary>
/// 消息事件
/// </summary>
public interface IMessageEvent : IEvent {
/// <summary>
/// 事件数据
/// </summary>
object Data { get; set; }
/// <summary>
/// 发送目标
/// </summary>
string Target { get; set; }
/// <summary>
/// 回调
/// </summary>
string Callback { get; set; }
}
}
@@ -0,0 +1,13 @@
namespace Util.Events.Messages {
/// <summary>
/// 消息事件总线
/// </summary>
public interface IMessageEventBus {
/// <summary>
/// 发布事件
/// </summary>
/// <typeparam name="TEvent">事件类型</typeparam>
/// <param name="event">事件</param>
void Publish<TEvent>( TEvent @event ) where TEvent : IMessageEvent;
}
}
+38
View File
@@ -0,0 +1,38 @@
using System.Text;
namespace Util.Events.Messages {
/// <summary>
/// 消息事件
/// </summary>
public class MessageEvent : Event, IMessageEvent {
/// <summary>
/// 事件数据
/// </summary>
public object Data { get; set; }
/// <summary>
/// 发送目标
/// </summary>
public string Target { get; set; }
/// <summary>
/// 回调
/// </summary>
public string Callback { get; set; }
/// <summary>
/// 输出日志
/// </summary>
public override string ToString() {
StringBuilder result = new StringBuilder();
result.AppendLine( $"事件标识: {Id}" );
result.AppendLine( $"事件时间:{Time.ToMillisecondString()}" );
if( string.IsNullOrWhiteSpace( Target ) == false )
result.AppendLine( $"发送目标:{Target}" );
if( string.IsNullOrWhiteSpace( Callback ) == false )
result.AppendLine( $"回调:{Callback}" );
result.Append( $"事件数据:{Util.Helpers.Json.ToJson( Data )}" );
return result.ToString();
}
}
}
+7 -8
View File
@@ -1,7 +1,6 @@
using NSubstitute;
using Util.Events;
using Util.Events.Default;
using Util.Events.Handlers;
using Util.Events.Memory;
using Util.Tests.Samples;
using Xunit;
@@ -13,18 +12,18 @@ namespace Util.Tests.Events {
/// <summary>
/// 事件处理器
/// </summary>
private readonly IEventHandler<EventDataSample> _handler;
private readonly IEventHandler<EventSample> _handler;
/// <summary>
/// 事件处理器2
/// </summary>
private readonly IEventHandler<EventDataSample> _handler2;
private readonly IEventHandler<EventSample> _handler2;
/// <summary>
/// 测试初始化
/// </summary>
public EventBusTest() {
_handler = Substitute.For<IEventHandler<EventDataSample>>();
_handler2 = Substitute.For<IEventHandler<EventDataSample>>();
_handler = Substitute.For<IEventHandler<EventSample>>();
_handler2 = Substitute.For<IEventHandler<EventSample>>();
}
/// <summary>
@@ -34,7 +33,7 @@ namespace Util.Tests.Events {
public void TestPublish() {
var manager = new EventHandlerManagerSample( _handler );
var eventBus = new EventBus( manager );
var @event = Event.Create( new EventDataSample {Name = "a"} );
var @event = new EventSample { Name = "a" };
eventBus.Publish( @event );
_handler.Received( 1 ).Handle( @event );
}
@@ -46,7 +45,7 @@ namespace Util.Tests.Events {
public void TestPublish_2() {
var manager = new EventHandlerManagerSample( _handler , _handler2 );
var eventBus = new EventBus( manager );
var @event = Event.Create( new EventDataSample { Name = "a" } );
var @event = new EventSample { Name = "a" };
eventBus.Publish( @event );
_handler.Received( 1 ).Handle( @event );
_handler2.Received( 1 ).Handle( @event );
+5 -5
View File
@@ -5,9 +5,9 @@ using Util.Events.Handlers;
namespace Util.Tests.Samples {
/// <summary>
/// 事件数据样例
/// 事件样例
/// </summary>
public class EventDataSample {
public class EventSample : Event{
/// <summary>
/// 名称
/// </summary>
@@ -34,9 +34,9 @@ namespace Util.Tests.Samples {
/// <summary>
/// 获取事件处理器列表
/// </summary>
/// <typeparam name="TData">事件数据类型</typeparam>
public List<IEventHandler<TData>> GetHandlers<TData>() {
return _handlers.Select( t => t as IEventHandler<TData> ).ToList();
/// <typeparam name="TEvent">事件类型</typeparam>
public List<IEventHandler<TEvent>> GetHandlers<TEvent>() where TEvent : IEvent {
return _handlers.Select( t => t as IEventHandler<TEvent> ).ToList();
}
}
}