* Added "LazyInitialize" property to "HandlerDescriptor" to make post-creation operation (required for BranchingHandler)

* Tweaked "HandlersProvider" implementation to fit new HandlerDescriptor property
* Fixed "BranchingHandler"'s descriptor creation logic
This commit is contained in:
2025-07-28 03:53:13 +04:00
parent 5a93623469
commit 6a18d9765b
5 changed files with 51 additions and 37 deletions
@@ -49,6 +49,7 @@ namespace Telegrator.Hosting.Providers
if (handlerInstance is not UpdateHandlerBase updateHandler) if (handlerInstance is not UpdateHandlerBase updateHandler)
throw new InvalidOperationException("Failed to resolve " + descriptor.HandlerType + " as UpdateHandlerBase"); throw new InvalidOperationException("Failed to resolve " + descriptor.HandlerType + " as UpdateHandlerBase");
descriptor.LazyInitialization?.Invoke(updateHandler);
updateHandler.LifetimeToken.OnLifetimeEnded += _ => scope.Dispose(); updateHandler.LifetimeToken.OnLifetimeEnded += _ => scope.Dispose();
return updateHandler; return updateHandler;
} }
+8
View File
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Analyzers", "Telegrator.Analyzers\Telegrator.Analyzers.csproj", "{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Analyzers", "Telegrator.Analyzers\Telegrator.Analyzers.csproj", "{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.ConsoleHost", "..\Telegram.Reactive.TestApps\Telegrator.ConsoleHost\Telegrator.ConsoleHost.csproj", "{78691EF7-6009-3BB1-C90D-1D1D95442041}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU
@@ -55,6 +57,12 @@ Global
{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Release|Any CPU.ActiveCfg = Release|Any CPU {8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Release|Any CPU.Build.0 = Release|Any CPU {8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}.Release|Any CPU.Build.0 = Release|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.AnalyzersDebug|Any CPU.ActiveCfg = AnalyzersDebug|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.AnalyzersDebug|Any CPU.Build.0 = AnalyzersDebug|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -43,14 +43,6 @@ namespace Telegrator.Handlers.Components
protected BranchingUpdateHandler(UpdateType handlingUpdateType) protected BranchingUpdateHandler(UpdateType handlingUpdateType)
: base(handlingUpdateType) { } : base(handlingUpdateType) { }
/// <summary>
/// Initializes a new instance of the <see cref="BranchingUpdateHandler{TUpdate}"/> class with a specific branch method.
/// </summary>
/// <param name="handlingUpdateType">The type of update this handler processes.</param>
/// <param name="branch">The specific branch method to execute.</param>
protected BranchingUpdateHandler(UpdateType handlingUpdateType, MethodInfo branch)
: base(handlingUpdateType) => branchMethodInfo = branch;
/// <summary> /// <summary>
/// Describes all handler branches in this class. /// Describes all handler branches in this class.
/// </summary> /// </summary>
@@ -92,7 +84,7 @@ namespace Telegrator.Handlers.Components
{ {
handlerAttribute = HandlerInspector.GetHandlerAttribute(branch); handlerAttribute = HandlerInspector.GetHandlerAttribute(branch);
} }
finally catch
{ {
_ = 0xBAD + 0xC0DE; _ = 0xBAD + 0xC0DE;
} }
@@ -105,7 +97,7 @@ namespace Telegrator.Handlers.Components
HandlerInspector.GetStateKeeperAttribute(branch), HandlerInspector.GetStateKeeperAttribute(branch),
branchFiltersList.ToArray()); branchFiltersList.ToArray());
return new HandlerBranchDescriptor(branch, HandlingUpdateType, handlerAttribute.GetIndexer(), filtersSet); return new HandlerBranchDescriptor(thisType, branch, HandlingUpdateType, handlerAttribute.GetIndexer(), filtersSet);
} }
/// <summary> /// <summary>
@@ -160,15 +152,15 @@ namespace Telegrator.Handlers.Components
private class HandlerBranchDescriptor : HandlerDescriptor private class HandlerBranchDescriptor : HandlerDescriptor
{ {
public HandlerBranchDescriptor(MethodInfo method, UpdateType updateType, DescriptorIndexer indexer, DescriptorFiltersSet filters) public HandlerBranchDescriptor(Type decalringType, MethodInfo method, UpdateType updateType, DescriptorIndexer indexer, DescriptorFiltersSet filters) : base(DescriptorType.General, decalringType, updateType, indexer, filters)
: base(DescriptorType.General, method.DeclaringType, updateType, indexer, filters)
{ {
DisplayString = string.Format("{0}+{1}", method.DeclaringType.Name, method.Name); DisplayString = HandlerInspector.GetDisplayName(method) ?? string.Format("{0}+{1}", method.DeclaringType.Name, method.Name);
InstanceFactory = () => LazyInitialization = handler =>
{ {
BranchingUpdateHandler<TUpdate> handler = (BranchingUpdateHandler<TUpdate>)Activator.CreateInstance(method.DeclaringType); if (handler is not BranchingUpdateHandler<TUpdate> brancher)
handler.branchMethodInfo = method; throw new InvalidDataException();
return handler;
brancher.branchMethodInfo = method;
}; };
} }
} }
@@ -97,7 +97,7 @@ namespace Telegrator.MadiatorCore.Descriptors
public Func<UpdateHandlerBase>? InstanceFactory public Func<UpdateHandlerBase>? InstanceFactory
{ {
get; get;
set; private set;
} }
/// <summary> /// <summary>
@@ -118,6 +118,15 @@ namespace Telegrator.MadiatorCore.Descriptors
set; set;
} }
/// <summary>
/// Gets or sets a function for 'lazy' handlers initialization
/// </summary>
public Action<UpdateHandlerBase>? LazyInitialization
{
get;
set;
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="HandlerDescriptor"/> class with the specified descriptor type and handler type. /// Initializes a new instance of the <see cref="HandlerDescriptor"/> class with the specified descriptor type and handler type.
/// Automatically inspects the handler type to extract attributes, filters, and configuration. /// Automatically inspects the handler type to extract attributes, filters, and configuration.
+21 -17
View File
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.Enums;
using Telegrator.Configuration; using Telegrator.Configuration;
@@ -60,28 +61,31 @@ namespace Telegrator.Providers
public virtual UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default) public virtual UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
switch (descriptor.Type) bool useSingleton = UseSingleton(descriptor);
{
case DescriptorType.Implicit: if (useSingleton && descriptor.SingletonInstance != null)
case DescriptorType.Singleton: return descriptor.SingletonInstance;
{
return descriptor.SingletonInstance ??= (descriptor.InstanceFactory != null UpdateHandlerBase instance = GetHandlerInstanceInternal(descriptor);
? descriptor.SingletonInstance = descriptor.InstanceFactory.Invoke() descriptor.SingletonInstance = useSingleton ? instance : null;
: descriptor.SingletonInstance = (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType)); descriptor.LazyInitialization?.Invoke(instance);
return instance;
} }
case DescriptorType.Keyed: private static UpdateHandlerBase GetHandlerInstanceInternal(HandlerDescriptor descriptor)
case DescriptorType.General:
{ {
return descriptor.InstanceFactory == null if (descriptor.InstanceFactory != null)
? (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType) return descriptor.InstanceFactory.Invoke();
: descriptor.InstanceFactory.Invoke();
return (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType);
} }
default: private static bool UseSingleton(HandlerDescriptor descriptor) => descriptor.Type switch
throw new Exception(); {
} DescriptorType.General or DescriptorType.Keyed => false,
} DescriptorType.Implicit or DescriptorType.Singleton => true,
_ => throw new Exception()
};
/// <inheritdoc/> /// <inheritdoc/>
public virtual bool TryGetDescriptorList(UpdateType updateType, out HandlerDescriptorList? list) public virtual bool TryGetDescriptorList(UpdateType updateType, out HandlerDescriptorList? list)