Skip to content

Commit

Permalink
Event context ground work
Browse files Browse the repository at this point in the history
  • Loading branch information
aritchie committed Oct 2, 2024
1 parent 8ba6808 commit e025325
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 59 deletions.
24 changes: 10 additions & 14 deletions src/Shiny.Mediator.Maui/Middleware/MainTheadEventMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
using Shiny.Mediator.Infrastructure;

namespace Shiny.Mediator.Middleware;


public class MainTheadEventMiddleware<TEvent> : IEventMiddleware<TEvent> where TEvent : IEvent
{
public async Task Process(
IEvent @event,
EventHandlerDelegate next,
IEventHandler<TEvent> eventHandler,
CancellationToken cancellationToken
EventExecutionContext<TEvent> context,
EventHandlerDelegate next
)
{
var attr = eventHandler.GetHandlerHandleMethodAttribute<TEvent, MainThreadAttribute>();

if (attr != null)
var attr = context.EventHandler.GetHandlerHandleMethodAttribute<TEvent, MainThreadAttribute>();

if (attr == null)
{
await next().ConfigureAwait(false);
}
else
{
var tcs = new TaskCompletionSource();
MainThread.BeginInvokeOnMainThread(async () =>
{
try
{
await next();
await next().ConfigureAwait(false);
tcs.SetResult();
}
catch (Exception ex)
Expand All @@ -31,9 +31,5 @@ CancellationToken cancellationToken
});
await tcs.Task.ConfigureAwait(false);
}
else
{
await next().ConfigureAwait(false);
}
}
}
18 changes: 18 additions & 0 deletions src/Shiny.Mediator/EventExecutionContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Shiny.Mediator;


public class EventExecutionContext<TEvent>(
TEvent @event,
IEventHandler<TEvent> eventHandler,
CancellationToken cancellationToken
) where TEvent : IEvent
{
public TEvent Event => @event;
public IEventHandler<TEvent> EventHandler => eventHandler;
public CancellationToken CancellationToken => cancellationToken;
}
public class EventAggregatedExecutionContext<TEvent>(IReadOnlyList<EventExecutionContext<TEvent>> contexts)
where TEvent : IEvent
{

}
6 changes: 2 additions & 4 deletions src/Shiny.Mediator/IEventMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ namespace Shiny.Mediator;
public interface IEventMiddleware<TEvent> where TEvent : IEvent
{
Task Process(
IEvent @event,
EventHandlerDelegate next,
IEventHandler<TEvent> eventHandler,
CancellationToken cancellationToken
EventExecutionContext<TEvent> context,
EventHandlerDelegate next
);
}
4 changes: 1 addition & 3 deletions src/Shiny.Mediator/Infrastructure/IEventPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ public interface IEventPublisher
/// <param name="cancellationToken"></param>
/// <typeparam name="TEvent"></typeparam>
/// <returns></returns>
Task Publish<TEvent>(
Task<EventAggregatedExecutionContext<TEvent>> Publish<TEvent>(
TEvent @event,
CancellationToken cancellationToken = default
) where TEvent : IEvent;

// Task Publish(object arg, CancellationToken cancellationToken = default)

/// <summary>
///
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Shiny.Mediator.Infrastructure;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


public class DefaultEventPublisher(
Expand All @@ -13,7 +12,7 @@ IEnumerable<IEventCollector> collectors
readonly SubscriptionEventCollector subscriptions = new();


public async Task Publish<TEvent>(
public async Task<EventAggregatedExecutionContext<TEvent>> Publish<TEvent>(
TEvent @event,
CancellationToken cancellationToken = default
) where TEvent : IEvent
Expand All @@ -31,18 +30,27 @@ public async Task Publish<TEvent>(
foreach (var collector in collectors)
AppendHandlersIf(handlers, collector);

var list = new List<EventExecutionContext<TEvent>>();
var context = new EventAggregatedExecutionContext<TEvent>(list);

if (handlers.Count == 0)
return;
return context;

var logger = services.GetRequiredService<ILogger<TEvent>>();
var middlewares = scope.ServiceProvider.GetServices<IEventMiddleware<TEvent>>().ToList();
var tasks = handlers
.Select(x => Execute(@event, x, logger, middlewares, cancellationToken))
.Select(async x =>
{
var econtext = await Execute(@event, x, logger, middlewares, cancellationToken).ConfigureAwait(false);
list.Add(econtext);
})
.ToList();

await Task
.WhenAll(tasks)
.ConfigureAwait(false);

return context;
}


Expand All @@ -54,21 +62,23 @@ public IDisposable Subscribe<TEvent>(Func<TEvent, CancellationToken, Task> actio
}


static async Task Execute<TEvent>(
static async Task<EventExecutionContext<TEvent>> Execute<TEvent>(
TEvent @event,
IEventHandler<TEvent> eventHandler,
ILogger logger,
IEnumerable<IEventMiddleware<TEvent>> middlewares,
CancellationToken cancellationToken
) where TEvent : IEvent
{
var context = new EventExecutionContext<TEvent>(@event, eventHandler, cancellationToken);

var handlerDelegate = new EventHandlerDelegate(() =>
{
logger.LogDebug(
"Executing Event Handler {HandlerType}",
eventHandler.GetType().FullName
);
return eventHandler.Handle(@event, cancellationToken);
return eventHandler.Handle(context.Event, context.CancellationToken);
});

await middlewares
Expand All @@ -78,22 +88,20 @@ await middlewares
(next, middleware) => () =>
{
logger.LogDebug(
"Executing event middleware {MiddlewareType} for {RequestType}",
middleware.GetType().FullName,
@event.GetType().FullName
"Executing event middleware {MiddlewareType}",
middleware.GetType().FullName
);

return middleware.Process(
@event,
next,
eventHandler,
cancellationToken
);
})
return middleware.Process(context, next);
}
)
.Invoke()
.ConfigureAwait(false);

return context;
}


static void AppendHandlersIf<TEvent>(List<IEventHandler<TEvent>> list, IEventCollector collector) where TEvent : IEvent
{
var handlers = collector.GetHandlers<TEvent>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Shiny.Mediator.Infrastructure;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


public class DefaultRequestSender(IServiceProvider services) : IRequestSender
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Shiny.Mediator.Infrastructure;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


public class Mediator(
Expand Down Expand Up @@ -49,7 +47,7 @@ public IAsyncEnumerable<TResult> Request<TResult>(IStreamRequest<TResult> reques
public ExecutionResult<IAsyncEnumerable<TResult>> RequestWithContext<TResult>(IStreamRequest<TResult> request, CancellationToken cancellationToken = default)
=> requestSender.RequestWithContext(request, cancellationToken);

public Task Publish<TEvent>(TEvent @event, CancellationToken cancellationToken = default) where TEvent : IEvent
public Task<EventAggregatedExecutionContext<TEvent>> Publish<TEvent>(TEvent @event, CancellationToken cancellationToken = default) where TEvent : IEvent
=> eventPublisher.Publish(@event, cancellationToken);

public IDisposable Subscribe<TEvent>(Func<TEvent, CancellationToken, Task> action) where TEvent : IEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


static class RequestExecutor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


class RequestVoidWrapper<TRequest> where TRequest : IRequest
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


class RequestWrapper<TRequest, TResult> where TRequest : IRequest<TResult>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure.Impl;


class StreamRequestWrapper<TRequest, TResult> where TRequest : IStreamRequest<TResult>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Shiny.Mediator.Infrastructure;

namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure;


public class SubscriptionEventCollector : IEventCollector
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Shiny.Mediator.Impl;
namespace Shiny.Mediator.Infrastructure;


public class SubscriptionEventHandler<TEvent> : IDisposable, IEventHandler<TEvent> where TEvent : IEvent
Expand Down
4 changes: 2 additions & 2 deletions src/Shiny.Mediator/MediatorExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Shiny.Mediator.Impl;
using Shiny.Mediator.Infrastructure;
using Shiny.Mediator.Infrastructure.Impl;
using Shiny.Mediator.Middleware;

namespace Shiny.Mediator;
Expand Down Expand Up @@ -52,7 +52,7 @@ public static IServiceCollection AddShinyMediator(this IServiceCollection servic
cfg.AddPerformanceLoggingMiddleware();
}

services.TryAddSingleton<IMediator, Impl.Mediator>();
services.TryAddSingleton<IMediator, Infrastructure.Impl.Mediator>();
services.TryAddSingleton<IRequestSender, DefaultRequestSender>();
services.TryAddSingleton<IEventPublisher, DefaultEventPublisher>();
return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ namespace Shiny.Mediator.Middleware;
public class ExceptionHandlerEventMiddleware<TEvent>(ILogger<TEvent> logger) : IEventMiddleware<TEvent> where TEvent : IEvent
{
public async Task Process(
IEvent @event,
EventHandlerDelegate next,
IEventHandler<TEvent> eventHandler,
CancellationToken cancellationToken
EventExecutionContext<TEvent> context,
EventHandlerDelegate next
)
{
try
Expand All @@ -18,7 +16,7 @@ CancellationToken cancellationToken
}
catch (Exception ex)
{
logger.LogError(ex, "Error in event {EventType}", @event.GetType().FullName);
logger.LogError(ex, "Error in event {EventType}", context.Event.GetType().FullName);
}
}
}
2 changes: 0 additions & 2 deletions tests/Shiny.Mediator.Tests/OfflineAvailableMiddlewareTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using Shiny.Mediator.Impl;
using Shiny.Mediator.Infrastructure;
using Shiny.Mediator.Middleware;

Expand Down

0 comments on commit e025325

Please sign in to comment.