using Microsoft.Extensions.DependencyInjection; using NadekoBot.Modules.Music; using NadekoBot.Modules.Music.Resolvers; using NadekoBot.Modules.Music.Services; using Ninject; using Ninject.Extensions.Conventions; using Ninject.Extensions.Conventions.Syntax; using StackExchange.Redis; using System.Net; using System.Reflection; using NadekoBot.Common.ModuleBehaviors; using Ninject.Infrastructure.Language; namespace NadekoBot.Extensions; public static class ServiceCollectionExtensions { public static IKernel AddBotStringsServices(this IKernel kernel, BotCacheImplemenation botCache) { if (botCache == BotCacheImplemenation.Memory) { kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); } else { kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); } return kernel; } public static IKernel AddConfigServices(this IKernel kernel, Assembly a) { kernel.Bind(x => { var configs = x.From(a) .SelectAllClasses() .Where(f => f.IsAssignableToGenericType(typeof(ConfigServiceBase<>))); configs.BindToSelfWithInterfaces() .Configure(c => c.InSingletonScope()); }); return kernel; } public static IKernel AddConfigMigrators(this IKernel kernel, Assembly a) => kernel.AddSealedSubclassesOf(typeof(IConfigMigrator), a); public static IKernel AddMusic(this IKernel kernel) { kernel.Bind() .To() .InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); // kernel.Bind().ToSelf().InSingletonScope(); return kernel; } public static IKernel AddSealedSubclassesOf(this IKernel kernel, Type baseType, Assembly a) { kernel.Bind(x => { var classes = x.From(a) .SelectAllClasses() .Where(c => c.IsPublic && c.IsNested && baseType.IsAssignableFrom(baseType)); classes.BindToSelfWithInterfaces().Configure(x => x.InSingletonScope()); }); return kernel; } public static IKernel AddCache(this IKernel kernel, IBotCredentials creds) { if (creds.BotCache == BotCacheImplemenation.Redis) { var conf = ConfigurationOptions.Parse(creds.RedisOptions); kernel.Bind().ToConstant(ConnectionMultiplexer.Connect(conf)).InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); } else { kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); } return kernel .AddBotStringsServices(creds.BotCache); } public static IKernel AddHttpClients(this IKernel kernel) { IServiceCollection svcs = new ServiceCollection(); svcs.AddHttpClient(); svcs.AddHttpClient("memelist") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AllowAutoRedirect = false }); svcs.AddHttpClient("google:search") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); var prov = svcs.BuildServiceProvider(); kernel.Bind().ToMethod(_ => prov.GetRequiredService()); kernel.Bind().ToMethod(_ => prov.GetRequiredService()); return kernel; } public static IConfigureSyntax BindToSelfWithInterfaces(this IJoinExcludeIncludeBindSyntax matcher) => matcher.BindSelection((type, types) => types.Append(type)); public static IKernel AddLifetimeServices(this IKernel kernel, Assembly a) { kernel.Bind(scan => { scan.From(a) .SelectAllClasses() .Where(c => (c.IsAssignableTo(typeof(INService)) || c.IsAssignableTo(typeof(IExecOnMessage)) || c.IsAssignableTo(typeof(IInputTransformer)) || c.IsAssignableTo(typeof(IExecPreCommand)) || c.IsAssignableTo(typeof(IExecPostCommand)) || c.IsAssignableTo(typeof(IExecNoCommand))) && !c.HasAttribute() #if GLOBAL_NADEK && !c.HasAttribute() #endif ) .BindToSelfWithInterfaces() .Configure(c => c.InSingletonScope()); }); return kernel; } }