// // ServiceCollectionExtensions.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using NosSmooth.Core.Commands; using NosSmooth.Core.Packets; using NosSmooth.Packets.Extensions; namespace NosSmooth.Core.Extensions; /// /// Contains extension methods for . /// public static class ServiceCollectionExtensions { /// /// Adds base packet and command handling for nostale client. /// /// The service collection to register the responder to. /// Custom types of packets to serialize and deserialize. /// The collection. public static IServiceCollection AddNostaleCore ( this IServiceCollection serviceCollection, params Type[] additionalPacketTypes ) { serviceCollection .TryAddSingleton(); serviceCollection.AddPacketSerialization(); serviceCollection.AddSingleton(); return serviceCollection; } /// /// Adds the specified packet responder that will be called upon receiving the given event. /// /// The service collection to register the responder to. /// The type of the responder. /// Thrown if the type of the responder is incorrect. /// The collection. public static IServiceCollection AddPacketResponder ( this IServiceCollection serviceCollection ) where TPacketResponder : class, IPacketResponder { return serviceCollection.AddPacketResponder(typeof(TPacketResponder)); } /// /// Adds the specified packet responder that will be called upon receiving the given event. /// /// The service collection to register the responder to. /// The type of the responder. /// The collection. /// Thrown if the type of the responder is incorrect. public static IServiceCollection AddPacketResponder ( this IServiceCollection serviceCollection, Type responderType ) { if (responderType.GetInterfaces().Any(i => i == typeof(IEveryPacketResponder))) { return serviceCollection.AddScoped(typeof(IEveryPacketResponder), responderType); } if (!responderType.GetInterfaces().Any( i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketResponder<>) )) { throw new ArgumentException( $"{nameof(responderType)} should implement IPacketResponder.", nameof(responderType)); } var responderTypeInterfaces = responderType.GetInterfaces(); var responderInterfaces = responderTypeInterfaces.Where ( r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(IPacketResponder<>) ); foreach (var responderInterface in responderInterfaces) { serviceCollection.AddScoped(responderInterface, responderType); } return serviceCollection; } /// /// Adds the specified command handler. /// /// The service collection to register the responder to. /// The type of the command. /// Thrown if the type of the responder is incorrect. /// The collection. public static IServiceCollection AddCommandHandler ( this IServiceCollection serviceCollection ) where TCommandHandler : class, ICommandHandler { return serviceCollection.AddCommandHandler(typeof(TCommandHandler)); } /// /// Adds the specified command handler. /// /// The service collection to register the responder to. /// The type of the command handler. /// The collection. /// Thrown if the type of the responder is incorrect. public static IServiceCollection AddCommandHandler ( this IServiceCollection serviceCollection, Type commandHandlerType ) { if (!commandHandlerType.GetInterfaces().Any( i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICommandHandler<>) )) { throw new ArgumentException( $"{nameof(commandHandlerType)} should implement ICommandHandler.", nameof(commandHandlerType)); } var handlerTypeInterfaces = commandHandlerType.GetInterfaces(); var handlerInterfaces = handlerTypeInterfaces.Where ( r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(ICommandHandler<>) ); foreach (var handlerInterface in handlerInterfaces) { serviceCollection.AddScoped(handlerInterface, commandHandlerType); } return serviceCollection; } }