* Added protection from NotImplementedException to HandlerBuilderBase

* Moved AddHandler<T> and AddHandler(Type) methods from IHandlersCollection to extension methods
* Added public constructor to IHost types form extensibility
* Code cleanup
This commit is contained in:
2025-08-19 04:33:02 +04:00
parent a5bae95bad
commit 16440bcf43
21 changed files with 211 additions and 165 deletions
+15 -10
View File
@@ -55,10 +55,15 @@ namespace Telegrator.Hosting.Web
IFeatureCollection IApplicationBuilder.ServerFeatures => ((IApplicationBuilder)_innerApp).ServerFeatures; IFeatureCollection IApplicationBuilder.ServerFeatures => ((IApplicationBuilder)_innerApp).ServerFeatures;
IDictionary<string, object?> IApplicationBuilder.Properties => ((IApplicationBuilder)_innerApp).Properties; IDictionary<string, object?> IApplicationBuilder.Properties => ((IApplicationBuilder)_innerApp).Properties;
internal TelegramBotWebHost(WebApplicationBuilder webApplicationBuilder, HostHandlersCollection handlers) /// <summary>
/// Initializes a new instance of the <see cref="WebApplicationBuilder"/> class.
/// </summary>
/// <param name="webApplicationBuilder">The proxied instance of host builder.</param>
/// <param name="handlers"></param>
public TelegramBotWebHost(WebApplicationBuilder webApplicationBuilder, IHandlersCollection handlers)
{ {
// Registering this host in services for easy access // Registering this host in services for easy access
RegisterHostServices(webApplicationBuilder, handlers); RegisterHostServices(webApplicationBuilder.Services, handlers);
// Building proxy application // Building proxy application
_innerApp = webApplicationBuilder.Build(); _innerApp = webApplicationBuilder.Build();
@@ -172,7 +177,7 @@ namespace Telegrator.Hosting.Web
_disposed = true; _disposed = true;
} }
private void LogHandlers(HostHandlersCollection handlers) private void LogHandlers(IHandlersCollection handlers)
{ {
StringBuilder logBuilder = new StringBuilder("Registered handlers : "); StringBuilder logBuilder = new StringBuilder("Registered handlers : ");
if (!handlers.Keys.Any()) if (!handlers.Keys.Any())
@@ -194,15 +199,15 @@ namespace Telegrator.Hosting.Web
Logger.LogInformation(logBuilder.ToString()); Logger.LogInformation(logBuilder.ToString());
} }
private void RegisterHostServices(WebApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers) private void RegisterHostServices(IServiceCollection service, IHandlersCollection handlers)
{ {
//hostApplicationBuilder.Services.RemoveAll<IHost>(); //service.RemoveAll<IHost>();
//hostApplicationBuilder.Services.AddSingleton<IHost>(this); //service.AddSingleton<IHost>(this);
hostApplicationBuilder.Services.AddSingleton<ITelegramBotHost>(this); service.AddSingleton<ITelegramBotHost>(this);
hostApplicationBuilder.Services.AddSingleton<ITelegramBotWebHost>(this); service.AddSingleton<ITelegramBotWebHost>(this);
hostApplicationBuilder.Services.AddSingleton<ITelegratorBot>(this); service.AddSingleton<ITelegratorBot>(this);
hostApplicationBuilder.Services.AddSingleton<IHandlersCollection>(handlers); service.AddSingleton<IHandlersCollection>(handlers);
} }
} }
} }
@@ -5,10 +5,10 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Telegram.Bot; using Telegram.Bot;
using Telegram.Bot.Polling;
using Telegrator.Hosting.Components; using Telegrator.Hosting.Components;
using Telegrator.Hosting.Configuration; using Telegrator.Hosting.Configuration;
using Telegrator.Hosting.Providers; using Telegrator.Hosting.Providers;
using Telegrator.Hosting.Providers.Components;
using Telegrator.MadiatorCore; using Telegrator.MadiatorCore;
#pragma warning disable IDE0001 #pragma warning disable IDE0001
@@ -21,7 +21,7 @@ namespace Telegrator.Hosting.Web
{ {
private readonly WebApplicationBuilder _innerBuilder; private readonly WebApplicationBuilder _innerBuilder;
private readonly TelegramBotWebOptions _settings; private readonly TelegramBotWebOptions _settings;
private readonly HostHandlersCollection _handlers; private readonly IHandlersCollection _handlers;
/// <inheritdoc/> /// <inheritdoc/>
public IHandlersCollection Handlers => _handlers; public IHandlersCollection Handlers => _handlers;
@@ -38,20 +38,40 @@ namespace Telegrator.Hosting.Web
/// <inheritdoc/> /// <inheritdoc/>
public IHostEnvironment Environment => _innerBuilder.Environment; public IHostEnvironment Environment => _innerBuilder.Environment;
internal TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder, TelegramBotWebOptions settings) /// <summary>
/// Initializes a new instance of the <see cref="TelegramBotWebHostBuilder"/> class.
/// </summary>
/// <param name="webApplicationBuilder"></param>
/// <param name="settings"></param>
public TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder, TelegramBotWebOptions settings)
{ {
_innerBuilder = webApplicationBuilder; _innerBuilder = webApplicationBuilder ?? throw new ArgumentNullException(nameof(webApplicationBuilder));
_settings = settings ?? throw new ArgumentNullException(nameof(settings)); _settings = settings ?? throw new ArgumentNullException(nameof(settings));
_handlers = new HostHandlersCollection(Services, _settings); _handlers = new HostHandlersCollection(Services, _settings);
} }
/// <summary>
/// Initializes a new instance of the <see cref="TelegramBotWebHostBuilder"/> class.
/// </summary>
/// <param name="webApplicationBuilder"></param>
/// <param name="handlers"></param>
/// <param name="settings"></param>
public TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder, TelegramBotWebOptions settings, IHandlersCollection handlers)
{
_innerBuilder = webApplicationBuilder ?? throw new ArgumentNullException(nameof(webApplicationBuilder));
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
_handlers = handlers ?? throw new ArgumentNullException(nameof(settings));
}
/// <summary> /// <summary>
/// Builds the host. /// Builds the host.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public TelegramBotWebHost Build() public TelegramBotWebHost Build()
{ {
foreach (PreBuildingRoutine preBuildRoutine in _handlers.PreBuilderRoutines) if (_handlers is IHostHandlersCollection hostHandlers)
{
foreach (PreBuildingRoutine preBuildRoutine in hostHandlers.PreBuilderRoutines)
{ {
try try
{ {
@@ -62,6 +82,7 @@ namespace Telegrator.Hosting.Web
_ = 0xBAD + 0xC0DE; _ = 0xBAD + 0xC0DE;
} }
} }
}
if (!_settings.DisableAutoConfigure) if (!_settings.DisableAutoConfigure)
{ {
@@ -0,0 +1,16 @@
using Telegrator.MadiatorCore;
namespace Telegrator.Hosting.Providers.Components
{
/// <summary>
/// Collection class for managing handler descriptors organized by update type for host apps.
/// Provides functionality for collecting, adding, scanning, and organizing handlers.
/// </summary>
public interface IHostHandlersCollection : IHandlersCollection
{
/// <summary>
/// List of tasks that should be completed right before building the bot
/// </summary>
public List<PreBuildingRoutine> PreBuilderRoutines { get; }
}
}
@@ -2,6 +2,7 @@
using System.Reflection; using System.Reflection;
using Telegrator.Configuration; using Telegrator.Configuration;
using Telegrator.Hosting.Components; using Telegrator.Hosting.Components;
using Telegrator.Hosting.Providers.Components;
using Telegrator.MadiatorCore; using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors; using Telegrator.MadiatorCore.Descriptors;
using Telegrator.Providers; using Telegrator.Providers;
@@ -15,7 +16,7 @@ namespace Telegrator.Hosting.Providers
public delegate void PreBuildingRoutine(ITelegramBotHostBuilder builder); public delegate void PreBuildingRoutine(ITelegramBotHostBuilder builder);
/// <inheritdoc/> /// <inheritdoc/>
public class HostHandlersCollection(IServiceCollection hostServiceColletion, ITelegratorOptions options) : HandlersCollection(options) public class HostHandlersCollection(IServiceCollection hostServiceColletion, ITelegratorOptions options) : HandlersCollection(options), IHostHandlersCollection
{ {
private readonly IServiceCollection Services = hostServiceColletion; private readonly IServiceCollection Services = hostServiceColletion;
@@ -25,20 +26,14 @@ namespace Telegrator.Hosting.Providers
/// <summary> /// <summary>
/// List of tasks that should be completed right before building the bot /// List of tasks that should be completed right before building the bot
/// </summary> /// </summary>
public readonly List<PreBuildingRoutine> PreBuilderRoutines = []; public List<PreBuildingRoutine> PreBuilderRoutines { get; } = [];
/// <inheritdoc/>
public override IHandlersCollection AddHandler(Type handlerType)
{
if (handlerType.IsPreBuildingRoutine(out MethodInfo? routineMethod))
PreBuilderRoutines.Add(routineMethod.CreateDelegate<PreBuildingRoutine>(null));
return base.AddHandler(handlerType);
}
/// <inheritdoc/> /// <inheritdoc/>
public override IHandlersCollection AddDescriptor(HandlerDescriptor descriptor) public override IHandlersCollection AddDescriptor(HandlerDescriptor descriptor)
{ {
if (descriptor.HandlerType.IsPreBuildingRoutine(out MethodInfo? routineMethod))
PreBuilderRoutines.Add(routineMethod.CreateDelegate<PreBuildingRoutine>(null));
switch (descriptor.Type) switch (descriptor.Type)
{ {
case DescriptorType.General: case DescriptorType.General:
+13 -14
View File
@@ -5,9 +5,6 @@ using System.Text;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Configuration; using Telegrator.Configuration;
using Telegrator.Hosting.Components; using Telegrator.Hosting.Components;
using Telegrator.Hosting.Logging;
using Telegrator.Logging;
using Telegrator.Hosting.Providers;
using Telegrator.MadiatorCore; using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors; using Telegrator.MadiatorCore.Descriptors;
@@ -19,13 +16,14 @@ namespace Telegrator.Hosting
public class TelegramBotHost : ITelegramBotHost public class TelegramBotHost : ITelegramBotHost
{ {
private readonly IHost _innerHost; private readonly IHost _innerHost;
private readonly IServiceProvider _serviceProvider;
private readonly IUpdateRouter _updateRouter; private readonly IUpdateRouter _updateRouter;
private readonly ILogger<TelegramBotHost> _logger; private readonly ILogger<TelegramBotHost> _logger;
private bool _disposed; private bool _disposed;
/// <inheritdoc/> /// <inheritdoc/>
public IServiceProvider Services => _innerHost.Services; public IServiceProvider Services => _serviceProvider;
/// <inheritdoc/> /// <inheritdoc/>
public IUpdateRouter UpdateRouter => _updateRouter; public IUpdateRouter UpdateRouter => _updateRouter;
@@ -38,15 +36,16 @@ namespace Telegrator.Hosting
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="TelegramBotHost"/> class. /// Initializes a new instance of the <see cref="TelegramBotHost"/> class.
/// </summary> /// </summary>
/// <param name="hostApplicationBuilder">The service provider.</param> /// <param name="hostApplicationBuilder">The proxied instance of host builder.</param>
/// <param name="handlers"></param> /// <param name="handlers"></param>
internal TelegramBotHost(HostApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers) public TelegramBotHost(HostApplicationBuilder hostApplicationBuilder, IHandlersCollection handlers)
{ {
// Registering this host in services for easy access // Registering this host in services for easy access
RegisterHostServices(hostApplicationBuilder, handlers); RegisterHostServices(hostApplicationBuilder.Services, handlers);
// Building proxy hoster // Building proxy hoster
_innerHost = hostApplicationBuilder.Build(); _innerHost = hostApplicationBuilder.Build();
_serviceProvider = _innerHost.Services;
// Initializing bot info, as it requires to make a request via tg bot // Initializing bot info, as it requires to make a request via tg bot
Services.GetRequiredService<ITelegramBotInfo>(); Services.GetRequiredService<ITelegramBotInfo>();
@@ -131,7 +130,7 @@ namespace Telegrator.Hosting
_disposed = true; _disposed = true;
} }
private void LogHandlers(HostHandlersCollection handlers) private void LogHandlers(IHandlersCollection handlers)
{ {
StringBuilder logBuilder = new StringBuilder("Registered handlers : "); StringBuilder logBuilder = new StringBuilder("Registered handlers : ");
if (!handlers.Keys.Any()) if (!handlers.Keys.Any())
@@ -153,14 +152,14 @@ namespace Telegrator.Hosting
Logger.LogInformation(logBuilder.ToString()); Logger.LogInformation(logBuilder.ToString());
} }
private void RegisterHostServices(HostApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers) private void RegisterHostServices(IServiceCollection services, IHandlersCollection handlers)
{ {
//hostApplicationBuilder.Services.RemoveAll<IHost>(); //services.RemoveAll<IHost>();
//hostApplicationBuilder.Services.AddSingleton<IHost>(this); //services.AddSingleton<IHost>(this);
hostApplicationBuilder.Services.AddSingleton<ITelegramBotHost>(this); services.AddSingleton<ITelegramBotHost>(this);
hostApplicationBuilder.Services.AddSingleton<ITelegratorBot>(this); services.AddSingleton<ITelegratorBot>(this);
hostApplicationBuilder.Services.AddSingleton<IHandlersCollection>(handlers); services.AddSingleton<IHandlersCollection>(handlers);
} }
} }
} }
+23 -4
View File
@@ -9,6 +9,7 @@ using Telegrator.Hosting;
using Telegrator.Hosting.Components; using Telegrator.Hosting.Components;
using Telegrator.Hosting.Configuration; using Telegrator.Hosting.Configuration;
using Telegrator.Hosting.Providers; using Telegrator.Hosting.Providers;
using Telegrator.Hosting.Providers.Components;
using Telegrator.MadiatorCore; using Telegrator.MadiatorCore;
#pragma warning disable IDE0001 #pragma warning disable IDE0001
@@ -21,7 +22,7 @@ namespace Telegrator.Hosting
{ {
private readonly HostApplicationBuilder _innerBuilder; private readonly HostApplicationBuilder _innerBuilder;
private readonly TelegramBotHostBuilderSettings _settings; private readonly TelegramBotHostBuilderSettings _settings;
private readonly HostHandlersCollection _handlers; private readonly IHandlersCollection _handlers;
/// <inheritdoc/> /// <inheritdoc/>
public IHandlersCollection Handlers => _handlers; public IHandlersCollection Handlers => _handlers;
@@ -43,22 +44,39 @@ namespace Telegrator.Hosting
/// </summary> /// </summary>
/// <param name="hostApplicationBuilder"></param> /// <param name="hostApplicationBuilder"></param>
/// <param name="settings"></param> /// <param name="settings"></param>
internal TelegramBotHostBuilder(HostApplicationBuilder hostApplicationBuilder, TelegramBotHostBuilderSettings? settings = null) public TelegramBotHostBuilder(HostApplicationBuilder hostApplicationBuilder, TelegramBotHostBuilderSettings? settings = null)
{ {
_innerBuilder = hostApplicationBuilder; _innerBuilder = hostApplicationBuilder ?? throw new ArgumentNullException(nameof(hostApplicationBuilder));
_settings = settings ?? new TelegramBotHostBuilderSettings(); _settings = settings ?? new TelegramBotHostBuilderSettings();
_handlers = new HostHandlersCollection(Services, _settings); _handlers = new HostHandlersCollection(Services, _settings);
_innerBuilder.Logging.ClearProviders(); _innerBuilder.Logging.ClearProviders();
} }
/// <summary>
/// Initializes a new instance of the <see cref="TelegramBotHostBuilder"/> class.
/// </summary>
/// <param name="hostApplicationBuilder"></param>
/// <param name="handlers"></param>
/// <param name="settings"></param>
public TelegramBotHostBuilder(HostApplicationBuilder hostApplicationBuilder, IHandlersCollection handlers, TelegramBotHostBuilderSettings? settings = null)
{
_innerBuilder = hostApplicationBuilder ?? throw new ArgumentNullException(nameof(hostApplicationBuilder));
_settings = settings ?? new TelegramBotHostBuilderSettings();
_handlers = handlers ?? throw new ArgumentNullException(nameof(handlers));
_innerBuilder.Logging.ClearProviders();
}
/// <summary> /// <summary>
/// Builds the host. /// Builds the host.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public TelegramBotHost Build() public TelegramBotHost Build()
{ {
foreach (PreBuildingRoutine preBuildRoutine in _handlers.PreBuilderRoutines) if (_handlers is IHostHandlersCollection hostHandlers)
{
foreach (PreBuildingRoutine preBuildRoutine in hostHandlers.PreBuilderRoutines)
{ {
try try
{ {
@@ -69,6 +87,7 @@ namespace Telegrator.Hosting
_ = 0xBAD + 0xC0DE; _ = 0xBAD + 0xC0DE;
} }
} }
}
if (!_settings.DisableAutoConfigure) if (!_settings.DisableAutoConfigure)
{ {
@@ -1,4 +1,5 @@
using Telegram.Bot; using System.ComponentModel;
using Telegram.Bot;
using Telegram.Bot.Polling; using Telegram.Bot.Polling;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
@@ -41,6 +42,8 @@ namespace Telegrator.Handlers.Components
// Executing pre processor // Executing pre processor
if (aspects != null) if (aspects != null)
{
try
{ {
Result? preResult = await aspects Result? preResult = await aspects
.ExecutePre(this, container, cancellationToken) .ExecutePre(this, container, cancellationToken)
@@ -49,12 +52,26 @@ namespace Telegrator.Handlers.Components
if (!preResult.Positive) if (!preResult.Positive)
return preResult; return preResult;
} }
catch (NotImplementedException)
{
_ = 0xBAD + 0xC0DE;
}
}
try
{
// Executing handler // Executing handler
Result execResult = await ExecuteInternal(container, cancellationToken).ConfigureAwait(false); Result execResult = await ExecuteInternal(container, cancellationToken).ConfigureAwait(false);
if (!execResult.Positive) if (!execResult.Positive)
return execResult; return execResult;
}
catch (NotImplementedException)
{
_ = 0xBAD + 0xC0DE;
}
try
{
// Executing post processor // Executing post processor
if (aspects != null) if (aspects != null)
{ {
@@ -65,6 +82,11 @@ namespace Telegrator.Handlers.Components
if (!postResult.Positive) if (!postResult.Positive)
return postResult; return postResult;
} }
}
catch (NotImplementedException)
{
_ = 0xBAD + 0xC0DE;
}
// Success // Success
return Result.Ok(); return Result.Ok();
@@ -76,10 +98,17 @@ namespace Telegrator.Handlers.Components
return Result.Ok(); return Result.Ok();
} }
catch (Exception exception) catch (Exception exception)
{
try
{ {
await described.UpdateRouter await described.UpdateRouter
.HandleErrorAsync(described.Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken) .HandleErrorAsync(described.Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
}
catch (NotImplementedException)
{
_ = 0xBAD + 0xC0DE;
}
return Result.Fault(); return Result.Fault();
} }
@@ -1,5 +1,4 @@
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Handlers.Components;
using Telegrator.MadiatorCore.Descriptors; using Telegrator.MadiatorCore.Descriptors;
namespace Telegrator.MadiatorCore namespace Telegrator.MadiatorCore
@@ -32,14 +31,6 @@ namespace Telegrator.MadiatorCore
/// <returns>The handler descriptor list for the given update type.</returns> /// <returns>The handler descriptor list for the given update type.</returns>
public HandlerDescriptorList this[UpdateType updateType] { get; } public HandlerDescriptorList this[UpdateType updateType] { get; }
/*
/// <summary>
/// Collects all handlers domain-wide and returns a new <see cref="IHandlersCollection"/>.
/// </summary>
/// <returns>A new <see cref="IHandlersCollection"/> with all handlers collected.</returns>
public IHandlersCollection CollectHandlersDomainWide();
*/
/// <summary> /// <summary>
/// Adds a <see cref="HandlerDescriptor"/> to the collection and returns the updated collection. /// Adds a <see cref="HandlerDescriptor"/> to the collection and returns the updated collection.
/// </summary> /// </summary>
@@ -47,21 +38,6 @@ namespace Telegrator.MadiatorCore
/// <returns>The updated <see cref="IHandlersCollection"/>.</returns> /// <returns>The updated <see cref="IHandlersCollection"/>.</returns>
public IHandlersCollection AddDescriptor(HandlerDescriptor descriptor); public IHandlersCollection AddDescriptor(HandlerDescriptor descriptor);
/// <summary>
/// Adds a handler of the specified type to the collection and returns the updated collection.
/// </summary>
/// <typeparam name="THandler">The type of handler to add, must inherit from <see cref="UpdateHandlerBase"/>.</typeparam>
/// <returns>The updated <see cref="IHandlersCollection"/>.</returns>
public IHandlersCollection AddHandler<THandler>() where THandler : UpdateHandlerBase;
/// <summary>
/// Adds a handler of the specified type to the collection and returns the updated collection.
/// </summary>
/// <param name="handlerType">The type of handler to add.</param>
/// <returns>The updated <see cref="IHandlersCollection"/>.</returns>
/// <exception cref="Exception">Thrown if the handler type is invalid.</exception>
public IHandlersCollection AddHandler(Type handlerType);
/// <summary> /// <summary>
/// Gets the <see cref="HandlerDescriptorList"/> for the specified <see cref="HandlerDescriptor"/>. /// Gets the <see cref="HandlerDescriptorList"/> for the specified <see cref="HandlerDescriptor"/>.
/// </summary> /// </summary>
@@ -88,42 +88,6 @@ namespace Telegrator.Providers
return this; return this;
} }
/// <summary>
/// Adds a handler type to the collection.
/// </summary>
/// <typeparam name="THandler">The type of handler to add.</typeparam>
/// <returns>This collection instance for method chaining.</returns>
public virtual IHandlersCollection AddHandler<THandler>() where THandler : UpdateHandlerBase
{
AddHandler(typeof(THandler));
return this;
}
/// <summary>
/// Adds a handler type to the collection.
/// </summary>
/// <param name="handlerType">The type of handler to add.</param>
/// <returns>This collection instance for method chaining.</returns>
/// <exception cref="Exception">Thrown when the type is not a valid handler implementation.</exception>
public virtual IHandlersCollection AddHandler(Type handlerType)
{
if (!handlerType.IsHandlerRealization())
throw new Exception();
if (handlerType.IsCustomDescriptorsProvider())
{
foreach (HandlerDescriptor handlerDescriptor in InvokeCustomDescriptorsProvider(handlerType))
AddDescriptor(handlerDescriptor);
}
else
{
HandlerDescriptor descriptor = new HandlerDescriptor(DescriptorType.General, handlerType);
AddDescriptor(descriptor);
}
return this;
}
/// <summary> /// <summary>
/// Gets or creates a descriptor list for the specified update type. /// Gets or creates a descriptor list for the specified update type.
/// </summary> /// </summary>
@@ -163,20 +127,5 @@ namespace Telegrator.Providers
CommandAliasses.AddRange(alliasAttribute.Alliases); CommandAliasses.AddRange(alliasAttribute.Alliases);
} }
/// <summary>
/// Invokes a custom descriptors provider to get handler descriptors.
/// </summary>
/// <param name="handlerType">The handler type that implements ICustomDescriptorsProvider.</param>
/// <returns>A collection of handler descriptors from the custom provider.</returns>
/// <exception cref="Exception">Thrown when the handler type doesn't have a parameterless constructor or cannot be instantiated.</exception>
protected virtual IEnumerable<HandlerDescriptor> InvokeCustomDescriptorsProvider(Type handlerType)
{
if (!handlerType.HasParameterlessCtor())
throw new Exception();
ICustomDescriptorsProvider? provider = (ICustomDescriptorsProvider?)Activator.CreateInstance(handlerType);
return provider == null ? throw new Exception() : provider.DescribeHandlers();
}
} }
} }
+40 -1
View File
@@ -86,7 +86,7 @@ namespace Telegrator
throw new InvalidDataException("Message does not contain a command"); throw new InvalidDataException("Message does not contain a command");
if (message is not { Text.Length: > 0 }) if (message is not { Text.Length: > 0 })
throw new ArgumentNullException("Command text cannot be null or empty"); throw new ArgumentNullException(nameof(message), "Command text cannot be null or empty");
if (!message.Text.Contains(' ')) if (!message.Text.Contains(' '))
throw new MissingMemberException("Command dont contains arguments"); throw new MissingMemberException("Command dont contains arguments");
@@ -620,6 +620,45 @@ namespace Telegrator
public static HandlerBuilder<CallbackQuery> CreateCallbackQuery(this IHandlersCollection handlers) public static HandlerBuilder<CallbackQuery> CreateCallbackQuery(this IHandlersCollection handlers)
=> handlers.CreateHandler<CallbackQuery>(UpdateType.CallbackQuery); => handlers.CreateHandler<CallbackQuery>(UpdateType.CallbackQuery);
/// <summary>
/// Adds a handler type to the collection.
/// </summary>
/// <param name="handlers">The handlers collection.</param>
/// <typeparam name="THandler">The type of handler to add.</typeparam>
/// <returns>This collection instance for method chaining.</returns>
public static IHandlersCollection AddHandler<THandler>(this IHandlersCollection handlers) where THandler : UpdateHandlerBase
=> handlers.AddHandler(typeof(THandler));
/// <summary>
/// Adds a handler type to the collection.
/// </summary>
/// <param name="handlers">The handlers collection.</param>
/// <param name="handlerType">The type of handler to add.</param>
/// <returns>This collection instance for method chaining.</returns>
/// <exception cref="Exception">Thrown when the type is not a valid handler implementation.</exception>
public static IHandlersCollection AddHandler(this IHandlersCollection handlers, Type handlerType)
{
if (!handlerType.IsHandlerRealization())
throw new Exception();
if (handlerType.IsCustomDescriptorsProvider())
{
if (!handlerType.HasParameterlessCtor())
throw new Exception();
ICustomDescriptorsProvider provider = (ICustomDescriptorsProvider)Activator.CreateInstance(handlerType);
foreach (HandlerDescriptor handlerDescriptor in provider.DescribeHandlers())
handlers.AddDescriptor(handlerDescriptor);
}
else
{
HandlerDescriptor descriptor = new HandlerDescriptor(DescriptorType.General, handlerType);
handlers.AddDescriptor(descriptor);
}
return handlers;
}
/// <summary> /// <summary>
/// Creates implicit handler from method /// Creates implicit handler from method
/// </summary> /// </summary>
@@ -1,11 +1,11 @@
#if DEBUG
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Text; using System.Text;
using System.Xml.Linq; using System.Xml.Linq;
using Telegrator.RoslynExtensions; using Telegrator.RoslynGenerators.RoslynExtensions;
#if DEBUG
namespace Telegrator.RoslynGenerators namespace Telegrator.RoslynGenerators
{ {
/// <summary> /// <summary>
@@ -3,7 +3,6 @@ using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Text; using System.Text;
using Telegrator.RoslynExtensions;
using Telegrator.RoslynGenerators.RoslynExtensions; using Telegrator.RoslynGenerators.RoslynExtensions;
#if DEBUG #if DEBUG
@@ -1,4 +1,4 @@
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class CollectionsExtensions public static class CollectionsExtensions
{ {
@@ -1,6 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class DiagnosticsHelper public static class DiagnosticsHelper
{ {
@@ -1,4 +1,4 @@
namespace Telegrator.RoslynExtensions; namespace Telegrator.RoslynGenerators.RoslynExtensions;
public class TargteterNotFoundException() : Exception() { } public class TargteterNotFoundException() : Exception() { }
@@ -1,7 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Telegrator.RoslynExtensions;
namespace Telegrator.RoslynGenerators.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
@@ -1,6 +1,6 @@
using System.Text; using System.Text;
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class StringBuilderExtensions public static class StringBuilderExtensions
{ {
@@ -1,4 +1,4 @@
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class StringExtensions public static class StringExtensions
{ {
@@ -1,6 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
namespace Telegrator.RoslynExtensions; namespace Telegrator.RoslynGenerators.RoslynExtensions;
public static class SymbolsExtensions public static class SymbolsExtensions
{ {
@@ -2,7 +2,7 @@
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class SyntaxNodesExtensions public static class SyntaxNodesExtensions
{ {
@@ -1,6 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
namespace Telegrator.RoslynExtensions namespace Telegrator.RoslynGenerators.RoslynExtensions
{ {
public static class SyntaxTokenExtensions public static class SyntaxTokenExtensions
{ {