From 6a7ab794469e292e58944b09168e189e9a115152 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 4 May 2024 08:08:13 +0000 Subject: [PATCH] Re-added medusa system, but untested --- .../Extensions/MedusaExtensions.cs | 126 +++++++++--------- src/NadekoBot/Bot.cs | 12 -- .../Medusa/Common/MedusaIoCKernelModule.cs | 78 ++++------- .../Medusa/Common/MedusaLoaderService.cs | 52 ++++---- .../Medusa/Common/Models/ResolvedMedusa.cs | 6 +- .../_common/Medusa/Common/RemovablePlanner.cs | 122 ----------------- .../_common/ServiceCollectionExtensions.cs | 122 ++++++----------- .../_common/Settings/IConfigMigrator.cs | 7 - 8 files changed, 152 insertions(+), 373 deletions(-) delete mode 100644 src/NadekoBot/_common/Medusa/Common/RemovablePlanner.cs delete mode 100644 src/NadekoBot/_common/Settings/IConfigMigrator.cs diff --git a/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs b/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs index ef26ae184..0c841eb39 100644 --- a/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs +++ b/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs @@ -1,65 +1,61 @@ -// using Discord; -// -// namespace NadekoBot.Medusa; -// -// public static class MedusaExtensions -// { -// public static Task EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "") -// => ch.SendMessageAsync(msg, -// embed: embed.Build(), -// options: new() -// { -// RetryMode = RetryMode.Retry502 -// }); -// -// // unlocalized -// public static Task SendConfirmAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => _sender.Response(ch).Embed(ctx.Embed().WithOkColor().WithDescription(msg)).SendAsync(); -// -// public static Task SendPendingAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => _sender.Response(ch).Embed(ctx.Embed().WithPendingColor().WithDescription(msg)).SendAsync(); -// -// public static Task SendErrorAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => _sender.Response(ch).Embed(ctx.Embed().WithErrorColor().WithDescription(msg)).SendAsync(); -// -// // unlocalized -// public static Task SendConfirmAsync(this AnyContext ctx, string msg) -// => ctx.Channel.SendConfirmAsync(ctx, msg); -// -// public static Task SendPendingAsync(this AnyContext ctx, string msg) -// => ctx.Channel.SendPendingAsync(ctx, msg); -// -// public static Task SendErrorAsync(this AnyContext ctx, string msg) -// => ctx.Channel.SendErrorAsync(ctx, msg); -// -// // localized -// public static Task ConfirmAsync(this AnyContext ctx) -// => ctx.Message.AddReactionAsync(new Emoji("✅")); -// -// public static Task ErrorAsync(this AnyContext ctx) -// => ctx.Message.AddReactionAsync(new Emoji("❌")); -// -// public static Task WarningAsync(this AnyContext ctx) -// => ctx.Message.AddReactionAsync(new Emoji("⚠️")); -// -// public static Task WaitAsync(this AnyContext ctx) -// => ctx.Message.AddReactionAsync(new Emoji("🤔")); -// -// public static Task ErrorLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendErrorAsync(ctx.GetText(key, args)); -// -// public static Task PendingLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendPendingAsync(ctx.GetText(key, args)); -// -// public static Task ConfirmLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendConfirmAsync(ctx.GetText(key, args)); -// -// public static Task ReplyErrorLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); -// -// public static Task ReplyPendingLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); -// -// public static Task ReplyConfirmLocalizedAsync(this AnyContext ctx, string key, params object[]? args) -// => ctx.SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); -// } \ No newline at end of file +using Discord; + +namespace NadekoBot.Medusa; + +public static class MedusaExtensions +{ + public static Task EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "") + => ch.SendMessageAsync(msg, + embed: embed.Build(), + options: new() + { + RetryMode = RetryMode.Retry502 + }); + + // unlocalized + public static Task SendConfirmAsync(this AnyContext ctx, string msg) + => ctx.Channel.EmbedAsync(new EmbedBuilder() + .WithColor(0, 200, 0) + .WithDescription(msg)); + + public static Task SendPendingAsync(this AnyContext ctx, string msg) + => ctx.Channel.EmbedAsync(new EmbedBuilder() + .WithColor(200, 200, 0) + .WithDescription(msg)); + + public static Task SendErrorAsync(this AnyContext ctx, string msg) + => ctx.Channel.EmbedAsync(new EmbedBuilder() + .WithColor(200, 0, 0) + .WithDescription(msg)); + + // localized + public static Task ConfirmAsync(this AnyContext ctx) + => ctx.Message.AddReactionAsync(new Emoji("✅")); + + public static Task ErrorAsync(this AnyContext ctx) + => ctx.Message.AddReactionAsync(new Emoji("❌")); + + public static Task WarningAsync(this AnyContext ctx) + => ctx.Message.AddReactionAsync(new Emoji("⚠️")); + + public static Task WaitAsync(this AnyContext ctx) + => ctx.Message.AddReactionAsync(new Emoji("🤔")); + + public static Task ErrorLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendErrorAsync(ctx.GetText(key, args)); + + public static Task PendingLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendPendingAsync(ctx.GetText(key, args)); + + public static Task ConfirmLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendConfirmAsync(ctx.GetText(key, args)); + + public static Task ReplyErrorLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); + + public static Task ReplyPendingLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); + + public static Task ReplyConfirmLocalizedAsync(this AnyContext ctx, string key, params object[]? args) + => ctx.SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {ctx.GetText(key, args)}"); +} \ No newline at end of file diff --git a/src/NadekoBot/Bot.cs b/src/NadekoBot/Bot.cs index 332e07992..67e72fd20 100644 --- a/src/NadekoBot/Bot.cs +++ b/src/NadekoBot/Bot.cs @@ -132,7 +132,6 @@ public sealed class Bot : IBot foreach (var a in _loadedAssemblies) { svcs.AddConfigServices(a) - .AddConfigMigrators(a) .AddLifetimeServices(a); } @@ -157,9 +156,6 @@ public sealed class Bot : IBot Services = svcs; Services.GetRequiredService().Initialize(); - if (Client.ShardId == 0) - ApplyConfigMigrations(); - foreach (var a in _loadedAssemblies) { LoadTypeReaders(a); @@ -169,14 +165,6 @@ public sealed class Bot : IBot Log.Information("All services loaded in {ServiceLoadTime:F2}s", sw.Elapsed.TotalSeconds); } - private void ApplyConfigMigrations() - { - // execute all migrators - var migrators = Services.GetServices(); - foreach (var migrator in migrators) - migrator.EnsureMigrated(); - } - private void LoadTypeReaders(Assembly assembly) { var filteredTypes = assembly.GetExportedTypes() diff --git a/src/NadekoBot/_common/Medusa/Common/MedusaIoCKernelModule.cs b/src/NadekoBot/_common/Medusa/Common/MedusaIoCKernelModule.cs index 40dbab400..3a1d7827d 100644 --- a/src/NadekoBot/_common/Medusa/Common/MedusaIoCKernelModule.cs +++ b/src/NadekoBot/_common/Medusa/Common/MedusaIoCKernelModule.cs @@ -1,22 +1,27 @@ -using System.Reflection; -using Ninject; -using Ninject.Activation; -using Ninject.Activation.Caching; -using Ninject.Modules; -using Ninject.Planning; +using DryIoc; +using System.Reflection; using System.Text.Json; namespace NadekoBot.Medusa; -public sealed class MedusaNinjectModule : NinjectModule +public interface IIocModule { - public override string Name { get; } + public string Name { get; } + public void Load(); + public void Unload(); +} + +public sealed class MedusaNinjectIocModule : IIocModule, IDisposable +{ + public string Name { get; } private volatile bool isLoaded = false; private readonly Dictionary _types; + private readonly IContainer _cont; - public MedusaNinjectModule(Assembly assembly, string name) + public MedusaNinjectIocModule(IContainer cont, Assembly assembly, string name) { Name = name; + _cont = cont; _types = assembly.GetExportedTypes() .Where(t => t.IsClass) .Where(t => t.GetCustomAttribute() is not null) @@ -24,7 +29,7 @@ public sealed class MedusaNinjectModule : NinjectModule type => type.GetInterfaces().ToArray()); } - public override void Load() + public void Load() { if (isLoaded) return; @@ -32,59 +37,27 @@ public sealed class MedusaNinjectModule : NinjectModule foreach (var (type, data) in _types) { var attribute = type.GetCustomAttribute()!; - var scope = GetScope(attribute.Lifetime); - Bind(type) - .ToSelf() - .InScope(scope); + var reuse = attribute.Lifetime == Lifetime.Singleton + ? Reuse.Singleton + : Reuse.Transient; - foreach (var inter in data) - { - Bind(inter) - .ToMethod(x => x.Kernel.Get(type)) - .InScope(scope); - } + _cont.RegisterMany([type], reuse); } isLoaded = true; } - private Func GetScope(Lifetime lt) - => _ => lt switch - { - Lifetime.Singleton => this, - Lifetime.Transient => null, - _ => null, - }; - - public override void Unload() + public void Unload() { if (!isLoaded) return; - - var planner = (RemovablePlanner)Kernel!.Components.Get(); - var cache = Kernel.Components.Get(); - foreach (var binding in this.Bindings) + + foreach (var type in _types.Keys) { - Kernel.RemoveBinding(binding); + _cont.Unregister(type); } - - foreach (var type in _types.SelectMany(x => x.Value).Concat(_types.Keys)) - { - var binds = Kernel.GetBindings(type); - - if (!binds.Any()) - { - Unbind(type); - - planner.RemovePlan(type); - } - } - - - Bindings.Clear(); - - cache.Clear(this); + _types.Clear(); // in case the library uses System.Text.Json @@ -95,4 +68,7 @@ public sealed class MedusaNinjectModule : NinjectModule isLoaded = false; } + + public void Dispose() + => _types.Clear(); } \ No newline at end of file diff --git a/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs b/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs index 633b24197..9b6697afc 100644 --- a/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs +++ b/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs @@ -4,8 +4,6 @@ using Microsoft.Extensions.DependencyInjection; using Nadeko.Common.Medusa; using Nadeko.Medusa.Adapters; using NadekoBot.Common.ModuleBehaviors; -using Ninject; -using Ninject.Modules; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Globalization; @@ -21,7 +19,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, private readonly IBehaviorHandler _behHandler; private readonly IPubSub _pubSub; private readonly IMedusaConfigService _medusaConfig; - private readonly IContainer _kernel; + private readonly IContainer _cont; private readonly ConcurrentDictionary _resolved = new(); private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1); @@ -35,7 +33,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, public MedusaLoaderService( CommandService cmdService, - IContainer kernel, + IContainer cont, IBehaviorHandler behHandler, IPubSub pubSub, IMedusaConfigService medusaConfig) @@ -44,7 +42,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, _behHandler = behHandler; _pubSub = pubSub; _medusaConfig = medusaConfig; - _kernel = kernel; + _cont = cont; // has to be done this way to support this feature on sharded bots _pubSub.Sub(_loadKey, async name => await InternalLoadAsync(name)); @@ -200,7 +198,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, if (LoadAssemblyInternal(safeName, out var ctx, out var snekData, - out var kernelModule, + out var iocModule, out var strings, out var typeReaders)) { @@ -219,7 +217,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, await sub.Instance.InitializeAsync(); } - var module = await LoadModuleInternalAsync(name, point, strings, kernelModule); + var module = await LoadModuleInternalAsync(name, point, strings, iocModule); moduleInfos.Add(module); } catch (Exception ex) @@ -240,7 +238,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, typeReaders, execs) { - KernelModule = kernelModule + IocModule = iocModule }; @@ -273,11 +271,11 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, var behs = new List(); foreach (var snek in snekData) { - behs.Add(new BehaviorAdapter(new(snek.Instance), strings, _kernel)); + behs.Add(new BehaviorAdapter(new(snek.Instance), strings, _cont)); foreach (var sub in snek.Subsneks) { - behs.Add(new BehaviorAdapter(new(sub.Instance), strings, _kernel)); + behs.Add(new BehaviorAdapter(new(sub.Instance), strings, _cont)); } } @@ -315,7 +313,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, string safeName, [NotNullWhen(true)] out WeakReference? ctxWr, [NotNullWhen(true)] out IReadOnlyCollection? snekData, - [NotNullWhen(true)] out INinjectModule? ninjectModule, + [NotNullWhen(true)] out IIocModule? iocModule, out IMedusaStrings strings, out Dictionary typeReaders) { @@ -337,18 +335,15 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, ctx.LoadDependencies(a); // load services - ninjectModule = new MedusaNinjectModule(a, safeName); - - // todo medusa won't work, uncomment - // _kernel.Load(ninjectModule); + iocModule = new MedusaNinjectIocModule(_cont, a, safeName); + iocModule.Load(); var sis = LoadSneksFromAssembly(safeName, a); typeReaders = LoadTypeReadersFromAssembly(a, strings); if (sis.Count == 0) { - // todo uncomment - // _kernel.Unload(safeName); + iocModule.Unload(); return false; } @@ -375,12 +370,12 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, var typeReaders = new Dictionary(); foreach (var parserType in paramParsers) { - var parserObj = ActivatorUtilities.CreateInstance(_kernel, parserType); + var parserObj = ActivatorUtilities.CreateInstance(_cont, parserType); var targetType = parserType.BaseType!.GetGenericArguments()[0]; var typeReaderInstance = (TypeReader)Activator.CreateInstance( typeof(ParamParserAdapter<>).MakeGenericType(targetType), - args: new[] { parserObj, strings, _kernel })!; + args: new[] { parserObj, strings, _cont })!; typeReaders.Add(targetType, typeReaderInstance); } @@ -393,7 +388,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, string medusaName, SnekInfo snekInfo, IMedusaStrings strings, - INinjectModule services) + IIocModule services) { var module = await _cmdService.CreateModuleAsync(snekInfo.Instance.Prefix, CreateModuleFactory(medusaName, snekInfo, strings, services)); @@ -406,7 +401,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, string medusaName, SnekInfo snekInfo, IMedusaStrings strings, - INinjectModule kernelModule) + IIocModule iocModule) => mb => { var m = mb.WithName(snekInfo.Name); @@ -427,7 +422,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, } foreach (var subInfo in snekInfo.Subsneks) - m.AddModule(subInfo.Instance.Prefix, CreateModuleFactory(medusaName, subInfo, strings, kernelModule)); + m.AddModule(subInfo.Instance.Prefix, CreateModuleFactory(medusaName, subInfo, strings, iocModule)); }; private static readonly RequireContextAttribute _reqGuild = new RequireContextAttribute(ContextType.Guild); @@ -511,7 +506,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, return; } - var paramObjs = ParamObjs(contextType, cmdData, parameters, context, svcs, _kernel, strings); + var paramObjs = ParamObjs(contextType, cmdData, parameters, context, svcs, _cont, strings); try { @@ -605,12 +600,11 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, await DisposeSnekInstances(lsi); var lc = lsi.LoadContext; - var km = lsi.KernelModule; - lsi.KernelModule = null!; - - // todo uncomment - // _kernel.Unload(km.Name); + var km = lsi.IocModule; + lsi.IocModule.Unload(); + lsi.IocModule = null!; + if (km is IDisposable d) d.Dispose(); @@ -748,7 +742,7 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, var filters = type.GetCustomAttributes(true) .ToArray(); - var instance = (Snek)ActivatorUtilities.CreateInstance(_kernel, type); + var instance = (Snek)ActivatorUtilities.CreateInstance(_cont, type); var module = new SnekInfo(instance.Name, parentData, diff --git a/src/NadekoBot/_common/Medusa/Common/Models/ResolvedMedusa.cs b/src/NadekoBot/_common/Medusa/Common/Models/ResolvedMedusa.cs index 4d5c311bf..558a8f0d0 100644 --- a/src/NadekoBot/_common/Medusa/Common/Models/ResolvedMedusa.cs +++ b/src/NadekoBot/_common/Medusa/Common/Models/ResolvedMedusa.cs @@ -1,6 +1,4 @@ -using NadekoBot.Medusa; -using Ninject.Modules; -using System.Collections.Immutable; +using System.Collections.Immutable; namespace NadekoBot.Medusa; @@ -13,5 +11,5 @@ public sealed record ResolvedMedusa( IReadOnlyCollection Execs ) { - public required INinjectModule KernelModule { get; set; } + public required IIocModule IocModule { get; set; } } \ No newline at end of file diff --git a/src/NadekoBot/_common/Medusa/Common/RemovablePlanner.cs b/src/NadekoBot/_common/Medusa/Common/RemovablePlanner.cs deleted file mode 100644 index 03158a679..000000000 --- a/src/NadekoBot/_common/Medusa/Common/RemovablePlanner.cs +++ /dev/null @@ -1,122 +0,0 @@ -//------------------------------------------------------------------------------- -// -// Copyright (c) 2007-2009, Enkari, Ltd. -// Copyright (c) 2009-2011 Ninject Project Contributors -// Authors: Nate Kohari (nate@enkari.com) -// Remo Gloor (remo.gloor@gmail.com) -// -// Dual-licensed under the Apache License, Version 2.0, and the Microsoft Public License (Ms-PL). -// you may not use this file except in compliance with one of the Licenses. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// or -// http://www.microsoft.com/opensource/licenses.mspx -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//------------------------------------------------------------------------------- - -// ReSharper disable all -#pragma warning disable - -namespace Ninject.Planning; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Ninject.Components; -using Ninject.Infrastructure.Language; -using Ninject.Planning.Strategies; - -/// -/// Generates plans for how to activate instances. -/// -public class RemovablePlanner : NinjectComponent, IPlanner -{ - private readonly ReaderWriterLock plannerLock = new ReaderWriterLock(); - private readonly Dictionary plans = new Dictionary(); - - /// - /// Initializes a new instance of the class. - /// - /// The strategies to execute during planning. - public RemovablePlanner(IEnumerable strategies) - { - this.Strategies = strategies.ToList(); - } - - /// - /// Gets the strategies that contribute to the planning process. - /// - public IList Strategies { get; private set; } - - /// - /// Gets or creates an activation plan for the specified type. - /// - /// The type for which a plan should be created. - /// The type's activation plan. - public IPlan GetPlan(Type type) - { - this.plannerLock.AcquireReaderLock(Timeout.Infinite); - try - { - IPlan plan; - return this.plans.TryGetValue(type, out plan) ? plan : this.CreateNewPlan(type); - } - finally - { - this.plannerLock.ReleaseReaderLock(); - } - } - - /// - /// Creates an empty plan for the specified type. - /// - /// The type for which a plan should be created. - /// The created plan. - protected virtual IPlan CreateEmptyPlan(Type type) - { - return new Plan(type); - } - - /// - /// Creates a new plan for the specified type. - /// This method requires an active reader lock! - /// - /// The type. - /// The newly created plan. - private IPlan CreateNewPlan(Type type) - { - var lockCooki = this.plannerLock.UpgradeToWriterLock(Timeout.Infinite); - try - { - IPlan plan; - if (this.plans.TryGetValue(type, out plan)) - { - return plan; - } - - plan = this.CreateEmptyPlan(type); - this.plans.Add(type, plan); - this.Strategies.Map(s => s.Execute(plan)); - - return plan; - } - finally - { - this.plannerLock.DowngradeFromWriterLock(ref lockCooki); - } - } - - public void RemovePlan(Type type) - { - plans.Remove(type); - plans.TrimExcess(); - } -} \ No newline at end of file diff --git a/src/NadekoBot/_common/ServiceCollectionExtensions.cs b/src/NadekoBot/_common/ServiceCollectionExtensions.cs index f86704db8..cb6105a4f 100644 --- a/src/NadekoBot/_common/ServiceCollectionExtensions.cs +++ b/src/NadekoBot/_common/ServiceCollectionExtensions.cs @@ -1,14 +1,13 @@ using DryIoc; +using LinqToDB.Extensions; using Microsoft.Extensions.DependencyInjection; using NadekoBot.Modules.Music; using NadekoBot.Modules.Music.Resolvers; using NadekoBot.Modules.Music.Services; -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; @@ -32,63 +31,32 @@ public static class ServiceCollectionExtensions return svcs; } - public static IContainer AddConfigServices(this IContainer kernel, Assembly a) + public static IContainer AddConfigServices(this IContainer svcs, Assembly a) { - // kernel.RegisterMany([typeof(ConfigServiceBase<>)]); foreach (var type in a.GetTypes() .Where(x => !x.IsAbstract && x.IsAssignableToGenericType(typeof(ConfigServiceBase<>)))) { - kernel.RegisterMany([type], + svcs.RegisterMany([type], getServiceTypes: type => type.GetImplementedTypes(ReflectionTools.AsImplementedType.SourceType), getImplFactory: type => ReflectionFactory.Of(type, Reuse.Singleton)); } - - // - // kernel.Bind(x => - // { - // var configs = x.From(a) - // .SelectAllClasses() - // .Where(f => f.IsAssignableToGenericType(typeof(ConfigServiceBase<>))); - // - // configs.BindToSelfWithInterfaces() - // .Configure(c => c.InSingletonScope()); - // }); - - return kernel; + + return svcs; } - public static IContainer AddConfigMigrators(this IContainer kernel, Assembly a) - => kernel.AddSealedSubclassesOf(typeof(IConfigMigrator), a); - public static IContainer AddMusic(this IContainer kernel) + public static IContainer AddMusic(this IContainer svcs) { - kernel.RegisterMany(Reuse.Singleton); + svcs.RegisterMany(Reuse.Singleton); - kernel.AddSingleton(); - kernel.AddSingleton(); - kernel.AddSingleton(); - kernel.AddSingleton(); - kernel.AddSingleton(); + svcs.AddSingleton(); + svcs.AddSingleton(); + svcs.AddSingleton(); + svcs.AddSingleton(); + svcs.AddSingleton(); - return kernel; - } - - public static IContainer AddSealedSubclassesOf(this IContainer cont, Type baseType, Assembly a) - { - var classes = a.GetExportedTypes() - .Where(x => x.IsClass && !x.IsAbstract && x.IsPublic) - .Where(x => x.IsNested && baseType.IsAssignableFrom(x)); - - foreach (var c in classes) - { - cont.RegisterMany([c], Reuse.Singleton); - // var inters = c.GetInterfaces(); - - // cont.RegisterMany(inters, c); - } - - return cont; + return svcs; } public static IContainer AddCache(this IContainer cont, IBotCredentials creds) @@ -110,33 +78,31 @@ public static class ServiceCollectionExtensions .AddBotStringsServices(creds.BotCache); } - public static IContainer AddHttpClients(this IContainer kernel) + public static IContainer AddHttpClients(this IContainer svcs) { - IServiceCollection svcs = new ServiceCollection(); - svcs.AddHttpClient(); - svcs.AddHttpClient("memelist") - .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler - { - AllowAutoRedirect = false - }); + IServiceCollection proxySvcs = new ServiceCollection(); + proxySvcs.AddHttpClient(); + proxySvcs.AddHttpClient("memelist") + .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler + { + AllowAutoRedirect = false + }); - svcs.AddHttpClient("google:search") - .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() - { - AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate - }); + proxySvcs.AddHttpClient("google:search") + .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() + { + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate + }); - var prov = svcs.BuildServiceProvider(); - kernel.RegisterDelegate(_ => prov.GetRequiredService()); - kernel.RegisterDelegate(_ => prov.GetRequiredService()); + var prov = proxySvcs.BuildServiceProvider(); + + svcs.RegisterDelegate(_ => prov.GetRequiredService()); + svcs.RegisterDelegate(_ => prov.GetRequiredService()); - return kernel; + return svcs; } - public static IConfigureSyntax BindToSelfWithInterfaces(this IJoinExcludeIncludeBindSyntax matcher) - => matcher.BindSelection((type, types) => types.Append(type)); - - public static IContainer AddLifetimeServices(this IContainer kernel, Assembly a) + public static IContainer AddLifetimeServices(this IContainer svcs, Assembly a) { Type[] types = [ @@ -149,27 +115,17 @@ public static class ServiceCollectionExtensions ]; foreach (var svc in a.GetTypes() - .Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute())) + .Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute() +#if GLOBAL_NADEKO + && !type.HasAttribute() +#endif + )) { - kernel.RegisterMany([svc], + svcs.RegisterMany([svc], getServiceTypes: type => type.GetImplementedTypes(ReflectionTools.AsImplementedType.SourceType), getImplFactory: type => ReflectionFactory.Of(type, Reuse.Singleton)); } -// -// kernel.RegisterMany( -// [a], -// #if GLOBAL_NADEKO -// && !c.HasAttribute() -// #endif -// ), -// reuse: -// Reuse.Singleton -// ); - - // todo maybe self is missing - // todo maybe attribute doesn't work - - return kernel; + return svcs; } } \ No newline at end of file diff --git a/src/NadekoBot/_common/Settings/IConfigMigrator.cs b/src/NadekoBot/_common/Settings/IConfigMigrator.cs deleted file mode 100644 index 05123d4cc..000000000 --- a/src/NadekoBot/_common/Settings/IConfigMigrator.cs +++ /dev/null @@ -1,7 +0,0 @@ -#nullable disable -namespace NadekoBot.Services; - -public interface IConfigMigrator -{ - public void EnsureMigrated(); -} \ No newline at end of file