Skip to content

Commit

Permalink
Merge pull request #1 from june-it/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
june-it authored Dec 18, 2024
2 parents 92eb028 + 919e0d9 commit 6f614e6
Show file tree
Hide file tree
Showing 19 changed files with 258 additions and 159 deletions.
86 changes: 85 additions & 1 deletion NUGET.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,88 @@
# MyStack.LocalMessage

开源的轻量级本地消息总线类库
Open-source lightweight local message bus library

# Getting Started

## Add Service Support
```
services.AddLocalMessage(Assembly.GetExecutingAssembly());
```

## 1、Event Subscription and Publication
### Define Events
```
public class HelloEvent: ILocalEvent
{
}
```

### Subscribe to Events
```
public class HelloEventHandler : ILocalEventHandler<HelloEvent>
{
public async Task HandleAsync(HelloEvent eventData, CancellationToken cancellationToken = default)
{
await Task.CompletedTask;
}
}
```
### Publish Events
```
await eventBus.PublishAsync(new HelloEvent());
```
## 2、Request/Response Subscription and Publication
### Define Requests
```
public class Ping : IRequest<Pong>
{
}
```
### Define Responses
```
public class Pong
{
}
```

### Subscribe to Requests and Return Response Results
```
public class PingHandler : IRequestHandler<Ping, Pong>
{
public Task<Pong> HandleAsync(Ping eventData, CancellationToken cancellationToken = default)
{
return Task.FromResult(new Pong());
}
}
```
### Publish Requests
```
var pongMessage = eventBus.SendAsync(ping);
```

## 3、Wrapped Event Data Subscription and Publication
### Define Wrapped Event Data
```
public class WrappedEventData
{
}
```

### Subscribe to Wrapped Event Data
```
public class WrappedEventHandler : ILocalEventHandler<LocalEventWrapper<WrappedEventData>>
{
public async Task HandleAsync(LocalEventWrapper<WrappedEventData> eventData, CancellationToken cancellationToken = default)
{
await Task.CompletedTask;
}
}
```

### Publish Wrapped Event Data
```
eventBus.SendAsync(new WrappedEventData());
```
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
# MyStack.LocalMessage

开源的轻量级本地事件总线类库
Open-source lightweight local message bus library


| nuget | stats |
| ----------- | ----------- |
| [![nuget](https://img.shields.io/nuget/v/MyStack.LocalMessage.svg?style=flat-square)](https://www.nuget.org/packages/MyStack.LocalMessage) | [![stats](https://img.shields.io/nuget/dt/MyStack.LocalMessage.svg?style=flat-square)](https://www.nuget.org/stats/packages/MyStack.LocalMessage?groupby=Version) |

# 开始使用
# Getting Started

## 添加服务支持
## Add Service Support
```
services.AddLocalMessage(Assembly.GetExecutingAssembly());
```

## 1、事件订阅发布
### 定义事件
## 1、Event Subscription and Publication
### Define Events
```
public class HelloEvent: ILocalEvent
{
}
```

### 订阅事件
### Subscribe to Events
```
public class HelloEventHandler : ILocalEventHandler<HelloEvent>
{
Expand All @@ -33,26 +33,26 @@ public class HelloEventHandler : ILocalEventHandler<HelloEvent>
}
}
```
### 发布事件
### Publish Events
```
await eventBus.PublishAsync(new HelloEvent());
```
## 2、请求/响应订阅发布
### 定义请求
## 2、Request/Response Subscription and Publication
### Define Requests
```
public class Ping : IRequest<Pong>
{
}
```
### 定义响应
### Define Responses
```
public class Pong
{
}
```

### 订阅请求并返回响应结果
### Subscribe to Requests and Return Response Results
```
public class PingHandler : IRequestHandler<Ping, Pong>
{
Expand All @@ -62,37 +62,37 @@ public class PingHandler : IRequestHandler<Ping, Pong>
}
}
```
### 发布请求
### Publish Requests
```
var pongMessage = eventBus.SendAsync(ping);
```

## 3、事件体订阅发布
### 定义事件体的消息对象
## 3、Wrapped Event Data Subscription and Publication
### Define Wrapped Event Data
```
public class WrappedEventData
{
}
```

### 订阅事件体
### Subscribe to Wrapped Event Data
```
public class WrappedEventHandler : ILocalEventHandler<WrappedEvent<WrappedEventData>>
public class WrappedEventHandler : ILocalEventHandler<LocalEventWrapper<WrappedEventData>>
{
public async Task HandleAsync(WrappedEvent<WrappedEventData> eventData, CancellationToken cancellationToken = default)
public async Task HandleAsync(LocalEventWrapper<WrappedEventData> eventData, CancellationToken cancellationToken = default)
{
await Task.CompletedTask;
}
}
```

### 发布事件体
### Publish Wrapped Event Data
```
eventBus.SendAsync(new WrappedEventData());
```


# 许可证
# License

MIT
32 changes: 17 additions & 15 deletions src/MyStack.LocalMessage/DefaultLocalEventBus.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.LocalMessage.Subscriptions;
using Microsoft.Extensions.LocalMessage;
using System;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.LocalMessage.Subscriptions;

namespace Microsoft.Extensions.LocalMessage
{
public class DefaultLocalEventBus : ILocalMessageBus
{
private readonly ISubscriptionManager _subscriptionManager;
private static Dictionary<string, Type> _cache = new Dictionary<string, Type>();
private readonly IServiceProvider _serviceProvider;
public DefaultLocalEventBus(IServiceProvider serviceProvider)
{
Expand All @@ -27,7 +23,7 @@ public async virtual Task PublishAsync(ILocalEvent eventData, CancellationToken
{
foreach (var subscription in subscriptions)
{
var eventHandlerType = subscription.EventHandlerType.MakeGenericType(subscription.EventType);
var eventHandlerType = subscription.HandlerType.MakeGenericType(subscription.MessageType);
var eventHandler = _serviceProvider.GetRequiredService(eventHandlerType);
await ((dynamic)eventHandler).HandleAsync((dynamic)eventData, cancellationToken);
}
Expand All @@ -42,24 +38,30 @@ public async Task PublishAsync(object eventData, CancellationToken cancellationT
{
foreach (var subscription in subscriptions)
{
var wrappedEvent = typeof(WrappedEvent<>).MakeGenericType(eventType);
var eventHandlerType = subscription.EventHandlerType.MakeGenericType(wrappedEvent);
var wrappedEvent = typeof(LocalEventWrapper<>).MakeGenericType(eventType);
var eventHandlerType = subscription.HandlerType.MakeGenericType(wrappedEvent);
var eventHandler = _serviceProvider.GetRequiredService(eventHandlerType);
var wrappedEventData = Activator.CreateInstance(wrappedEvent, eventData);
if (wrappedEventData == null)
throw new ArgumentNullException(nameof(wrappedEventData));
await ((dynamic)eventHandler).HandleAsync((dynamic)wrappedEventData, cancellationToken);
}
}
}

public async virtual Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> requestData, CancellationToken cancellationToken = default) where TResponse : class
{
var dataType = requestData.GetType();
var subscriptions = _subscriptionManager.GetSubscriptions(dataType);
var requestDataType = requestData.GetType();
var subscriptions = _subscriptionManager.GetSubscriptions(requestDataType);
if (subscriptions == null)
throw new InvalidOperationException("未查找到任何事件订阅。");
throw new InvalidOperationException("No event subscriptions were found.");
if (subscriptions != null && subscriptions.Count > 1)
throw new InvalidOperationException("有且仅能支持一个事件订阅。");
var requestHandlerType = subscriptions![0].EventHandlerType.MakeGenericType(subscriptions[0].EventType, subscriptions[0].ResponseType);
throw new InvalidOperationException("Only one event subscription is supported.");
Type requestHandlerType;
if (subscriptions?[0]?.ResponseType != null)
requestHandlerType = subscriptions![0].HandlerType.MakeGenericType(subscriptions[0].MessageType, subscriptions[0].ResponseType!);
else
requestHandlerType = subscriptions![0].HandlerType.MakeGenericType(subscriptions[0].MessageType);
var requestHandler = _serviceProvider.GetRequiredService(requestHandlerType);
return await ((dynamic)requestHandler).HandleAsync((dynamic)requestData, cancellationToken);
}
Expand Down
26 changes: 26 additions & 0 deletions src/MyStack.LocalMessage/IEventPublisher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Extensions.LocalMessage
{
/// <summary>
/// Represents the event publisher interface
/// </summary>
public interface IEventPublisher
{
/// <summary>
/// Publish an Event
/// </summary>
/// <param name="eventData">Event</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <returns></returns>
Task PublishAsync(ILocalEvent eventData, CancellationToken cancellationToken = default);
/// <summary>
/// Publish an Event Data
/// </summary>
/// <param name="eventData">Event data</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <returns></returns>
Task PublishAsync(object eventData, CancellationToken cancellationToken = default);
}
}
6 changes: 3 additions & 3 deletions src/MyStack.LocalMessage/ILocalEvent.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace Microsoft.Extensions.LocalMessage
{
/// <summary>
/// 表示一个事件接口
/// Represents an event interface
/// </summary>
public interface ILocalEvent
{
{
}

}
19 changes: 6 additions & 13 deletions src/MyStack.LocalMessage/ILocalEventHandler.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
using System.Threading.Tasks;
using System.Threading;
using System.Xml.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Extensions.LocalMessage
{
/// <summary>
/// 表示一个本地事件订阅接口
/// Represents an event subscription interface
/// </summary>
public interface ILocalEventHandler
{
}
/// <summary>
/// 表示一个事件订阅接口
/// </summary>
/// <typeparam name="TEvent">事件的类型</typeparam>
public interface ILocalEventHandler<TEvent> : ILocalEventHandler
/// <typeparam name="TEvent">The type of the event</typeparam>
public interface ILocalEventHandler<TEvent>
where TEvent : class, ILocalEvent
{
Task HandleAsync(TEvent eventData, CancellationToken cancellationToken = default);
}

}
33 changes: 3 additions & 30 deletions src/MyStack.LocalMessage/ILocalMessageBus.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,9 @@
using Microsoft.Extensions.LocalMessage;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Extensions.LocalMessage
namespace Microsoft.Extensions.LocalMessage
{
/// <summary>
/// 表示本地事件总线接口
/// Represents the local message bus interface
/// </summary>
public interface ILocalMessageBus
public interface ILocalMessageBus : IEventPublisher, IRequestSender
{
/// <summary>
/// 发布一个事件
/// </summary>
/// <param name="eventData">事件数据</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns></returns>
Task PublishAsync(ILocalEvent eventData, CancellationToken cancellationToken = default);
/// <summary>
/// 发布一个事件体
/// </summary>
/// <param name="eventData">事件体对象</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns></returns>
Task PublishAsync(object eventData, CancellationToken cancellationToken = default);
/// <summary>
/// 发送一个有返回结果的事件请求
/// </summary>
/// <typeparam name="TResponse">返回结果的类型</typeparam>
/// <param name="requestData">事件数据</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>处理成功时返回结果,否则返回null</returns>
Task<TResponse?> SendAsync<TResponse>(IRequest<TResponse> requestData, CancellationToken cancellationToken = default)
where TResponse : class;
}
}
2 changes: 1 addition & 1 deletion src/MyStack.LocalMessage/IRequest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Microsoft.Extensions.LocalMessage
{
/// <summary>
/// 表示一个可返回结果的事件接口
/// Represents an event interface that can return a result
/// </summary>
/// <typeparam name="TResponse"></typeparam>
public interface IRequest<TResponse>
Expand Down
Loading

0 comments on commit 6f614e6

Please sign in to comment.