* hotfix of aspects inspection

* Added IHandlersManager. interface that allows both collecting and providing handlers
This commit is contained in:
2025-08-19 12:10:40 +04:00
parent 6905045cde
commit 92df5e9c79
9 changed files with 168 additions and 16 deletions
+13 -9
View File
@@ -3,17 +3,14 @@ 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 Microsoft.Extensions.Options;
using System.Text;
using Telegram.Bot.Types.Enums;
using Telegrator.Configuration;
using Telegrator.Hosting.Components;
using Telegrator.Hosting.Providers;
using Telegrator.Hosting.Web.Components;
using Telegrator.Hosting.Logging;
using Telegrator.Logging;
using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors;
@@ -199,15 +196,22 @@ namespace Telegrator.Hosting.Web
Logger.LogInformation(logBuilder.ToString());
}
private void RegisterHostServices(IServiceCollection service, IHandlersCollection handlers)
private void RegisterHostServices(IServiceCollection services, IHandlersCollection handlers)
{
//service.RemoveAll<IHost>();
//service.AddSingleton<IHost>(this);
service.AddSingleton<ITelegramBotHost>(this);
service.AddSingleton<ITelegramBotWebHost>(this);
service.AddSingleton<ITelegratorBot>(this);
service.AddSingleton<IHandlersCollection>(handlers);
services.AddSingleton<ITelegramBotHost>(this);
services.AddSingleton<ITelegramBotWebHost>(this);
services.AddSingleton<ITelegratorBot>(this);
services.AddSingleton(handlers);
if (handlers is IHandlersManager manager)
{
services.RemoveAll<IHandlersProvider>();
services.AddSingleton<IHandlersProvider>(manager);
services.AddSingleton(manager);
}
}
}
}
@@ -15,7 +15,7 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>1.15.4</Version>
<Version>1.15.5</Version>
</PropertyGroup>
<ItemGroup>
+9 -1
View File
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Text;
@@ -159,7 +160,14 @@ namespace Telegrator.Hosting
services.AddSingleton<ITelegramBotHost>(this);
services.AddSingleton<ITelegratorBot>(this);
services.AddSingleton<IHandlersCollection>(handlers);
services.AddSingleton(handlers);
if (handlers is IHandlersManager manager)
{
services.RemoveAll<IHandlersProvider>();
services.AddSingleton<IHandlersProvider>(manager);
services.AddSingleton(manager);
}
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>1.15.4</Version>
<Version>1.15.5</Version>
</PropertyGroup>
<ItemGroup>
@@ -91,7 +91,7 @@ namespace Telegrator.MadiatorCore.Descriptors
public static DescriptorAspectsSet GetAspects(Type handlerType)
{
Type? typedPre = handlerType.GetCustomAttribute(typeof(BeforeExecutionAttribute<>))?.GetType().GetGenericArguments()[0];
Type? typedPost = handlerType.GetCustomAttribute(typeof(AfterExecutionAttribute<>)).GetType().GetGenericArguments()[0];
Type? typedPost = handlerType.GetCustomAttribute(typeof(AfterExecutionAttribute<>))?.GetType().GetGenericArguments()[0];
return new DescriptorAspectsSet(typedPre, typedPost);
}
}
@@ -0,0 +1,11 @@
namespace Telegrator.MadiatorCore
{
/// <summary>
/// Combines <see cref="IHandlersCollection"/> and <see cref="IHandlersProvider"/>.
/// Provides functionality of collecting, organizing and resolving handlers instances.
/// </summary>
public interface IHandlersManager : IHandlersCollection, IHandlersProvider
{
}
}
+3 -2
View File
@@ -74,8 +74,9 @@ namespace Telegrator.Providers
throw new Exception("This handler (" + descriptor.HandlerType.FullName + "), must contain constructor without parameters.");
_allowedTypes.UnionAdd(descriptor.UpdateType);
foreach (MightAwaitAttribute mightAwaits in descriptor.HandlerType.GetCustomAttributes<MightAwaitAttribute>())
_allowedTypes.UnionAdd(mightAwaits.UpdateTypes);
MightAwaitAttribute? mightAwait = descriptor.HandlerType.GetCustomAttribute<MightAwaitAttribute>();
if (mightAwait != null)
_allowedTypes.UnionAdd(mightAwait.UpdateTypes);
IntersectCommands(descriptor);
HandlerDescriptorList list = GetDescriptorList(descriptor);
+128
View File
@@ -0,0 +1,128 @@
using System.Reflection;
using Telegram.Bot.Types.Enums;
using Telegrator.Annotations;
using Telegrator.Attributes;
using Telegrator.Configuration;
using Telegrator.Handlers.Components;
using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors;
namespace Telegrator.Providers
{
/// <summary>
/// Provides functionality of incrementally collecting, organizing and resolving handlers instances.
/// Minimum implementation of <see cref="IHandlersManager"/>. Abstract class, still requires handler instance resolving.
/// </summary>
/// <param name="options"></param>
public abstract class HandlersManagerBase(ITelegratorOptions options) : IHandlersManager
{
/// <summary>
/// Dictionary that organizes handler descriptors by update type.
/// </summary>
protected readonly Dictionary<UpdateType, HandlerDescriptorList> _handlersDictionary = [];
/// <summary>
/// Gets the collection of Telegram.Bot.Types.Enums.UpdateType's allowed by registered handlers
/// </summary>
protected readonly List<UpdateType> _allowedTypes = [];
/// <summary>
/// Configuration options for handler collecting.
/// </summary>
protected readonly ITelegratorOptions? Options = options;
/// <summary>
/// Gets whether handlers must have a parameterless constructor.
/// </summary>
protected virtual bool MustHaveParameterlessCtor => true;
/// <summary>
/// List of command aliases that have been registered.
/// </summary>
public readonly List<string> CommandAliasses = [];
/// <inheritdoc/>
public HandlerDescriptorList this[UpdateType updateType] => _handlersDictionary[updateType];
/// <inheritdoc/>
public IEnumerable<UpdateType> AllowedTypes => _allowedTypes;
/// <inheritdoc/>
public IEnumerable<UpdateType> Keys => _handlersDictionary.Keys;
/// <inheritdoc/>
public IEnumerable<HandlerDescriptorList> Values => _handlersDictionary.Values;
/// <inheritdoc/>
public virtual IHandlersCollection AddDescriptor(HandlerDescriptor descriptor)
{
if (MustHaveParameterlessCtor && !descriptor.HandlerType.HasParameterlessCtor())
throw new Exception("This handler (" + descriptor.HandlerType.FullName + "), must contain constructor without parameters.");
_allowedTypes.UnionAdd([descriptor.UpdateType]);
MightAwaitAttribute? mightAwait = descriptor.HandlerType.GetCustomAttribute<MightAwaitAttribute>();
if (mightAwait != null)
_allowedTypes.UnionAdd(mightAwait.UpdateTypes);
IntersectCommands(descriptor);
HandlerDescriptorList list = GetDescriptorList(descriptor);
list.Add(descriptor);
return this;
}
/// <summary>
/// Gets the <see cref="HandlerDescriptorList"/> for the specified <see cref="HandlerDescriptor"/>.
/// </summary>
/// <param name="descriptor">The handler descriptor.</param>
/// <returns>The handler descriptor list containing the descriptor.</returns>
protected virtual HandlerDescriptorList GetDescriptorList(HandlerDescriptor descriptor)
{
UpdateType updateType = UpdateTypeExtensions.SuppressTypes.TryGetValue(descriptor.UpdateType, out UpdateType suppressType)
? suppressType : descriptor.UpdateType;
if (!_handlersDictionary.TryGetValue(updateType, out HandlerDescriptorList? list))
{
list = new HandlerDescriptorList(updateType, Options);
_handlersDictionary.Add(updateType, list);
}
return list;
}
/// <summary>
/// Checks for intersecting command aliases and handles them according to configuration.
/// </summary>
/// <param name="descriptor">The handler descriptor to check for command aliases.</param>
/// <exception cref="Exception">Thrown when intersecting command aliases are found and ExceptIntersectingCommandAliases is enabled.</exception>
protected virtual void IntersectCommands(HandlerDescriptor descriptor)
{
if (Options == null || !Options.ExceptIntersectingCommandAliases)
return;
CommandAlliasAttribute? alliasAttribute = descriptor.HandlerType.GetCustomAttribute<CommandAlliasAttribute>();
if (alliasAttribute == null)
return;
if (CommandAliasses.Intersect(alliasAttribute.Alliases, StringComparer.InvariantCultureIgnoreCase).Any())
throw new Exception(descriptor.HandlerType.FullName);
CommandAliasses.AddRange(alliasAttribute.Alliases);
}
/// <inheritdoc/>
public bool TryGetDescriptorList(UpdateType updateType, out HandlerDescriptorList? list)
{
return _handlersDictionary.TryGetValue(updateType, out list);
}
/// <inheritdoc/>
public bool IsEmpty()
{
return _handlersDictionary.Any(pair => pair.Value.Count != 0);
}
/// <inheritdoc/>
public abstract UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default);
}
}
+1 -1
View File
@@ -17,7 +17,7 @@
<PackageTags>telegram;bot;mediator;attributes;aspect;hosting;host;framework;easy;simple;handlers</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>1.15.4</Version>
<Version>1.15.5</Version>
</PropertyGroup>
<ItemGroup>