diff --git a/Framework/Foundation/Configurations/ConfigurationWriter.cs b/Framework/Foundation/Configurations/ConfigurationWriter.cs index cde7b85..b953116 100644 --- a/Framework/Foundation/Configurations/ConfigurationWriter.cs +++ b/Framework/Foundation/Configurations/ConfigurationWriter.cs @@ -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 : IConfigurationWriter() .AddHandler() - .AddSingleton(provider => new ServiceFactory(provider.GetService, (instanceType, parameters) => ActivatorUtilities.CreateInstance(provider, instanceType, parameters!))) + .AddSingleton(provider => new ServiceFactory(provider.GetService, (type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))) .AddHandler() .AddSingleton(provider => new Initialization(() => { @@ -37,7 +37,7 @@ public static class IServiceCollectionExtensions return serviceCollection; } - public static IServiceCollection AddHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient) where THandler : notnull + public static IServiceCollection AddHandler(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(), ServiceLifetime.Singleton)); + serviceCollection.TryAdd(new ServiceDescriptor(typeof(THandler), typeof(THandler), ServiceLifetime.Singleton)); + + serviceCollection.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType), sp => sp.GetRequiredService(), 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()?.Create(wrapperType, sp.GetRequiredService(), 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()?.Create(wrapperType, sp.GetRequiredService(), 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()?.Create(wrapperType, sp.GetRequiredService(), sp.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)))!; @@ -110,7 +111,7 @@ public static class IServiceCollectionExtensions )); } } - return services; + return serviceCollection; } public static IServiceCollection AddWritableConfiguration(this IServiceCollection serviceCollection, IConfiguration configuration) where TConfiguration : class, new() diff --git a/Framework/Foundation/Lifecycles/IMediator.cs b/Framework/Foundation/Lifecycles/IMediator.cs index 41947bf..e0b768c 100644 --- a/Framework/Foundation/Lifecycles/IMediator.cs +++ b/Framework/Foundation/Lifecycles/IMediator.cs @@ -11,4 +11,6 @@ public interface IMediator ValueTask Send(IQuery query, CancellationToken cancellationToken = default); ValueTask Send(object message, CancellationToken cancellationToken = default); + + void Subscribe(object subscriber); } diff --git a/Framework/Foundation/Lifecycles/Initialization.cs b/Framework/Foundation/Lifecycles/Initialization.cs index febe1ec..35bca79 100644 --- a/Framework/Foundation/Lifecycles/Initialization.cs +++ b/Framework/Foundation/Lifecycles/Initialization.cs @@ -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"); } } } diff --git a/Framework/Foundation/Lifecycles/Mediator.cs b/Framework/Foundation/Lifecycles/Mediator.cs index 3fe0ebf..d0be017 100644 --- a/Framework/Foundation/Lifecycles/Mediator.cs +++ b/Framework/Foundation/Lifecycles/Mediator.cs @@ -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> subscriptions = new(); public Mediator(IServiceProvider factory) { @@ -15,6 +17,11 @@ public class Mediator : IMediator { List> handlers = factory.GetServices>().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 Send(IRequest 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 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 { subscriber }, (type, hashSet) => + { + hashSet.Add(subscriber); + return hashSet; + }); + } + } + } + } }