Skip to content

Commit

Permalink
Allow handlers to be transient or scoped instead of just singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
aritchie committed Jun 1, 2024
1 parent 954f733 commit 6d8a8d9
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/Shiny.Mediator/Impl/Mediator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ namespace Shiny.Mediator.Impl;
// TODO: validate all handlers (event or request) are scoped or singleton (how?)
public class Mediator(
IServiceProvider services,
IEventCollector? collector = null
IEnumerable<IEventCollector> collectors
) : IMediator
{
readonly SubscriptionEventCollector subscriptions = new();

public async Task Send<TRequest>(TRequest request, CancellationToken cancellationToken = default) where TRequest : IRequest
{
var handlers = services.GetServices<IRequestHandler<TRequest>>().ToList();
using var scope = services.CreateScope();
var handlers = scope.ServiceProvider.GetServices<IRequestHandler<TRequest>>().ToList();
AssertRequestHandlers(handlers.Count, request);

// TODO: pipelines
Expand All @@ -29,9 +30,11 @@ await handlers
public async Task<TResult> Send<TResult>(IRequest<TResult> request, CancellationToken cancellationToken = default)
{
var handlerType = typeof(IRequestHandler<,>).MakeGenericType(request.GetType(), typeof(TResult));
var handlers = services.GetServices(handlerType).ToList();
AssertRequestHandlers(handlers.Count, request);

using var scope = services.CreateScope();
var handlers = scope.ServiceProvider.GetServices(handlerType).ToList();
AssertRequestHandlers(handlers.Count, request);

var handler = handlers.First();
var handleMethod = handlerType.GetMethod("Handle", BindingFlags.Instance | BindingFlags.Public)!;
var resultTask = (Task<TResult>)handleMethod.Invoke(handler, [request, cancellationToken])!;
Expand All @@ -49,15 +52,16 @@ public async Task Publish<TEvent>(
CancellationToken cancellationToken = default
) where TEvent : IEvent
{
// TODO: filter out the dupes from the collector by instance (viewmodels may be in DI and MAUI collector)
var handlers = services.GetServices<IEventHandler<TEvent>>().ToList();
// allow registered services to be transient/scoped/singleton
using var scope = services.CreateScope();
var handlers = scope.ServiceProvider.GetServices<IEventHandler<TEvent>>().ToList();
AppendHandlersIf(handlers, this.subscriptions);
if (collector != null)
foreach (var collector in collectors)
AppendHandlersIf(handlers, collector);

if (handlers.Count == 0)
return;

Task executor = null!;
if (executeInParallel)
{
Expand All @@ -80,7 +84,7 @@ await handler
}
});
}

// TODO: pipelines
if (fireAndForget)
{
Expand Down

0 comments on commit 6d8a8d9

Please sign in to comment.