using Microsoft.Extensions.DependencyInjection; namespace Toolkit.Foundation; public static class IServiceCollectionExtensions { public static IServiceCollection AddAsyncHandler(this IServiceCollection services, string key) where THandler : class, IAsyncHandler where TMessage : class => AddAsyncHandler(services, ServiceLifetime.Transient, key); public static IServiceCollection AddAsyncHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, string? key = null) where THandler : class, IAsyncHandler where TMessage : class { if (key is { Length: > 0 }) { services.Add(new ServiceDescriptor(typeof(IAsyncHandler), key, typeof(THandler), lifetime)); services.AddInitialization>>(key); } else { services.Add(new ServiceDescriptor(typeof(IAsyncHandler), typeof(THandler), lifetime)); services.AddInitialization>>(); } return services; } public static IServiceCollection AddAsyncHandler(this IServiceCollection services, string key) where THandler : class, IAsyncHandler where TMessage : class => AddAsyncHandler(services, ServiceLifetime.Transient, key); public static IServiceCollection AddAsyncHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, string? key = null) where THandler : class, IAsyncHandler where TMessage : class { if (key is { Length: > 0 }) { services.Add(new ServiceDescriptor(typeof(IAsyncHandler), key, typeof(THandler), lifetime)); services.AddInitialization>>(key); } else { services.Add(new ServiceDescriptor(typeof(IAsyncHandler), typeof(THandler), lifetime)); services.AddInitialization>>(); } return services; } public static IServiceCollection AddAsyncInitialization(this IServiceCollection services) where TInitialization : class, IAsyncInitialization { services.AddTransient(); return services; } public static IServiceCollection AddCache(this IServiceCollection services) where TKey : notnull where TValue : notnull { services.AddScoped, Cache>(); services.AddTransient(provider => provider.GetService>()!.Select(x => x.Value)); return services; } public static IServiceCollection AddCache(this IServiceCollection services) { services.AddSingleton, Cache>(); services.AddTransient(provider => provider.GetService>()!.Select(x => x)); return services; } public static IServiceCollection AddComponent(this IServiceCollection services) where TComponent : class, IComponent { services.AddTransient(); return services; } public static IServiceCollection AddHandler(this IServiceCollection services, string key) where THandler : class, IHandler where TMessage : class => AddHandler(services, ServiceLifetime.Transient, key); public static IServiceCollection AddHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, string? key = null) where THandler : class, IHandler where TMessage : class { if (key is { Length: > 0 }) { services.Add(new ServiceDescriptor(typeof(IHandler), key, typeof(THandler), lifetime)); services.AddInitialization>>(key); } else { services.Add(new ServiceDescriptor(typeof(IHandler), typeof(THandler), lifetime)); services.AddInitialization>>(); } return services; } public static IServiceCollection AddHandler(this IServiceCollection services, string key) where THandler : class, IHandler where TMessage : class => AddHandler(services, ServiceLifetime.Transient, key); public static IServiceCollection AddHandler(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient, string? key = null) where THandler : class, IHandler where TMessage : class { if (key is { Length: > 0 }) { services.Add(new ServiceDescriptor(typeof(IHandler), key, typeof(THandler), lifetime)); services.AddInitialization>>(key); } else { services.Add(new ServiceDescriptor(typeof(IHandler), typeof(THandler), lifetime)); services.AddInitialization>>(); } return services; } public static IServiceCollection AddInitialization(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Transient) where TInitialization : class, IInitialization where TInitializationImplementation : class, TInitialization { services.Add(new ServiceDescriptor(typeof(TInitialization), typeof(TInitializationImplementation), lifetime)); services.AddTransient(provider => provider.GetRequiredService()); return services; } public static IServiceCollection AddInitialization(this IServiceCollection services) where TInitialization : class, IInitialization { services.AddTransient(); return services; } public static IServiceCollection AddInitialization(this IServiceCollection services, params object[] parameters) where TInitialization : class, IInitialization { services.AddTransient(provider => provider.GetRequiredService().Create(parameters)); return services; } public static IServiceCollection AddAsyncPipelineBehavior(this IServiceCollection services) where TBehavior : class, IAsyncPipelineBehavior { services.AddTransient, TBehavior>(); return services; } public static IServiceCollection AddPipelineBehavior(this IServiceCollection services) where TBehavior : class, IPipelineBehavior { services.AddTransient, TBehavior>(); return services; } public static IServiceCollection AddRange(this IServiceCollection services, IServiceCollection fromServices) { foreach (ServiceDescriptor service in fromServices) { services.Add(service); } return services; } public static IServiceCollection AddTemplate(this IServiceCollection services, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, params object[]? parameters) { return AddTemplate(services, key, serviceLifetime, parameters); } public static IServiceCollection AddTemplate(this IServiceCollection services, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, params object?[]? parameters) { Type viewModelType = typeof(TViewModel); Type viewModelImplementationType = typeof(TViewModelImplementation); Type viewType = typeof(TView); key ??= viewModelImplementationType.Name.Replace("ViewModel", ""); if (parameters is { Length: 0 }) { services.Add(new ServiceDescriptor(viewModelType, viewModelImplementationType, serviceLifetime)); } else { services.Add(new ServiceDescriptor(viewModelType, provider => provider.GetRequiredService().Create(parameters)!, serviceLifetime)); } services.Add(new ServiceDescriptor(viewType, viewType, serviceLifetime)); if (parameters is { Length: 0 }) { services.Add(new ServiceDescriptor(viewModelType, key, viewModelImplementationType, serviceLifetime)); } else { services.Add(new ServiceDescriptor(viewModelType, key, (provider, key) => provider.GetRequiredService().Create(parameters)!, serviceLifetime)); } services.Add(new ServiceDescriptor(viewType, key, viewType, serviceLifetime)); services.AddKeyedTransient(key, (provider, _) => new ContentTemplateDescriptor(key, viewModelImplementationType, viewType, parameters)); return services; } public static IServiceCollection AddValueTemplate(this IServiceCollection services, Func readDelegate, Action writeDelegate, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, params object?[]? parameters) { parameters = [readDelegate, writeDelegate, .. parameters ?? Enumerable.Empty()]; return AddTemplate(services, key, serviceLifetime, parameters); } public static IServiceCollection AddValueTemplate(this IServiceCollection services, Func readDelegate, Action writeDelegate, object? key = null, ServiceLifetime serviceLifetime = ServiceLifetime.Transient, params object?[]? parameters) { parameters = [readDelegate, writeDelegate, .. parameters ?? Enumerable.Empty()]; return AddTemplate(services, key, serviceLifetime, parameters); } }