using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using BotSharp.Abstraction.Functions; using BotSharp.Core.Plugins; using BotSharp.Abstraction.Settings; using BotSharp.Abstraction.Options; using BotSharp.Abstraction.Messaging.JsonConverters; using BotSharp.Abstraction.Users.Settings; using BotSharp.Abstraction.Interpreters.Settings; using BotSharp.Abstraction.Infrastructures; using BotSharp.Core.Processors; using StackExchange.Redis; using BotSharp.Core.Infrastructures.Events; using BotSharp.Core.Roles.Services; using BotSharp.Abstraction.Templating; using BotSharp.Core.Templating; using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Realtime; using BotSharp.Abstraction.Repositories.Settings; namespace BotSharp.Core; public static class BotSharpCoreExtensions { public static IServiceCollection AddBotSharpCore(this IServiceCollection services, IConfiguration config, Action? configOptions = null) { var interpreterSettings = new InterpreterSettings(); config.Bind("Interpreter", interpreterSettings); services.AddSingleton(x => interpreterSettings); services.AddSingleton(); // Register template render services.AddSingleton(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); AddRedisEvents(services, config); // Register cache service AddCacheServices(services, config); RegisterPlugins(services, config); AddBotSharpOptions(services, configOptions); return services; } private static void AddCacheServices(IServiceCollection services, IConfiguration config) { services.AddMemoryCache(); var cacheSettings = new SharpCacheSettings(); config.Bind("SharpCache", cacheSettings); services.AddSingleton(x => cacheSettings); services.AddSingleton(sp => cacheSettings.CacheType switch { CacheType.RedisCache => ActivatorUtilities.CreateInstance(sp), _ => ActivatorUtilities.CreateInstance(sp), }); } public static IServiceCollection UsingSqlServer(this IServiceCollection services, IConfiguration config) { services.AddScoped(sp => { var myDatabaseSettings = sp.GetRequiredService(); return DataContextHelper.GetSqlServerDbContext(myDatabaseSettings, sp); }); return services; } public static IApplicationBuilder UseBotSharp(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } app.ApplicationServices.GetRequiredService().Configure(app); // Set root services for SharpCacheAttribute SharpCacheAttribute.Services = app.ApplicationServices; return app; } private static void AddBotSharpOptions(IServiceCollection services, Action? configure) { var options = new BotSharpOptions(); if (configure != null) { configure(options); } AddDefaultJsonConverters(options); services.AddSingleton(options); } private static void AddRedisEvents(IServiceCollection services, IConfiguration config) { // Add Redis connection as a singleton var dbSettings = new BotSharpDatabaseSettings(); config.Bind("Database", dbSettings); if (string.IsNullOrEmpty(dbSettings.Redis)) { return; } services.AddSingleton(ConnectionMultiplexer.Connect(dbSettings.Redis)); services.AddSingleton(); services.AddSingleton(); } private static void AddDefaultJsonConverters(BotSharpOptions options) { options.JsonSerializerOptions.Converters.Add(new RichContentJsonConverter()); options.JsonSerializerOptions.Converters.Add(new TemplateMessageJsonConverter()); } public static void RegisterPlugins(IServiceCollection services, IConfiguration config) { var pluginSettings = new PluginSettings(); config.Bind("PluginLoader", pluginSettings); services.AddScoped(provider => { var settingService = provider.GetRequiredService(); return settingService.Bind("PluginLoader"); }); var accountSettings = new AccountSetting(); config.Bind("Account", accountSettings); services.AddScoped(x => accountSettings); var loader = new PluginLoader(services, config, pluginSettings); loader.Load(assembly => { // Register function callback var functions = assembly.GetTypes() .Where(x => x.IsClass && x.GetInterface(nameof(IFunctionCallback)) != null) .ToArray(); foreach (var function in functions) { services.AddScoped(typeof(IFunctionCallback), function); } }); services.AddSingleton(loader); } }