Added subscription to Mediator to allow later subscriptions
This commit is contained in:
@@ -1,6 +1,4 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Toolkit.Framework.Foundation;
|
namespace Toolkit.Framework.Foundation;
|
||||||
|
|
||||||
@@ -11,7 +9,6 @@ public class ConfigurationWriter<TConfiguration> : IConfigurationWriter<TConfigu
|
|||||||
|
|
||||||
public ConfigurationWriter(IConfiguration rootConfiguration, string section)
|
public ConfigurationWriter(IConfiguration rootConfiguration, string section)
|
||||||
{
|
{
|
||||||
Trace.WriteLine(section);
|
|
||||||
this.rootConfiguration = rootConfiguration;
|
this.rootConfiguration = rootConfiguration;
|
||||||
this.section = section;
|
this.section = section;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public static class IServiceCollectionExtensions
|
|||||||
serviceCollection
|
serviceCollection
|
||||||
.AddSingleton<IMediator, Mediator>()
|
.AddSingleton<IMediator, Mediator>()
|
||||||
.AddHandler<InitializeHandler>()
|
.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>()
|
.AddHandler<ServiceFactoryHandler>()
|
||||||
.AddSingleton<IInitialization, Initialization>(provider => new Initialization(() =>
|
.AddSingleton<IInitialization, Initialization>(provider => new Initialization(() =>
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,7 @@ public static class IServiceCollectionExtensions
|
|||||||
return serviceCollection;
|
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)
|
if (typeof(THandler).GetInterface(typeof(INotificationHandler<>).Name) is { } notificationContract)
|
||||||
{
|
{
|
||||||
@@ -45,8 +45,9 @@ public static class IServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
Type notificationType = arguments[0];
|
Type notificationType = arguments[0];
|
||||||
|
|
||||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton));
|
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton));
|
||||||
services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), sp => sp.GetRequiredService<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);
|
Type wrapperType = typeof(RequestClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||||
|
|
||||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||||
services.Add(new ServiceDescriptor(wrapperType,
|
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||||
sp =>
|
sp =>
|
||||||
{
|
{
|
||||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
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);
|
Type wrapperType = typeof(CommandClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||||
|
|
||||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||||
services.Add(new ServiceDescriptor(wrapperType,
|
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||||
sp =>
|
sp =>
|
||||||
{
|
{
|
||||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
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);
|
Type wrapperType = typeof(QueryClassHandlerWrapper<,>).MakeGenericType(requestType, responseType);
|
||||||
|
|
||||||
services.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), lifetime));
|
||||||
services.Add(new ServiceDescriptor(wrapperType,
|
serviceCollection.Add(new ServiceDescriptor(wrapperType,
|
||||||
sp =>
|
sp =>
|
||||||
{
|
{
|
||||||
return sp.GetService<IServiceFactory>()?.Create(wrapperType, sp.GetRequiredService<THandler>(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!;
|
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()
|
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<TResponse> Send<TResponse>(IQuery<TResponse> query, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
ValueTask<object?> Send(object message, 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
|
public class Initialization : IInitialization
|
||||||
{
|
{
|
||||||
@@ -17,9 +15,7 @@ public class Initialization : IInitialization
|
|||||||
{
|
{
|
||||||
if (initializer is not null)
|
if (initializer is not null)
|
||||||
{
|
{
|
||||||
Trace.WriteLine(initializer.GetType());
|
|
||||||
await initializer.InitializeAsync();
|
await initializer.InitializeAsync();
|
||||||
Trace.WriteLine("Done");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace Toolkit.Framework.Foundation;
|
namespace Toolkit.Framework.Foundation;
|
||||||
|
|
||||||
public class Mediator : IMediator
|
public class Mediator : IMediator
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider factory;
|
private readonly IServiceProvider factory;
|
||||||
|
private readonly ConcurrentDictionary<Type, HashSet<dynamic>> subscriptions = new();
|
||||||
|
|
||||||
public Mediator(IServiceProvider factory)
|
public Mediator(IServiceProvider factory)
|
||||||
{
|
{
|
||||||
@@ -15,6 +17,11 @@ public class Mediator : IMediator
|
|||||||
{
|
{
|
||||||
List<INotificationHandler<TNotification>> handlers = factory.GetServices<INotificationHandler<TNotification>>().ToList();
|
List<INotificationHandler<TNotification>> handlers = factory.GetServices<INotificationHandler<TNotification>>().ToList();
|
||||||
|
|
||||||
|
foreach (dynamic handler in subscriptions[typeof(TNotification)])
|
||||||
|
{
|
||||||
|
handlers.Add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
if (handlers.Count == 0)
|
if (handlers.Count == 0)
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
@@ -62,9 +69,9 @@ public class Mediator : IMediator
|
|||||||
|
|
||||||
public ValueTask<object?> Send(object message, CancellationToken cancellationToken = default)
|
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];
|
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];
|
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];
|
Type responseType = arguments[0];
|
||||||
|
|
||||||
@@ -106,4 +113,25 @@ public class Mediator : IMediator
|
|||||||
|
|
||||||
return default;
|
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