mirror of https://github.com/abpframework/abp.git
19 changed files with 1199 additions and 5 deletions
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.EventBus</AssemblyName> |
||||
|
<PackageId>Volo.Abp.EventBus</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
public class AbpEventBusModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
services.AddAssemblyOf<AbpEventBusModule>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,495 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Factories; |
||||
|
using Volo.Abp.EventBus.Factories.Internals; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
using Volo.Abp.EventBus.Handlers.Internals; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements EventBus as Singleton pattern.
|
||||
|
/// </summary>
|
||||
|
public class EventBus : IEventBus, ISingletonDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the default <see cref="EventBus"/> instance.
|
||||
|
/// </summary>
|
||||
|
public static EventBus Instance { get; } = new EventBus(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Reference to the Logger.
|
||||
|
/// </summary>
|
||||
|
public ILogger<EventBus> Logger { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// All registered handler factories.
|
||||
|
/// Key: Type of the event
|
||||
|
/// Value: List of handler factories
|
||||
|
/// </summary>
|
||||
|
private readonly ConcurrentDictionary<Type, List<IEventHandlerFactory>> _handlerFactories; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new <see cref="EventBus"/> instance.
|
||||
|
/// Instead of creating a new instace, you can use <see cref="Instance"/> to use Global <see cref="EventBus"/>.
|
||||
|
/// </summary>
|
||||
|
public EventBus() |
||||
|
{ |
||||
|
_handlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>(); |
||||
|
Logger = NullLogger<EventBus>.Instance; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register<TEventData>(Action<TEventData> action) |
||||
|
where TEventData : class |
||||
|
{ |
||||
|
return Register(typeof(TEventData), new ActionEventHandler<TEventData>(action)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable AsyncRegister<TEventData>(Func<TEventData, Task> action) where TEventData : class |
||||
|
{ |
||||
|
return Register(typeof(TEventData), new AsyncActionEventHandler<TEventData>(action)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register<TEventData>(IEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
return Register(typeof(TEventData), handler); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable AsyncRegister<TEventData>(IAsyncEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
return Register(typeof(TEventData), handler); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register<TEventData, THandler>() |
||||
|
where TEventData : class |
||||
|
where THandler : IEventHandler, new() |
||||
|
{ |
||||
|
return Register(typeof(TEventData), new TransientEventHandlerFactory<THandler>()); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register(Type eventType, IEventHandler handler) |
||||
|
{ |
||||
|
return Register(eventType, new SingleInstanceHandlerFactory(handler)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register<TEventData>(IEventHandlerFactory factory) where TEventData : class |
||||
|
{ |
||||
|
return Register(typeof(TEventData), factory); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IDisposable Register(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType) |
||||
|
.Locking(factories => factories.Add(factory)); |
||||
|
|
||||
|
return new FactoryUnregistrar(this, eventType, factory); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Unregister<TEventData>(Action<TEventData> action) where TEventData : class |
||||
|
{ |
||||
|
Check.NotNull(action, nameof(action)); |
||||
|
|
||||
|
GetOrCreateHandlerFactories(typeof(TEventData)) |
||||
|
.Locking(factories => |
||||
|
{ |
||||
|
factories.RemoveAll( |
||||
|
factory => |
||||
|
{ |
||||
|
var singleInstanceFactory = factory as SingleInstanceHandlerFactory; |
||||
|
if (singleInstanceFactory == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler<TEventData>; |
||||
|
if (actionHandler == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return actionHandler.Action == action; |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void AsyncUnregister<TEventData>(Func<TEventData, Task> action) where TEventData : class |
||||
|
{ |
||||
|
Check.NotNull(action, nameof(action)); |
||||
|
|
||||
|
GetOrCreateHandlerFactories(typeof(TEventData)) |
||||
|
.Locking(factories => |
||||
|
{ |
||||
|
factories.RemoveAll( |
||||
|
factory => |
||||
|
{ |
||||
|
var singleInstanceFactory = factory as SingleInstanceHandlerFactory; |
||||
|
if (singleInstanceFactory == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var actionHandler = singleInstanceFactory.HandlerInstance as AsyncActionEventHandler<TEventData>; |
||||
|
if (actionHandler == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return actionHandler.Action == action; |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Unregister<TEventData>(IEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
Unregister(typeof(TEventData), handler); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void AsyncUnregister<TEventData>(IAsyncEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
Unregister(typeof(TEventData), handler); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Unregister(Type eventType, IEventHandler handler) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType) |
||||
|
.Locking(factories => |
||||
|
{ |
||||
|
factories.RemoveAll( |
||||
|
factory => |
||||
|
factory is SingleInstanceHandlerFactory && |
||||
|
(factory as SingleInstanceHandlerFactory).HandlerInstance == handler |
||||
|
); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Unregister<TEventData>(IEventHandlerFactory factory) where TEventData : class |
||||
|
{ |
||||
|
Unregister(typeof(TEventData), factory); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Unregister(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void UnregisterAll<TEventData>() where TEventData : class |
||||
|
{ |
||||
|
UnregisterAll(typeof(TEventData)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void UnregisterAll(Type eventType) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Trigger<TEventData>(TEventData eventData) where TEventData : class |
||||
|
{ |
||||
|
Trigger(typeof(TEventData), eventData); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public void Trigger(Type eventType, object eventData) |
||||
|
{ |
||||
|
var exceptions = new List<Exception>(); |
||||
|
|
||||
|
foreach (var handlerFactories in GetHandlerFactories(eventType)) |
||||
|
{ |
||||
|
foreach (var handlerFactory in handlerFactories.EventHandlerFactories) |
||||
|
{ |
||||
|
var handlerType = handlerFactory.GetHandlerType(); |
||||
|
|
||||
|
if (IsAsyncEventHandler(handlerType)) |
||||
|
{ |
||||
|
AsyncHelper.RunSync(() => TriggerAsyncHandlingException(handlerFactory, handlerFactories.EventType, eventData, exceptions)); |
||||
|
} |
||||
|
else if (IsEventHandler(handlerType)) |
||||
|
{ |
||||
|
TriggerHandlingException(handlerFactory, handlerFactories.EventType, eventData, exceptions); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var message = $"Event handler to register for event type {eventType.Name} does not implement IEventHandler<{eventType.Name}> or IAsyncEventHandler<{eventType.Name}> interface!"; |
||||
|
exceptions.Add(new AbpException(message)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//Implements generic argument inheritance. See classWithInheritableGenericArgument
|
||||
|
if (eventType.GetTypeInfo().IsGenericType && |
||||
|
eventType.GetGenericArguments().Length == 1 && |
||||
|
typeof(IEventDataWithInheritableGenericArgument).IsAssignableFrom(eventType)) |
||||
|
{ |
||||
|
var genericArg = eventType.GetGenericArguments()[0]; |
||||
|
var baseArg = genericArg.GetTypeInfo().BaseType; |
||||
|
if (baseArg != null) |
||||
|
{ |
||||
|
var baseEventType = eventType.GetGenericTypeDefinition().MakeGenericType(baseArg); |
||||
|
var constructorArgs = ((IEventDataWithInheritableGenericArgument)eventData).GetConstructorArgs(); |
||||
|
var baseEventData = Activator.CreateInstance(baseEventType, constructorArgs); |
||||
|
Trigger(baseEventType, baseEventData); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (exceptions.Any()) |
||||
|
{ |
||||
|
if (exceptions.Count == 1) |
||||
|
{ |
||||
|
exceptions[0].ReThrow(); |
||||
|
} |
||||
|
|
||||
|
throw new AggregateException("More than one error has occurred while triggering the event: " + eventType, exceptions); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : class |
||||
|
{ |
||||
|
return TriggerAsync(typeof(TEventData), eventData); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public async Task TriggerAsync(Type eventType, object eventData) |
||||
|
{ |
||||
|
var exceptions = new List<Exception>(); |
||||
|
|
||||
|
await new SynchronizationContextRemover(); |
||||
|
|
||||
|
foreach (var handlerFactories in GetHandlerFactories(eventType)) |
||||
|
{ |
||||
|
foreach (var handlerFactory in handlerFactories.EventHandlerFactories) |
||||
|
{ |
||||
|
var handlerType = handlerFactory.GetHandlerType(); |
||||
|
|
||||
|
if (IsAsyncEventHandler(handlerType)) |
||||
|
{ |
||||
|
await TriggerAsyncHandlingException(handlerFactory, handlerFactories.EventType, eventData, exceptions); |
||||
|
} |
||||
|
else if (IsEventHandler(handlerType)) |
||||
|
{ |
||||
|
TriggerHandlingException(handlerFactory, handlerFactories.EventType, eventData, exceptions); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var message = $"Event handler to register for event type {eventType.Name} does not implement IEventHandler<{eventType.Name}> or IAsyncEventHandler<{eventType.Name}> interface!"; |
||||
|
exceptions.Add(new AbpException(message)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//Implements generic argument inheritance. See classWithInheritableGenericArgument
|
||||
|
if (eventType.GetTypeInfo().IsGenericType && |
||||
|
eventType.GetGenericArguments().Length == 1 && |
||||
|
typeof(IEventDataWithInheritableGenericArgument).IsAssignableFrom(eventType)) |
||||
|
{ |
||||
|
var genericArg = eventType.GetGenericArguments()[0]; |
||||
|
var baseArg = genericArg.GetTypeInfo().BaseType; |
||||
|
if (baseArg != null) |
||||
|
{ |
||||
|
var baseEventType = eventType.GetGenericTypeDefinition().MakeGenericType(baseArg); |
||||
|
var constructorArgs = ((IEventDataWithInheritableGenericArgument)eventData).GetConstructorArgs(); |
||||
|
var baseEventData = Activator.CreateInstance(baseEventType, constructorArgs); |
||||
|
await TriggerAsync(baseEventType, baseEventData); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (exceptions.Any()) |
||||
|
{ |
||||
|
if (exceptions.Count == 1) |
||||
|
{ |
||||
|
exceptions[0].ReThrow(); |
||||
|
} |
||||
|
|
||||
|
throw new AggregateException("More than one error has occurred while triggering the event: " + eventType, exceptions); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void TriggerHandlingException(IEventHandlerFactory handlerFactory, Type eventType, object eventData, List<Exception> exceptions) |
||||
|
{ |
||||
|
var eventHandler = handlerFactory.GetHandler(); |
||||
|
try |
||||
|
{ |
||||
|
if (eventHandler == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException($"Registered event handler for event type {eventType.Name} is null!"); |
||||
|
} |
||||
|
|
||||
|
var handlerType = typeof(IEventHandler<>).MakeGenericType(eventType); |
||||
|
|
||||
|
var method = handlerType.GetMethod( |
||||
|
"HandleEvent", |
||||
|
new[] { eventType } |
||||
|
); |
||||
|
|
||||
|
method.Invoke(eventHandler, new[] { eventData }); |
||||
|
} |
||||
|
catch (TargetInvocationException ex) |
||||
|
{ |
||||
|
exceptions.Add(ex.InnerException); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exceptions.Add(ex); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
handlerFactory.ReleaseHandler(eventHandler); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task TriggerAsyncHandlingException(IEventHandlerFactory asyncHandlerFactory, Type eventType, object eventData, List<Exception> exceptions) |
||||
|
{ |
||||
|
var asyncEventHandler = asyncHandlerFactory.GetHandler(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (asyncEventHandler == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException($"Registered async event handler for event type {eventType.Name} is null!"); |
||||
|
} |
||||
|
|
||||
|
var asyncHandlerType = typeof(IAsyncEventHandler<>).MakeGenericType(eventType); |
||||
|
|
||||
|
var method = asyncHandlerType.GetMethod( |
||||
|
"HandleEventAsync", |
||||
|
new[] { eventType } |
||||
|
); |
||||
|
|
||||
|
await (Task)method.Invoke(asyncEventHandler, new[] { eventData }); |
||||
|
} |
||||
|
catch (TargetInvocationException ex) |
||||
|
{ |
||||
|
exceptions.Add(ex.InnerException); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exceptions.Add(ex); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
asyncHandlerFactory.ReleaseHandler(asyncEventHandler); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private bool IsEventHandler(Type handlerType) |
||||
|
{ |
||||
|
return handlerType.GetInterfaces() |
||||
|
.Where(i => i.IsGenericType) |
||||
|
.Any(i => i.GetGenericTypeDefinition() == typeof(IEventHandler<>)); |
||||
|
} |
||||
|
|
||||
|
private bool IsAsyncEventHandler(Type handlerType) |
||||
|
{ |
||||
|
return handlerType.GetInterfaces() |
||||
|
.Where(i => i.IsGenericType) |
||||
|
.Any(i => i.GetGenericTypeDefinition() == typeof(IAsyncEventHandler<>)); |
||||
|
} |
||||
|
|
||||
|
private IEnumerable<EventTypeWithEventHandlerFactories> GetHandlerFactories(Type eventType) |
||||
|
{ |
||||
|
var handlerFactoryList = new List<EventTypeWithEventHandlerFactories>(); |
||||
|
|
||||
|
foreach (var handlerFactory in _handlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) |
||||
|
{ |
||||
|
handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); |
||||
|
} |
||||
|
|
||||
|
return handlerFactoryList.ToArray(); |
||||
|
} |
||||
|
|
||||
|
private static bool ShouldTriggerEventForHandler(Type eventType, Type handlerType) |
||||
|
{ |
||||
|
//Should trigger same type
|
||||
|
if (handlerType == eventType) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
//Should trigger for inherited types
|
||||
|
if (handlerType.IsAssignableFrom(eventType)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType) |
||||
|
{ |
||||
|
return _handlerFactories.GetOrAdd(eventType, (type) => new List<IEventHandlerFactory>()); |
||||
|
} |
||||
|
|
||||
|
private class EventTypeWithEventHandlerFactories |
||||
|
{ |
||||
|
public Type EventType { get; } |
||||
|
|
||||
|
public List<IEventHandlerFactory> EventHandlerFactories { get; } |
||||
|
|
||||
|
public EventTypeWithEventHandlerFactories(Type eventType, List<IEventHandlerFactory> eventHandlerFactories) |
||||
|
{ |
||||
|
EventType = eventType; |
||||
|
EventHandlerFactories = eventHandlerFactories; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Reference from
|
||||
|
// https://blogs.msdn.microsoft.com/benwilli/2017/02/09/an-alternative-to-configureawaitfalse-everywhere/
|
||||
|
private struct SynchronizationContextRemover : INotifyCompletion |
||||
|
{ |
||||
|
public bool IsCompleted |
||||
|
{ |
||||
|
get { return SynchronizationContext.Current == null; } |
||||
|
} |
||||
|
|
||||
|
public void OnCompleted(Action continuation) |
||||
|
{ |
||||
|
var prevContext = SynchronizationContext.Current; |
||||
|
try |
||||
|
{ |
||||
|
SynchronizationContext.SetSynchronizationContext(null); |
||||
|
continuation(); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
SynchronizationContext.SetSynchronizationContext(prevContext); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public SynchronizationContextRemover GetAwaiter() |
||||
|
{ |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public void GetResult() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Factories |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines an interface for factories those are responsible to create/get and release of event handlers.
|
||||
|
/// </summary>
|
||||
|
public interface IEventHandlerFactory |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets an event handler.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The event handler</returns>
|
||||
|
IEventHandler GetHandler(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets type of the handler (without creating an instance).
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
Type GetHandlerType(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Releases an event handler.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">Handle to be released</param>
|
||||
|
void ReleaseHandler(IEventHandler handler); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Factories.Internals |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to unregister a <see cref="IEventHandlerFactory"/> on <see cref="Dispose"/> method.
|
||||
|
/// </summary>
|
||||
|
internal class FactoryUnregistrar : IDisposable |
||||
|
{ |
||||
|
private readonly IEventBus _eventBus; |
||||
|
private readonly Type _eventType; |
||||
|
private readonly IEventHandlerFactory _factory; |
||||
|
|
||||
|
public FactoryUnregistrar(IEventBus eventBus, Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
_eventBus = eventBus; |
||||
|
_eventType = eventType; |
||||
|
_factory = factory; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
_eventBus.Unregister(_eventType, _factory); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Factories.Internals |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This <see cref="IEventHandlerFactory"/> implementation is used to handle events
|
||||
|
/// by a single instance object.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// This class always gets the same single instance of handler.
|
||||
|
/// </remarks>
|
||||
|
internal class SingleInstanceHandlerFactory : IEventHandlerFactory |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The event handler instance.
|
||||
|
/// </summary>
|
||||
|
public IEventHandler HandlerInstance { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
///
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler"></param>
|
||||
|
public SingleInstanceHandlerFactory(IEventHandler handler) |
||||
|
{ |
||||
|
HandlerInstance = handler; |
||||
|
} |
||||
|
|
||||
|
public IEventHandler GetHandler() |
||||
|
{ |
||||
|
return HandlerInstance; |
||||
|
} |
||||
|
|
||||
|
public Type GetHandlerType() |
||||
|
{ |
||||
|
return ProxyHelper.UnProxy(HandlerInstance).GetType(); |
||||
|
} |
||||
|
|
||||
|
public void ReleaseHandler(IEventHandler handler) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Factories.Internals |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This <see cref="IEventHandlerFactory"/> implementation is used to handle events
|
||||
|
/// by a transient instance object.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// This class always creates a new transient instance of handler.
|
||||
|
/// </remarks>
|
||||
|
internal class TransientEventHandlerFactory<THandler> : IEventHandlerFactory |
||||
|
where THandler : IEventHandler, new() |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of the handler object.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The handler object</returns>
|
||||
|
public IEventHandler GetHandler() |
||||
|
{ |
||||
|
return new THandler(); |
||||
|
} |
||||
|
|
||||
|
public Type GetHandlerType() |
||||
|
{ |
||||
|
return typeof(THandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Disposes the handler object if it's <see cref="IDisposable"/>. Does nothing if it's not.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">Handler to be released</param>
|
||||
|
public void ReleaseHandler(IEventHandler handler) |
||||
|
{ |
||||
|
if (handler is IDisposable) |
||||
|
{ |
||||
|
(handler as IDisposable).Dispose(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Factories |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This <see cref="IEventHandlerFactory"/> implementation is used to get/release
|
||||
|
/// handlers using Ioc.
|
||||
|
/// </summary>
|
||||
|
public class IocHandlerFactory : IEventHandlerFactory |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Type of the handler.
|
||||
|
/// </summary>
|
||||
|
public Type HandlerType { get; } |
||||
|
|
||||
|
private readonly IServiceProvider _iocResolver; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="IocHandlerFactory"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="iocResolver"></param>
|
||||
|
/// <param name="handlerType">Type of the handler</param>
|
||||
|
public IocHandlerFactory(IServiceProvider iocResolver, Type handlerType) |
||||
|
{ |
||||
|
_iocResolver = iocResolver; |
||||
|
HandlerType = handlerType; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Resolves handler object from Ioc container.
|
||||
|
/// </summary>
|
||||
|
/// <returns>Resolved handler object</returns>
|
||||
|
public IEventHandler GetHandler() |
||||
|
{ |
||||
|
return (IEventHandler)_iocResolver.GetRequiredService(HandlerType); |
||||
|
} |
||||
|
|
||||
|
public Type GetHandlerType() |
||||
|
{ |
||||
|
return HandlerType; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Releases handler object using Ioc container.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">Handler to be released</param>
|
||||
|
public void ReleaseHandler(IEventHandler handler) |
||||
|
{ |
||||
|
//TODO: Scope!!!
|
||||
|
//_iocResolver.Release(handler);
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Handlers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines an interface of a class that handles events asynchrounously of type <see cref="IAsyncEventHandler{TEventData}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type to handle</typeparam>
|
||||
|
public interface IAsyncEventHandler<in TEventData> : IEventHandler |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Handler handles the event by implementing this method.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData">Event data</param>
|
||||
|
Task HandleEventAsync(TEventData eventData); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.EventBus.Handlers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Undirect base interface for all event handlers.
|
||||
|
/// Implement <see cref="IEventHandler{TEventData}"/> instead of this one.
|
||||
|
/// </summary>
|
||||
|
public interface IEventHandler |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
namespace Volo.Abp.EventBus.Handlers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines an interface of a class that handles events of type <see cref="IEventHandler{TEventData}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type to handle</typeparam>
|
||||
|
public interface IEventHandler<in TEventData> : IEventHandler |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Handler handles the event by implementing this method.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData">Event data</param>
|
||||
|
void HandleEvent(TEventData eventData); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Handlers.Internals |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This event handler is an adapter to be able to use an action as <see cref="IEventHandler{TEventData}"/> implementation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
internal class ActionEventHandler<TEventData> : |
||||
|
IEventHandler<TEventData>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Action to handle the event.
|
||||
|
/// </summary>
|
||||
|
public Action<TEventData> Action { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ActionEventHandler{TEventData}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">Action to handle the event</param>
|
||||
|
public ActionEventHandler(Action<TEventData> handler) |
||||
|
{ |
||||
|
Action = handler; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Handles the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData"></param>
|
||||
|
public void HandleEvent(TEventData eventData) |
||||
|
{ |
||||
|
Action(eventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus.Handlers.Internals |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This event handler is an adapter to be able to use an action as <see cref="IAsyncEventHandler{TEventData}"/> implementation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
internal class AsyncActionEventHandler<TEventData> : |
||||
|
IAsyncEventHandler<TEventData>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Function to handle the event.
|
||||
|
/// </summary>
|
||||
|
public Func<TEventData, Task> Action { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="AsyncActionEventHandler{TEventData}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="handler">Action to handle the event</param>
|
||||
|
public AsyncActionEventHandler(Func<TEventData, Task> handler) |
||||
|
{ |
||||
|
Action = handler; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Handles the event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData"></param>
|
||||
|
public async Task HandleEventAsync(TEventData eventData) |
||||
|
{ |
||||
|
await Action(eventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
public interface IDistributedEventBus |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,194 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.EventBus.Factories; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines interface of the event bus.
|
||||
|
/// </summary>
|
||||
|
public interface IEventBus |
||||
|
{ |
||||
|
#region Register
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Given action is called for all event occurrences.
|
||||
|
/// </summary>
|
||||
|
/// <param name="action">Action to handle events</param>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
IDisposable Register<TEventData>(Action<TEventData> action) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Given action is called for all event occurrences.
|
||||
|
/// </summary>
|
||||
|
/// <param name="action">Action to handle events</param>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
IDisposable AsyncRegister<TEventData>(Func<TEventData, Task> action) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Same (given) instance of the handler is used for all event occurrences.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="handler">Object to handle the event</param>
|
||||
|
IDisposable Register<TEventData>(IEventHandler<TEventData> handler) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Same (given) instance of the async handler is used for all event occurrences.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="handler">Object to handle the event</param>
|
||||
|
IDisposable AsyncRegister<TEventData>(IAsyncEventHandler<TEventData> handler) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// A new instance of <see cref="THandler"/> object is created for every event occurrence.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <typeparam name="THandler">Type of the event handler</typeparam>
|
||||
|
IDisposable Register<TEventData, THandler>() |
||||
|
where TEventData : class |
||||
|
where THandler : IEventHandler, new(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Same (given) instance of the handler is used for all event occurrences.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="handler">Object to handle the event</param>
|
||||
|
IDisposable Register(Type eventType, IEventHandler handler); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// Given factory is used to create/release handlers
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="factory">A factory to create/release handlers</param>
|
||||
|
IDisposable Register<TEventData>(IEventHandlerFactory factory) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers to an event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="factory">A factory to create/release handlers</param>
|
||||
|
IDisposable Register(Type eventType, IEventHandlerFactory factory); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Unregister
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="action"></param>
|
||||
|
void Unregister<TEventData>(Action<TEventData> action) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="action"></param>
|
||||
|
void AsyncUnregister<TEventData>(Func<TEventData, Task> action) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="handler">Handler object that is registered before</param>
|
||||
|
void Unregister<TEventData>(IEventHandler<TEventData> handler) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="handler">Handler object that is registered before</param>
|
||||
|
void AsyncUnregister<TEventData>(IAsyncEventHandler<TEventData> handler) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="handler">Handler object that is registered before</param>
|
||||
|
void Unregister(Type eventType, IEventHandler handler); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="factory">Factory object that is registered before</param>
|
||||
|
void Unregister<TEventData>(IEventHandlerFactory factory) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters from an event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="factory">Factory object that is registered before</param>
|
||||
|
void Unregister(Type eventType, IEventHandlerFactory factory); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters all event handlers of given event type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
void UnregisterAll<TEventData>() |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Unregisters all event handlers of given event type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
void UnregisterAll(Type eventType); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Trigger
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Triggers an event.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="eventData">Related data for the event</param>
|
||||
|
void Trigger<TEventData>(TEventData eventData) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Triggers an event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="eventData">Related data for the event</param>
|
||||
|
void Trigger(Type eventType, object eventData); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Triggers an event asynchronously.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEventData">Event type</typeparam>
|
||||
|
/// <param name="eventData">Related data for the event</param>
|
||||
|
/// <returns>The task to handle async operation</returns>
|
||||
|
Task TriggerAsync<TEventData>(TEventData eventData) |
||||
|
where TEventData : class; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Triggers an event asynchronously.
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventType">Event type</param>
|
||||
|
/// <param name="eventData">Related data for the event</param>
|
||||
|
/// <returns>The task to handle async operation</returns>
|
||||
|
Task TriggerAsync(Type eventType, object eventData); |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This interface must be implemented by event data classes that
|
||||
|
/// has a single generic argument and this argument will be used by inheritance.
|
||||
|
///
|
||||
|
/// For example;
|
||||
|
/// Assume that Student inherits From Person. When trigger an EntityCreatedEventData{Student},
|
||||
|
/// EntityCreatedEventData{Person} is also triggered if EntityCreatedEventData implements
|
||||
|
/// this interface.
|
||||
|
/// </summary>
|
||||
|
public interface IEventDataWithInheritableGenericArgument |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets arguments to create this class since a new instance of this class is created.
|
||||
|
/// </summary>
|
||||
|
/// <returns>Constructor arguments</returns>
|
||||
|
object[] GetConstructorArgs(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,122 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.EventBus.Factories; |
||||
|
using Volo.Abp.EventBus.Handlers; |
||||
|
|
||||
|
namespace Volo.Abp.EventBus |
||||
|
{ |
||||
|
public sealed class NullEventBus : IEventBus |
||||
|
{ |
||||
|
public static NullEventBus Instance { get; } = new NullEventBus(); |
||||
|
|
||||
|
private NullEventBus() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public IDisposable Register<TEventData>(Action<TEventData> action) where TEventData : class |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable AsyncRegister<TEventData>(Func<TEventData, Task> action) where TEventData : class |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Register<TEventData>(IEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable AsyncRegister<TEventData>(IAsyncEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Register<TEventData, THandler>() where TEventData : class where THandler : IEventHandler, new() |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Register(Type eventType, IEventHandler handler) |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Register<TEventData>(IEventHandlerFactory factory) where TEventData : class |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public IDisposable Register(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
return NullDisposable.Instance; |
||||
|
} |
||||
|
|
||||
|
public void Unregister<TEventData>(Action<TEventData> action) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void AsyncUnregister<TEventData>(Func<TEventData, Task> action) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Unregister<TEventData>(IEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void AsyncUnregister<TEventData>(IAsyncEventHandler<TEventData> handler) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Unregister(Type eventType, IEventHandler handler) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Unregister<TEventData>(IEventHandlerFactory factory) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Unregister(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void UnregisterAll<TEventData>() where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void UnregisterAll(Type eventType) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Trigger<TEventData>(TEventData eventData) where TEventData : class |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Trigger(Type eventType, object eventData) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : class |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public Task TriggerAsync(Type eventType, object eventData) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue