Added subscription to Mediator to allow later subscriptions
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
@@ -11,7 +9,6 @@ public class ConfigurationWriter<TConfiguration> : IConfigurationWriter<TConfigu
|
||||
|
||||
public ConfigurationWriter(IConfiguration rootConfiguration, string section)
|
||||
{
|
||||
Trace.WriteLine(section);
|
||||
this.rootConfiguration = rootConfiguration;
|
||||
this.section = section;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public static class IServiceCollectionExtensions
|
||||
serviceCollection
|
||||
.AddSingleton<IMediator, Mediator>()
|
||||
.AddHandler<InitializeHandler>()
|
||||
.AddSingleton<IServiceFactory>(provider => new ServiceFactory(provider.GetService, (instanceType, parameters) => ActivatorUtilities.CreateInstance(provider, instanceType, parameters!)))
|
||||
.AddSingleton<IServiceFactory>(provider => new ServiceFactory(provider.GetService, (type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!)))
|
||||
.AddHandler<ServiceFactoryHandler>()
|
||||
.AddSingleton<IInitialization, Initialization>(provider => new Initialization(() =>
|
||||
{
|
||||
@@ -37,7 +37,7 @@ public static class IServiceCollectionExtensions
|
||||
return serviceCollection;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddHandler<THandler>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient) where THandler : notnull
|
||||
public static IServiceCollection AddHandler<THandler>(this IServiceCollection serviceCollection, ServiceLifetime lifetime = ServiceLifetime.Transient) where THandler : notnull
|
||||
{
|
||||
if (typeof(THandler).GetInterface(typeof(INotificationHandler<>).Name) is { } notificationContract)
|
||||
{
|
||||
@@ -45,8 +45,9 @@ public static class IServiceCollectionExtensions
|
||||
{
|
||||
Type notificationType = arguments[0];
|
||||
|
||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton));
|
||||
services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), sp => sp.GetRequiredService<THandler>(), ServiceLifetime.Singleton));
|
||||
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton));
|
||||
|
||||
serviceCollection.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), sp => sp.GetRequiredService<THandler>(), lifetime));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +60,8 @@ public static class IServiceCollectionExtensions
|
||||
|
||||
Type wrapperType = typeof(RequestClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||
|
||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
services.Add(new ServiceDescriptor(wrapperType,
|
||||
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||
sp =>
|
||||
{
|
||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
||||
@@ -80,8 +81,8 @@ public static class IServiceCollectionExtensions
|
||||
|
||||
Type wrapperType = typeof(CommandClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||
|
||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
services.Add(new ServiceDescriptor(wrapperType,
|
||||
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||
sp =>
|
||||
{
|
||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
||||
@@ -100,8 +101,8 @@ public static class IServiceCollectionExtensions
|
||||
|
||||
Type wrapperType = typeof(QueryClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||
|
||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
services.Add(new ServiceDescriptor(wrapperType,
|
||||
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||
sp =>
|
||||
{
|
||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
||||
@@ -110,7 +111,7 @@ public static class IServiceCollectionExtensions
|
||||
));
|
||||
}
|
||||
}
|
||||
return services;
|
||||
return serviceCollection;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddWritableConfiguration<TConfiguration>(this IServiceCollection serviceCollection, IConfiguration configuration) where TConfiguration : class, new()
|
||||
|
||||
@@ -11,4 +11,6 @@ public interface IMediator
|
||||
ValueTask<TResponse> Send<TResponse>(IQuery<TResponse> query, CancellationToken cancellationToken = default);
|
||||
|
||||
ValueTask<object?> Send(object message, CancellationToken cancellationToken = default);
|
||||
|
||||
void Subscribe(object subscriber);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
public class Initialization : IInitialization
|
||||
{
|
||||
@@ -17,9 +15,7 @@ public class Initialization : IInitialization
|
||||
{
|
||||
if (initializer is not null)
|
||||
{
|
||||
Trace.WriteLine(initializer.GetType());
|
||||
await initializer.InitializeAsync();
|
||||
Trace.WriteLine("Done");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Toolkit.Framework.Foundation;
|
||||
|
||||
public class Mediator : IMediator
|
||||
{
|
||||
private readonly IServiceProvider factory;
|
||||
private readonly ConcurrentDictionary<Type, HashSet<dynamic>> subscriptions = new();
|
||||
|
||||
public Mediator(IServiceProvider factory)
|
||||
{
|
||||
@@ -15,6 +17,11 @@ public class Mediator : IMediator
|
||||
{
|
||||
List<INotificationHandler<TNotification>> handlers = factory.GetServices<INotificationHandler<TNotification>>().ToList();
|
||||
|
||||
foreach (dynamic handler in subscriptions[typeof(TNotification)])
|
||||
{
|
||||
handlers.Add(handler);
|
||||
}
|
||||
|
||||
if (handlers.Count == 0)
|
||||
{
|
||||
return default;
|
||||
@@ -29,7 +36,7 @@ public class Mediator : IMediator
|
||||
|
||||
public ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
dynamic? handler = factory.GetService(typeof(RequestClassHandlerWrapper<,>).MakeGenericType(request.GetType(), typeof(TResponse)));
|
||||
dynamic? handler = factory.GetService(typeof(RequestClassHandlerWrapper<,>).MakeGenericType(request.GetType(), typeof(TResponse)));
|
||||
if (handler is not null)
|
||||
{
|
||||
return handler.Handle((dynamic)request, cancellationToken);
|
||||
@@ -62,9 +69,9 @@ public class Mediator : IMediator
|
||||
|
||||
public ValueTask<object?> Send(object message, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (message.GetType().GetInterface(typeof(IRequest<>).Name) is { } requestInterface)
|
||||
if (message.GetType().GetInterface(typeof(IRequest<>).Name) is { } requestType)
|
||||
{
|
||||
if (requestInterface.GetGenericArguments() is { Length: 1 } arguments)
|
||||
if (requestType.GetGenericArguments() is { Length: 1 } arguments)
|
||||
{
|
||||
Type responseType = arguments[0];
|
||||
|
||||
@@ -76,9 +83,9 @@ public class Mediator : IMediator
|
||||
}
|
||||
}
|
||||
|
||||
if (message.GetType().GetInterface(typeof(ICommand<>).Name) is { } commandInterface)
|
||||
if (message.GetType().GetInterface(typeof(ICommand<>).Name) is { } commandType)
|
||||
{
|
||||
if (commandInterface.GetGenericArguments() is { Length: 1 } arguments)
|
||||
if (commandType.GetGenericArguments() is { Length: 1 } arguments)
|
||||
{
|
||||
Type responseType = arguments[0];
|
||||
|
||||
@@ -90,9 +97,9 @@ public class Mediator : IMediator
|
||||
}
|
||||
}
|
||||
|
||||
if (message.GetType().GetInterface(typeof(IQuery<>).Name) is { } queryInterface)
|
||||
if (message.GetType().GetInterface(typeof(IQuery<>).Name) is { } queryType)
|
||||
{
|
||||
if (queryInterface.GetGenericArguments() is { Length: 1 } arguments)
|
||||
if (queryType.GetGenericArguments() is { Length: 1 } arguments)
|
||||
{
|
||||
Type responseType = arguments[0];
|
||||
|
||||
@@ -106,4 +113,25 @@ public class Mediator : IMediator
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public void Subscribe(object subscriber)
|
||||
{
|
||||
Type[] interfaceTypes = subscriber.GetType().GetInterfaces();
|
||||
foreach (Type interfaceType in interfaceTypes.Where(x => x.IsGenericType))
|
||||
{
|
||||
if (interfaceType.GetGenericTypeDefinition() == typeof(INotificationHandler<>))
|
||||
{
|
||||
if (interfaceType.GetGenericArguments() is { Length: 1 } arguments)
|
||||
{
|
||||
Type notificationType = arguments[0];
|
||||
|
||||
subscriptions.AddOrUpdate(notificationType, new HashSet<dynamic> { subscriber }, (type, hashSet) =>
|
||||
{
|
||||
hashSet.Add(subscriber);
|
||||
return hashSet;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user