* Code cleanup
* Moved handler execution logic from "DescribedHandlerInfo" to "UpdateHandlerBase" * Added logging message on handler described
This commit is contained in:
@@ -18,6 +18,7 @@ namespace Telegrator.Tests.Handlers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class HandlerTests
|
public class HandlerTests
|
||||||
{
|
{
|
||||||
|
/*s
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Тест для базового обработчика обновлений.
|
/// Тест для базового обработчика обновлений.
|
||||||
///
|
///
|
||||||
@@ -37,6 +38,7 @@ namespace Telegrator.Tests.Handlers
|
|||||||
testHandler.WasExecuted.Should().BeTrue();
|
testHandler.WasExecuted.Should().BeTrue();
|
||||||
testHandler.LifetimeToken.IsEnded.Should().BeTrue();
|
testHandler.LifetimeToken.IsEnded.Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Тест для проверки токена жизненного цикла.
|
/// Тест для проверки токена жизненного цикла.
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using Telegrator.Handlers;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Telegrator.Handlers;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
|
|
||||||
namespace Telegrator.Aspects
|
namespace Telegrator.Aspects
|
||||||
@@ -16,7 +13,8 @@ namespace Telegrator.Aspects
|
|||||||
/// Executes after the handler's main execution logic.
|
/// Executes after the handler's main execution logic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The handler container containing the current update and context.</param>
|
/// <param name="container">The handler container containing the current update and context.</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A <see cref="Result"/> indicating the final execution result.</returns>
|
/// <returns>A <see cref="Result"/> indicating the final execution result.</returns>
|
||||||
public Task<Result> AfterExecution(IHandlerContainer container);
|
public Task<Result> AfterExecution(IHandlerContainer container, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using Telegrator.Handlers;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Telegrator.Handlers;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
|
|
||||||
namespace Telegrator.Aspects
|
namespace Telegrator.Aspects
|
||||||
@@ -16,7 +13,8 @@ namespace Telegrator.Aspects
|
|||||||
/// Executes before the handler's main execution logic.
|
/// Executes before the handler's main execution logic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The handler container containing the current update and context.</param>
|
/// <param name="container">The handler container containing the current update and context.</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A <see cref="Result"/> indicating whether execution should continue or be stopped.</returns>
|
/// <returns>A <see cref="Result"/> indicating whether execution should continue or be stopped.</returns>
|
||||||
public Task<Result> BeforeExecution(IHandlerContainer container);
|
public Task<Result> BeforeExecution(IHandlerContainer container, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegrator.Filters.Components;
|
using Telegrator.Filters.Components;
|
||||||
using Telegrator.Handlers.Components;
|
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
@@ -12,51 +11,26 @@ namespace Telegrator.Handlers
|
|||||||
/// Provides access to the update, client, filters, and other execution context.
|
/// Provides access to the update, client, filters, and other execution context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TUpdate">The type of update being handled.</typeparam>
|
/// <typeparam name="TUpdate">The type of update being handled.</typeparam>
|
||||||
public class AbstractHandlerContainer<TUpdate> : IAbstractHandlerContainer<TUpdate> where TUpdate : class
|
public class AbstractHandlerContainer<TUpdate>(DescribedHandlerInfo handlerInfo) : IAbstractHandlerContainer<TUpdate> where TUpdate : class
|
||||||
{
|
{
|
||||||
private readonly TUpdate _actualUpdate;
|
|
||||||
private readonly Update _handlingUpdate;
|
|
||||||
private readonly ITelegramBotClient _client;
|
|
||||||
private readonly Dictionary<string, object> _extraData;
|
|
||||||
private readonly CompletedFiltersList _completedFilters;
|
|
||||||
private readonly IAwaitingProvider _awaitingProvider;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the actual update object of type TUpdate.
|
/// Gets the actual update object of type TUpdate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TUpdate ActualUpdate => _actualUpdate;
|
public TUpdate ActualUpdate { get; } = handlerInfo.HandlingUpdate.GetActualUpdateObject<TUpdate>();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Update HandlingUpdate => _handlingUpdate;
|
public Update HandlingUpdate { get; } = handlerInfo.HandlingUpdate;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ITelegramBotClient Client => _client;
|
public ITelegramBotClient Client { get; } = handlerInfo.Client;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Dictionary<string, object> ExtraData => _extraData;
|
public Dictionary<string, object> ExtraData { get; } = handlerInfo.ExtraData;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public CompletedFiltersList CompletedFilters => _completedFilters;
|
public CompletedFiltersList CompletedFilters { get; } = handlerInfo.CompletedFilters;
|
||||||
|
|
||||||
/// <inheritdoc cref="IHandlerContainer.AwaitingProvider"/>
|
|
||||||
public IAwaitingProvider AwaitingProvider => _awaitingProvider;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IAwaitingProvider IHandlerContainer.AwaitingProvider => AwaitingProvider;
|
public IAwaitingProvider AwaitingProvider { get; } = handlerInfo.AwaitingProvider;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="AbstractHandlerContainer{TUpdate}"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="awaitingProvider">The awaiting provider for managing async operations.</param>
|
|
||||||
/// <param name="handlerInfo">The handler information containing execution context.</param>
|
|
||||||
public AbstractHandlerContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo)
|
|
||||||
{
|
|
||||||
_actualUpdate = handlerInfo.HandlingUpdate.GetActualUpdateObject<TUpdate>();
|
|
||||||
_handlingUpdate = handlerInfo.HandlingUpdate;
|
|
||||||
_client = handlerInfo.Client;
|
|
||||||
_extraData = handlerInfo.ExtraData;
|
|
||||||
_completedFilters = handlerInfo.CompletedFilters;
|
|
||||||
_awaitingProvider = awaitingProvider;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,9 @@ namespace Telegrator.Handlers.Building
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a handler container for this awaiter handler.
|
/// Creates a handler container for this awaiter handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_">The awaiting provider (unused).</param>
|
|
||||||
/// <param name="describedHandler">The handler information containing the update.</param>
|
/// <param name="describedHandler">The handler information containing the update.</param>
|
||||||
/// <returns>An empty handler container.</returns>
|
/// <returns>An empty handler container.</returns>
|
||||||
public IHandlerContainer CreateContainer(IAwaitingProvider _, DescribedHandlerInfo describedHandler)
|
public IHandlerContainer CreateContainer(DescribedHandlerInfo describedHandler)
|
||||||
{
|
{
|
||||||
HandlingUpdate = describedHandler.HandlingUpdate;
|
HandlingUpdate = describedHandler.HandlingUpdate;
|
||||||
return new EmptyHandlerContainer();
|
return new EmptyHandlerContainer();
|
||||||
|
|||||||
@@ -60,12 +60,11 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a handler container for the specified awaiting provider and handler info.
|
/// Creates a handler container for the specified awaiting provider and handler info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="awaitingProvider">The awaiting provider.</param>
|
|
||||||
/// <param name="handlerInfo">The handler descriptor info.</param>
|
/// <param name="handlerInfo">The handler descriptor info.</param>
|
||||||
/// <returns>The created handler container.</returns>
|
/// <returns>The created handler container.</returns>
|
||||||
public virtual IHandlerContainer CreateContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo)
|
public virtual IHandlerContainer CreateContainer(DescribedHandlerInfo handlerInfo)
|
||||||
{
|
{
|
||||||
return new AbstractHandlerContainer<TUpdate>(awaitingProvider, handlerInfo);
|
return new AbstractHandlerContainer<TUpdate>(handlerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -103,13 +103,12 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a handler container for this branching handler.
|
/// Creates a handler container for this branching handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="awaitingProvider">The awaiting provider for the container.</param>
|
|
||||||
/// <param name="handlerInfo">The handler information.</param>
|
/// <param name="handlerInfo">The handler information.</param>
|
||||||
/// <returns>A handler container for this branching handler.</returns>
|
/// <returns>A handler container for this branching handler.</returns>
|
||||||
/// <exception cref="Exception">Thrown when the awaiting provider is not of the expected type.</exception>
|
/// <exception cref="Exception">Thrown when the awaiting provider is not of the expected type.</exception>
|
||||||
public override IHandlerContainer CreateContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo)
|
public override IHandlerContainer CreateContainer(DescribedHandlerInfo handlerInfo)
|
||||||
{
|
{
|
||||||
return new AbstractHandlerContainer<TUpdate>(awaitingProvider, handlerInfo);
|
return new AbstractHandlerContainer<TUpdate>(handlerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -12,9 +12,8 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="IHandlerContainer"/> for the specified awaiting provider and handler info.
|
/// Creates a new <see cref="IHandlerContainer"/> for the specified awaiting provider and handler info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="awaitingProvider">The <see cref="IAwaitingProvider"/> to use.</param>
|
|
||||||
/// <param name="handlerInfo">The <see cref="DescribedHandlerInfo"/> for the handler.</param>
|
/// <param name="handlerInfo">The <see cref="DescribedHandlerInfo"/> for the handler.</param>
|
||||||
/// <returns>A new <see cref="IHandlerContainer"/> instance.</returns>
|
/// <returns>A new <see cref="IHandlerContainer"/> instance.</returns>
|
||||||
public IHandlerContainer CreateContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo);
|
public IHandlerContainer CreateContainer(DescribedHandlerInfo handlerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
using Telegram.Bot.Types.Enums;
|
using System.ComponentModel;
|
||||||
|
using System.Threading;
|
||||||
|
using Telegram.Bot.Polling;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
using Telegrator.Polling;
|
||||||
|
|
||||||
namespace Telegrator.Handlers.Components
|
namespace Telegrator.Handlers.Components
|
||||||
{
|
{
|
||||||
@@ -21,14 +26,57 @@ namespace Telegrator.Handlers.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the handler logic and marks the lifetime as ended after execution.
|
/// Executes the handler logic and marks the lifetime as ended after execution.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The <see cref="IHandlerContainer"/> for the update.</param>
|
/// <param name="described"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public async Task<Result> Execute(IHandlerContainer container, CancellationToken cancellationToken = default)
|
public async Task<Result> Execute(DescribedHandlerInfo described, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
if (LifetimeToken.IsEnded)
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await ExecuteInternal(container, cancellationToken);
|
// Creating container
|
||||||
|
IHandlerContainer container = GetContainer(described);
|
||||||
|
DescriptorAspectsSet? aspects = described.From.Aspects;
|
||||||
|
|
||||||
|
// Executing pre processor
|
||||||
|
if (aspects != null)
|
||||||
|
{
|
||||||
|
Result? preResult = await aspects.ExecutePre(this, container, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (!preResult.Positive)
|
||||||
|
return preResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executing handler
|
||||||
|
Result execResult = await ExecuteInternal(container, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (!execResult.Positive)
|
||||||
|
return execResult;
|
||||||
|
|
||||||
|
// Executing post processor
|
||||||
|
if (aspects != null)
|
||||||
|
{
|
||||||
|
Result postResult = await aspects.ExecutePost(this, container, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (!postResult.Positive)
|
||||||
|
return postResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return Result.Ok();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// Cancelled
|
||||||
|
_ = 0xBAD + 0xC0DE;
|
||||||
|
return Result.Ok();
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
await described.UpdateRouter
|
||||||
|
.HandleErrorAsync(described.Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return Result.Fault();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -36,6 +84,17 @@ namespace Telegrator.Handlers.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IHandlerContainer GetContainer(DescribedHandlerInfo handlerInfo)
|
||||||
|
{
|
||||||
|
if (this is IHandlerContainerFactory handlerDefainedContainerFactory)
|
||||||
|
return handlerDefainedContainerFactory.CreateContainer(handlerInfo);
|
||||||
|
|
||||||
|
if (handlerInfo.UpdateRouter.DefaultContainerFactory is not null)
|
||||||
|
return handlerInfo.UpdateRouter.DefaultContainerFactory.CreateContainer(handlerInfo);
|
||||||
|
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the handler logic for the given container and cancellation token.
|
/// Executes the handler logic for the given container and cancellation token.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly IUpdateRouter UpdateRouter;
|
public readonly IUpdateRouter UpdateRouter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The awaiting provider to fetch new updates inside handler
|
||||||
|
/// </summary>
|
||||||
|
public readonly IAwaitingProvider AwaitingProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Telegram bot client used for this handler.
|
/// The Telegram bot client used for this handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -52,11 +57,6 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public HandlerLifetimeToken HandlerLifetime => HandlerInstance.LifetimeToken;
|
public HandlerLifetimeToken HandlerLifetime => HandlerInstance.LifetimeToken;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The handler container created during execution.
|
|
||||||
/// </summary>
|
|
||||||
public IHandlerContainer? HandlerContainer { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Display string for the handler (for debugging or logging).
|
/// Display string for the handler (for debugging or logging).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -66,87 +66,27 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// Initializes a new instance of the <see cref="DescribedHandlerInfo"/> class.
|
/// Initializes a new instance of the <see cref="DescribedHandlerInfo"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fromDescriptor">descriptor from that handler was described from</param>
|
/// <param name="fromDescriptor">descriptor from that handler was described from</param>
|
||||||
|
/// <param name="awaitingProvider"></param>
|
||||||
/// <param name="updateRouter">The update router.</param>
|
/// <param name="updateRouter">The update router.</param>
|
||||||
/// <param name="client">The Telegram bot client.</param>
|
/// <param name="client">The Telegram bot client.</param>
|
||||||
/// <param name="handlerInstance">The handler instance.</param>
|
/// <param name="handlerInstance">The handler instance.</param>
|
||||||
/// <param name="filterContext">The filter execution context.</param>
|
/// <param name="filterContext">The filter execution context.</param>
|
||||||
/// <param name="displayString">Optional display string.</param>
|
/// <param name="displayString">Optional display string.</param>
|
||||||
public DescribedHandlerInfo(HandlerDescriptor fromDescriptor, IUpdateRouter updateRouter, ITelegramBotClient client, UpdateHandlerBase handlerInstance, FilterExecutionContext<Update> filterContext, string? displayString)
|
public DescribedHandlerInfo(HandlerDescriptor fromDescriptor, IUpdateRouter updateRouter, IAwaitingProvider awaitingProvider, ITelegramBotClient client, UpdateHandlerBase handlerInstance, FilterExecutionContext<Update> filterContext, string? displayString)
|
||||||
{
|
{
|
||||||
From = fromDescriptor;
|
From = fromDescriptor;
|
||||||
UpdateRouter = updateRouter;
|
UpdateRouter = updateRouter;
|
||||||
|
AwaitingProvider = awaitingProvider;
|
||||||
Client = client;
|
Client = client;
|
||||||
HandlerInstance = handlerInstance;
|
HandlerInstance = handlerInstance;
|
||||||
ExtraData = filterContext.Data;
|
ExtraData = filterContext.Data;
|
||||||
CompletedFilters = filterContext.CompletedFilters;
|
CompletedFilters = filterContext.CompletedFilters;
|
||||||
HandlingUpdate = filterContext.Update;
|
HandlingUpdate = filterContext.Update;
|
||||||
DisplayString = displayString ?? handlerInstance.GetType().Name;
|
DisplayString = displayString ?? fromDescriptor.HandlerType.Name;
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Executes the handler logic asynchronously.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cancellationToken">Cancellation token.</param>
|
|
||||||
/// <returns>A task representing the asynchronous operation.</returns>
|
|
||||||
/// <exception cref="Exception">Thrown if the handler lifetime has ended or the handler is not a container factory.</exception>
|
|
||||||
public async Task<Result> Execute(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (HandlerLifetime.IsEnded)
|
|
||||||
throw new Exception();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HandlerContainer = GetContainer(UpdateRouter.AwaitingProvider, this);
|
|
||||||
|
|
||||||
if (From.Aspects != null)
|
|
||||||
{
|
|
||||||
Result preResult = await From.Aspects.ExecutePre(HandlerInstance, HandlerContainer);
|
|
||||||
if (!preResult.Positive)
|
|
||||||
return preResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result execResult = await HandlerInstance.Execute(HandlerContainer, cancellationToken);
|
|
||||||
if (!execResult.Positive)
|
|
||||||
return execResult;
|
|
||||||
|
|
||||||
if (From.Aspects != null)
|
|
||||||
{
|
|
||||||
Result postResult = await From.Aspects.ExecutePost(HandlerInstance, HandlerContainer);
|
|
||||||
if (!postResult.Positive)
|
|
||||||
return postResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result.Ok();
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
// Cancelled
|
|
||||||
_ = 0xBAD + 0xC0DE;
|
|
||||||
return Result.Ok();
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
await UpdateRouter
|
|
||||||
.HandleErrorAsync(Client, exception, HandleErrorSource.HandleUpdateError, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
return Result.Fault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IHandlerContainer GetContainer(IAwaitingProvider awaitingProvider, DescribedHandlerInfo handlerInfo)
|
|
||||||
{
|
|
||||||
if (HandlerInstance is IHandlerContainerFactory handlerDefainedContainerFactory)
|
|
||||||
return handlerDefainedContainerFactory.CreateContainer(awaitingProvider, handlerInfo);
|
|
||||||
|
|
||||||
if (UpdateRouter.DefaultContainerFactory is not null)
|
|
||||||
return UpdateRouter.DefaultContainerFactory.CreateContainer(awaitingProvider, handlerInfo);
|
|
||||||
|
|
||||||
throw new Exception();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
=> DisplayString ?? HandlerInstance.GetType().Name;
|
=> DisplayString ?? From.HandlerType.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,22 +51,22 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handler">The handler instance.</param>
|
/// <param name="handler">The handler instance.</param>
|
||||||
/// <param name="container">The handler container with update context.</param>
|
/// <param name="container">The handler container with update context.</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A <see cref="Result"/> indicating whether execution should continue.</returns>
|
/// <returns>A <see cref="Result"/> indicating whether execution should continue.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Thrown when handler claims to implement <see cref="IPreProcessor"/> but doesn't.</exception>
|
/// <exception cref="InvalidOperationException">Thrown when handler claims to implement <see cref="IPreProcessor"/> but doesn't.</exception>
|
||||||
public async Task<Result> ExecutePre(UpdateHandlerBase handler, IHandlerContainer container)
|
public async Task<Result> ExecutePre(UpdateHandlerBase handler, IHandlerContainer container, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (SelfPre)
|
if (SelfPre)
|
||||||
{
|
{
|
||||||
if (handler is not IPreProcessor preProcessor)
|
if (handler is not IPreProcessor preProcessor)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
return await preProcessor.BeforeExecution(container);
|
return await preProcessor.BeforeExecution(container, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
else if (TypedPre != null)
|
||||||
if (TypedPre != null)
|
|
||||||
{
|
{
|
||||||
IPreProcessor preProcessor = (IPreProcessor)Activator.CreateInstance(TypedPre);
|
IPreProcessor preProcessor = (IPreProcessor)Activator.CreateInstance(TypedPre);
|
||||||
return await preProcessor.BeforeExecution(container);
|
return await preProcessor.BeforeExecution(container, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.Ok();
|
return Result.Ok();
|
||||||
@@ -77,22 +77,22 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handler">The handler instance.</param>
|
/// <param name="handler">The handler instance.</param>
|
||||||
/// <param name="container">The handler container with update context.</param>
|
/// <param name="container">The handler container with update context.</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A <see cref="Result"/> indicating the final execution result.</returns>
|
/// <returns>A <see cref="Result"/> indicating the final execution result.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Thrown when handler claims to implement <see cref="IPostProcessor"/> but doesn't.</exception>
|
/// <exception cref="InvalidOperationException">Thrown when handler claims to implement <see cref="IPostProcessor"/> but doesn't.</exception>
|
||||||
public async Task<Result> ExecutePost(UpdateHandlerBase handler, IHandlerContainer container)
|
public async Task<Result> ExecutePost(UpdateHandlerBase handler, IHandlerContainer container, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (SelfPost)
|
if (SelfPost)
|
||||||
{
|
{
|
||||||
if (handler is not IPostProcessor postProcessor)
|
if (handler is not IPostProcessor postProcessor)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
return await postProcessor.AfterExecution(container);
|
return await postProcessor.AfterExecution(container, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
else if (TypedPost != null)
|
||||||
if (TypedPost != null)
|
|
||||||
{
|
{
|
||||||
IPostProcessor postProcessor = (IPostProcessor)Activator.CreateInstance(TypedPost);
|
IPostProcessor postProcessor = (IPostProcessor)Activator.CreateInstance(TypedPost);
|
||||||
return await postProcessor.AfterExecution(container);
|
return await postProcessor.AfterExecution(container, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.Ok();
|
return Result.Ok();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Telegrator.Handlers;
|
using Telegrator.Handlers;
|
||||||
|
using Telegrator.Logging;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ namespace Telegrator.Polling
|
|||||||
{
|
{
|
||||||
if (lastResult?.NextType != null)
|
if (lastResult?.NextType != null)
|
||||||
{
|
{
|
||||||
if (lastResult.NextType != handlerInfo.HandlerInstance.GetType())
|
if (lastResult.NextType != handlerInfo.From.HandlerType)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,9 +77,16 @@ namespace Telegrator.Polling
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Alligator.LogDebug("Described handler '{0}'", handlerInfo.DisplayString);
|
||||||
HandlerExecuting?.Invoke(handlerInfo);
|
HandlerExecuting?.Invoke(handlerInfo);
|
||||||
lastResult = await handlerInfo.Execute(GlobalCancellationToken);
|
|
||||||
|
lastResult = await handlerInfo.HandlerInstance.Execute(handlerInfo);
|
||||||
ExecutingHandlersSemaphore?.Release(1);
|
ExecutingHandlersSemaphore?.Release(1);
|
||||||
|
|
||||||
|
if (lastResult.RouteNext)
|
||||||
|
{
|
||||||
|
Alligator.LogDebug("Handler requested route continuation");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace Telegrator.Polling
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Getting handlers in update awaiting pool
|
// Getting handlers in update awaiting pool
|
||||||
IEnumerable<DescribedHandlerInfo> handlers = GetHandlers(AwaitingProvider, this, botClient, update, cancellationToken);
|
IEnumerable<DescribedHandlerInfo> handlers = GetHandlers(AwaitingProvider, botClient, update, cancellationToken);
|
||||||
if (handlers.Any())
|
if (handlers.Any())
|
||||||
{
|
{
|
||||||
// Enqueuing found awiting handlers
|
// Enqueuing found awiting handlers
|
||||||
@@ -121,7 +121,7 @@ namespace Telegrator.Polling
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Queuing reagular handlers for execution
|
// Queuing reagular handlers for execution
|
||||||
await HandlersPool.Enqueue(GetHandlers(HandlersProvider, this, botClient, update, cancellationToken));
|
await HandlersPool.Enqueue(GetHandlers(HandlersProvider, botClient, update, cancellationToken));
|
||||||
Alligator.LogDebug("Receiving Update ({0}) finished", update.Id);
|
Alligator.LogDebug("Receiving Update ({0}) finished", update.Id);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
@@ -140,12 +140,11 @@ namespace Telegrator.Polling
|
|||||||
/// Searches for handlers by update type, falling back to Unknown type if no specific handlers are found.
|
/// Searches for handlers by update type, falling back to Unknown type if no specific handlers are found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">The privode used to get handlers instance</param>
|
/// <param name="provider">The privode used to get handlers instance</param>
|
||||||
/// <param name="updateRouter">The update router for handler execution</param>
|
|
||||||
/// <param name="client">The Telegram bot client instance</param>
|
/// <param name="client">The Telegram bot client instance</param>
|
||||||
/// <param name="update">The incoming Telegram update to process</param>
|
/// <param name="update">The incoming Telegram update to process</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A collection of described handler information for the update</returns>
|
/// <returns>A collection of described handler information for the update</returns>
|
||||||
protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
Alligator.LogDebug("Requested handlers for UpdateType.{0}", update.Type);
|
Alligator.LogDebug("Requested handlers for UpdateType.{0}", update.Type);
|
||||||
if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors))
|
if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors))
|
||||||
@@ -164,7 +163,7 @@ namespace Telegrator.Polling
|
|||||||
//Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
//Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
||||||
//Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
//Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
||||||
|
|
||||||
return DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
return DescribeDescriptors(provider, descriptors, client, update, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -173,12 +172,11 @@ namespace Telegrator.Polling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">The privode used to get handlers instance</param>
|
/// <param name="provider">The privode used to get handlers instance</param>
|
||||||
/// <param name="descriptors">The list of handler descriptors to process</param>
|
/// <param name="descriptors">The list of handler descriptors to process</param>
|
||||||
/// <param name="updateRouter">The update router for handler execution</param>
|
|
||||||
/// <param name="client">The Telegram bot client instance</param>
|
/// <param name="client">The Telegram bot client instance</param>
|
||||||
/// <param name="update">The incoming Telegram update to process</param>
|
/// <param name="update">The incoming Telegram update to process</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>A collection of described handler information</returns>
|
/// <returns>A collection of described handler information</returns>
|
||||||
protected virtual IEnumerable<DescribedHandlerInfo> DescribeDescriptors(IHandlersProvider provider, HandlerDescriptorList descriptors, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
protected virtual IEnumerable<DescribedHandlerInfo> DescribeDescriptors(IHandlersProvider provider, HandlerDescriptorList descriptors, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -186,16 +184,11 @@ namespace Telegrator.Polling
|
|||||||
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
|
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
DescribedHandlerInfo? describedHandler = DescribeHandler(provider, descriptor, updateRouter, client, update, cancellationToken);
|
DescribedHandlerInfo? describedHandler = DescribeHandler(provider, descriptor, client, update, cancellationToken);
|
||||||
if (describedHandler == null)
|
if (describedHandler == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
yield return describedHandler;
|
yield return describedHandler;
|
||||||
|
|
||||||
/*
|
|
||||||
if (Options.ExecuteOnlyFirstFoundHanlder)
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -210,12 +203,11 @@ namespace Telegrator.Polling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">The privode used to get handlers instance</param>
|
/// <param name="provider">The privode used to get handlers instance</param>
|
||||||
/// <param name="descriptor">The handler descriptor to process</param>
|
/// <param name="descriptor">The handler descriptor to process</param>
|
||||||
/// <param name="updateRouter">The update router for handler execution</param>
|
|
||||||
/// <param name="client">The Telegram bot client instance</param>
|
/// <param name="client">The Telegram bot client instance</param>
|
||||||
/// <param name="update">The incoming Telegram update to process</param>
|
/// <param name="update">The incoming Telegram update to process</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns>The described handler info if validation passes; otherwise, null</returns>
|
/// <returns>The described handler info if validation passes; otherwise, null</returns>
|
||||||
public virtual DescribedHandlerInfo? DescribeHandler(IHandlersProvider provider, HandlerDescriptor descriptor, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
public virtual DescribedHandlerInfo? DescribeHandler(IHandlersProvider provider, HandlerDescriptor descriptor, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
Dictionary<string, object> data = new Dictionary<string, object>()
|
Dictionary<string, object> data = new Dictionary<string, object>()
|
||||||
@@ -228,7 +220,7 @@ namespace Telegrator.Polling
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
UpdateHandlerBase handlerInstance = provider.GetHandlerInstance(descriptor, cancellationToken);
|
UpdateHandlerBase handlerInstance = provider.GetHandlerInstance(descriptor, cancellationToken);
|
||||||
return new DescribedHandlerInfo(descriptor, updateRouter, client, handlerInstance, filterContext, descriptor.DisplayString);
|
return new DescribedHandlerInfo(descriptor, this, AwaitingProvider, client, handlerInstance, filterContext, descriptor.DisplayString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -844,8 +844,6 @@ namespace Telegrator
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static partial class ReflectionExtensions
|
public static partial class ReflectionExtensions
|
||||||
{
|
{
|
||||||
private static readonly BindingFlags BindAll = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type implements the <see cref="ICustomDescriptorsProvider"/> interface.
|
/// Checks if a type implements the <see cref="ICustomDescriptorsProvider"/> interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user