diff --git a/Telegrator.Hosting.Web/TelegramBotWebHost.cs b/Telegrator.Hosting.Web/TelegramBotWebHost.cs index 29220f7..f1243f2 100644 --- a/Telegrator.Hosting.Web/TelegramBotWebHost.cs +++ b/Telegrator.Hosting.Web/TelegramBotWebHost.cs @@ -3,16 +3,11 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using System.Text; -using Telegram.Bot.Types.Enums; -using Telegrator.Configuration; using Telegrator.Hosting.Components; using Telegrator.Hosting.Web.Components; using Telegrator.MadiatorCore; -using Telegrator.MadiatorCore.Descriptors; namespace Telegrator.Hosting.Web { diff --git a/Telegrator.Hosting.Web/TypesExtensions.cs b/Telegrator.Hosting.Web/TypesExtensions.cs index 0758647..5b80577 100644 --- a/Telegrator.Hosting.Web/TypesExtensions.cs +++ b/Telegrator.Hosting.Web/TypesExtensions.cs @@ -5,16 +5,13 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Diagnostics; -using System.Text; using Telegram.Bot; -using Telegram.Bot.Types.Enums; using Telegrator.Configuration; using Telegrator.Hosting.Providers; using Telegrator.Hosting.Providers.Components; using Telegrator.Hosting.Web.Components; using Telegrator.Hosting.Web.Polling; using Telegrator.MadiatorCore; -using Telegrator.MadiatorCore.Descriptors; namespace Telegrator.Hosting.Web { @@ -96,8 +93,8 @@ namespace Telegrator.Hosting.Web ILoggerFactory loggerFactory = app.Services.GetRequiredService(); ILogger logger = loggerFactory.CreateLogger("Telegrator.Hosting.Web.TelegratorHost"); - logger.LogInformation("Telegrator Bot WebHost started"); - LogHandlers(handlers, logger); + logger.LogInformation("Telegrator Bot ASP.NET WebHost started"); + logger.LogHandlers(handlers); return app; } @@ -116,27 +113,5 @@ namespace Telegrator.Hosting.Web private static ITelegramBotClient TypedTelegramBotClientFactory(HttpClient httpClient, IServiceProvider provider) => new TelegramBotClient(provider.GetRequiredService>().Value, httpClient); - - private static void LogHandlers(IHandlersCollection handlers, ILogger logger) - { - if (!handlers.Keys.Any()) - throw new Exception("No handlers were registered for the bot."); - - StringBuilder logBuilder = new StringBuilder("Registered handlers : "); - foreach (UpdateType updateType in handlers.Keys) - { - HandlerDescriptorList descriptors = handlers[updateType]; - logBuilder.Append("\n\tUpdateType." + updateType + " :"); - - foreach (HandlerDescriptor descriptor in Enumerable.Reverse(descriptors)) - { - logBuilder.AppendFormat("\n\t* {0} - {1}", - descriptor.Indexer.ToString(), - descriptor.ToString()); - } - } - - logger.LogInformation(logBuilder.ToString()); - } } } diff --git a/Telegrator.Hosting/Providers/HostHandlersCollection.cs b/Telegrator.Hosting/Providers/HostHandlersCollection.cs index eb4a95d..cc76683 100644 --- a/Telegrator.Hosting/Providers/HostHandlersCollection.cs +++ b/Telegrator.Hosting/Providers/HostHandlersCollection.cs @@ -13,7 +13,7 @@ namespace Telegrator.Hosting.Providers /// Pre host building task /// /// - public delegate void PreBuildingRoutine(IApplicationBuilder builder); + public delegate void PreBuildingRoutine(ITelegramBotHostBuilder builder); /// public class HostHandlersCollection(IServiceCollection hostServiceColletion, ITelegratorOptions options) : HandlersCollection(options), IHostHandlersCollection diff --git a/Telegrator.Hosting/TelegramBotHost.cs b/Telegrator.Hosting/TelegramBotHost.cs index ca82e1d..0da2423 100644 --- a/Telegrator.Hosting/TelegramBotHost.cs +++ b/Telegrator.Hosting/TelegramBotHost.cs @@ -1,13 +1,8 @@ using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using System.Text; -using Telegram.Bot.Types.Enums; -using Telegrator.Configuration; using Telegrator.Hosting.Components; using Telegrator.MadiatorCore; -using Telegrator.MadiatorCore.Descriptors; namespace Telegrator.Hosting { @@ -47,16 +42,14 @@ namespace Telegrator.Hosting // Building proxy hoster _innerHost = hostApplicationBuilder.Build(); _serviceProvider = _innerHost.Services; - - // Initializing bot info, as it requires to make a request via tg bot - Services.GetRequiredService(); + _innerHost.UseTelegrator(); // Reruesting services for this host _updateRouter = Services.GetRequiredService(); _logger = Services.GetRequiredService>(); // Logging registering handlers in DEBUG purposes - LogHandlers(handlers); + _logger.LogHandlers(handlers); } /// @@ -131,28 +124,6 @@ namespace Telegrator.Hosting _disposed = true; } - private void LogHandlers(IHandlersCollection handlers) - { - StringBuilder logBuilder = new StringBuilder("Registered handlers : "); - if (!handlers.Keys.Any()) - throw new Exception(); - - foreach (UpdateType updateType in handlers.Keys) - { - HandlerDescriptorList descriptors = handlers[updateType]; - logBuilder.Append("\n\tUpdateType." + updateType + " :"); - - foreach (HandlerDescriptor descriptor in descriptors.Reverse()) - { - logBuilder.AppendFormat("\n\t* {0} - {1}", - descriptor.Indexer.ToString(), - descriptor.ToString()); - } - } - - Logger.LogInformation(logBuilder.ToString()); - } - private void RegisterHostServices(IServiceCollection services, IHandlersCollection handlers) { //services.RemoveAll(); @@ -160,14 +131,6 @@ namespace Telegrator.Hosting services.AddSingleton(this); services.AddSingleton(this); - services.AddSingleton(handlers); - - if (handlers is IHandlersManager manager) - { - services.RemoveAll(); - services.AddSingleton(manager); - services.AddSingleton(manager); - } } } } diff --git a/Telegrator.Hosting/TelegramBotHostBuilder.cs b/Telegrator.Hosting/TelegramBotHostBuilder.cs index 9387e7d..ee767f2 100644 --- a/Telegrator.Hosting/TelegramBotHostBuilder.cs +++ b/Telegrator.Hosting/TelegramBotHostBuilder.cs @@ -2,14 +2,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Telegram.Bot; -using Telegram.Bot.Polling; -using Telegrator.Hosting; using Telegrator.Hosting.Components; -using Telegrator.Hosting.Configuration; using Telegrator.Hosting.Providers; -using Telegrator.Hosting.Providers.Components; using Telegrator.MadiatorCore; #pragma warning disable IDE0001 @@ -50,6 +44,7 @@ namespace Telegrator.Hosting _settings = settings ?? new TelegramBotHostBuilderSettings(); _handlers = new HostHandlersCollection(Services, _settings); + _innerBuilder.AddTelegrator(_settings, _handlers); _innerBuilder.Logging.ClearProviders(); } @@ -65,6 +60,7 @@ namespace Telegrator.Hosting _settings = settings ?? new TelegramBotHostBuilderSettings(); _handlers = handlers ?? throw new ArgumentNullException(nameof(handlers)); + _innerBuilder.AddTelegrator(_settings, _handlers); _innerBuilder.Logging.ClearProviders(); } @@ -74,39 +70,6 @@ namespace Telegrator.Hosting /// public TelegramBotHost Build() { - if (_handlers is IHostHandlersCollection hostHandlers) - { - foreach (PreBuildingRoutine preBuildRoutine in hostHandlers.PreBuilderRoutines) - { - try - { - preBuildRoutine.Invoke(this); - } - catch (NotImplementedException) - { - _ = 0xBAD + 0xC0DE; - } - } - } - - if (!_settings.DisableAutoConfigure) - { - Services.Configure(Configuration.GetSection(nameof(ReceiverOptions))); - Services.Configure(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy()); - } - else - { - /* - if (null == Services.SingleOrDefault(srvc => srvc.ImplementationType == typeof(IOptions))) - throw new MissingMemberException("Auto configuration disabled, yet no options of type 'ReceiverOptions' wasn't registered. This configuration is runtime required!"); - */ - - if (null == Services.SingleOrDefault(srvc => srvc.ImplementationType == typeof(IOptions))) - throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegramBotClientOptions' wasn't registered. This configuration is runtime required!"); - } - - Services.AddSingleton>(Options.Create(_settings)); - Services.AddSingleton(Configuration); return new TelegramBotHost(_innerBuilder, _handlers); } } diff --git a/Telegrator.Hosting/TypesExtensions.cs b/Telegrator.Hosting/TypesExtensions.cs index 93b3f69..2a07986 100644 --- a/Telegrator.Hosting/TypesExtensions.cs +++ b/Telegrator.Hosting/TypesExtensions.cs @@ -1,22 +1,95 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Text; using Telegram.Bot; +using Telegram.Bot.Polling; using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; using Telegrator.Configuration; using Telegrator.Hosting.Components; using Telegrator.Hosting.Configuration; using Telegrator.Hosting.Logging; using Telegrator.Hosting.Polling; using Telegrator.Hosting.Providers; +using Telegrator.Hosting.Providers.Components; using Telegrator.Logging; using Telegrator.MadiatorCore; +using Telegrator.MadiatorCore.Descriptors; namespace Telegrator.Hosting { + public static class HostBuilderExtensions + { + /// + /// Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers. + /// + public static IHostApplicationBuilder AddTelegrator(this IHostApplicationBuilder builder, TelegramBotHostBuilderSettings settings, IHandlersCollection? handlers = null) + { + if (settings is null) + throw new ArgumentNullException(nameof(settings)); + + IServiceCollection services = builder.Services; + IConfigurationManager configuration = builder.Configuration; + + handlers ??= new HostHandlersCollection(services, settings); + + if (handlers is IHostHandlersCollection hostHandlers) + { + foreach (PreBuildingRoutine preBuildRoutine in hostHandlers.PreBuilderRoutines) + { + try + { + // TODO: fix + //preBuildRoutine.Invoke(builder); + Debug.WriteLine("Pre-Building routine was not executed"); + } + catch (NotImplementedException) + { + _ = 0xBAD + 0xC0DE; + } + } + } + + if (!settings.DisableAutoConfigure) + { + services.Configure(configuration.GetSection(nameof(ReceiverOptions))); + services.Configure(configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy()); + } + else + { + /* + if (null == Services.SingleOrDefault(srvc => srvc.ImplementationType == typeof(IOptions))) + throw new MissingMemberException("Auto configuration disabled, yet no options of type 'ReceiverOptions' wasn't registered. This configuration is runtime required!"); + */ + + if (null == services.SingleOrDefault(srvc => srvc.ImplementationType == typeof(IOptions))) + throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegramBotClientOptions' wasn't registered. This configuration is runtime required!"); + } + + IOptions options = Options.Create(settings); + services.AddSingleton((IOptions)options); + services.AddTelegramBotHostDefaults(); + services.AddSingleton(options); + services.AddSingleton(handlers); + + if (handlers is IHandlersManager manager) + { + ServiceDescriptor descriptor = new ServiceDescriptor(typeof(IHandlersProvider), manager); + services.Replace(descriptor); + services.AddSingleton(manager); + } + + return builder; + } + } + /// /// Contains extensions for /// Provides method to configure @@ -81,15 +154,34 @@ namespace Telegrator.Hosting /// public static class TelegramBotHostExtensions { + /// + /// Replaces the initialization logic from TelegramBotWebHost constructor. + /// Initializes the bot and logs handlers on application startup. + /// + public static IHost UseTelegrator(this IHost botHost) + { + ITelegramBotInfo info = botHost.Services.GetRequiredService(); + IHandlersCollection handlers = botHost.Services.GetRequiredService(); + ILoggerFactory loggerFactory = botHost.Services.GetRequiredService(); + ILogger logger = loggerFactory.CreateLogger("Telegrator.Hosting.Web.TelegratorHost"); + + logger.LogInformation("Telegrator Bot .NET Host started"); + logger.LogHandlers(handlers); + + return botHost; + } + /// /// Configures bots available commands depending on what handlers was registered /// /// /// - public static ITelegramBotHost SetBotCommands(this ITelegramBotHost botHost) + public static IHost SetBotCommands(this IHost botHost) { ITelegramBotClient client = botHost.Services.GetRequiredService(); - IEnumerable aliases = botHost.UpdateRouter.HandlersProvider.GetBotCommands(); + IUpdateRouter router = botHost.Services.GetRequiredService(); + + IEnumerable aliases = router.HandlersProvider.GetBotCommands(); client.SetMyCommands(aliases).Wait(); return botHost; } @@ -98,10 +190,11 @@ namespace Telegrator.Hosting /// Adds a Microsoft.Extensions.Logging adapter to Alligator using a logger factory. /// /// - public static ITelegramBotHost AddLoggingAdapter(this ITelegramBotHost host) + public static IHost AddLoggingAdapter(this IHost host) { ILoggerFactory loggerFactory = host.Services.GetRequiredService(); ILogger logger = loggerFactory.CreateLogger("Telegrator"); + MicrosoftLoggingAdapter adapter = new MicrosoftLoggingAdapter(logger); Alligator.AddAdapter(adapter); return host; @@ -129,4 +222,29 @@ namespace Telegrator.Hosting return routineMethod != null; } } + + public static class LoggerExtensions + { + public static void LogHandlers(this ILogger logger, IHandlersCollection handlers) + { + StringBuilder logBuilder = new StringBuilder("Registered handlers : "); + if (!handlers.Keys.Any()) + throw new Exception(); + + foreach (UpdateType updateType in handlers.Keys) + { + HandlerDescriptorList descriptors = handlers[updateType]; + logBuilder.Append("\n\tUpdateType." + updateType + " :"); + + foreach (HandlerDescriptor descriptor in descriptors.Reverse()) + { + logBuilder.AppendFormat("\n\t* {0} - {1}", + descriptor.Indexer.ToString(), + descriptor.ToString()); + } + } + + logger.LogInformation(logBuilder.ToString()); + } + } }