diff --git a/Telegrator.Hosting/Providers/HostHandlersProvider.cs b/Telegrator.Hosting/Providers/HostHandlersProvider.cs
index 167737b..8204fd2 100644
--- a/Telegrator.Hosting/Providers/HostHandlersProvider.cs
+++ b/Telegrator.Hosting/Providers/HostHandlersProvider.cs
@@ -49,6 +49,7 @@ namespace Telegrator.Hosting.Providers
if (handlerInstance is not UpdateHandlerBase updateHandler)
throw new InvalidOperationException("Failed to resolve " + descriptor.HandlerType + " as UpdateHandlerBase");
+ descriptor.LazyInitialization?.Invoke(updateHandler);
updateHandler.LifetimeToken.OnLifetimeEnded += _ => scope.Dispose();
return updateHandler;
}
diff --git a/Telegrator.sln b/Telegrator.sln
index 0f9d08f..84f7362 100644
--- a/Telegrator.sln
+++ b/Telegrator.sln
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Analyzers", "Telegrator.Analyzers\Telegrator.Analyzers.csproj", "{8B6A32EA-ECF7-4CAB-A1E5-2392063C986D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.ConsoleHost", "..\Telegram.Reactive.TestApps\Telegrator.ConsoleHost\Telegrator.ConsoleHost.csproj", "{78691EF7-6009-3BB1-C90D-1D1D95442041}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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}.Release|Any CPU.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Telegrator/Handlers/Components/BranchingUpdateHandler.cs b/Telegrator/Handlers/Components/BranchingUpdateHandler.cs
index 0352127..a8b6108 100644
--- a/Telegrator/Handlers/Components/BranchingUpdateHandler.cs
+++ b/Telegrator/Handlers/Components/BranchingUpdateHandler.cs
@@ -43,14 +43,6 @@ namespace Telegrator.Handlers.Components
protected BranchingUpdateHandler(UpdateType handlingUpdateType)
: base(handlingUpdateType) { }
- ///
- /// Initializes a new instance of the class with a specific branch method.
- ///
- /// The type of update this handler processes.
- /// The specific branch method to execute.
- protected BranchingUpdateHandler(UpdateType handlingUpdateType, MethodInfo branch)
- : base(handlingUpdateType) => branchMethodInfo = branch;
-
///
/// Describes all handler branches in this class.
///
@@ -92,7 +84,7 @@ namespace Telegrator.Handlers.Components
{
handlerAttribute = HandlerInspector.GetHandlerAttribute(branch);
}
- finally
+ catch
{
_ = 0xBAD + 0xC0DE;
}
@@ -105,7 +97,7 @@ namespace Telegrator.Handlers.Components
HandlerInspector.GetStateKeeperAttribute(branch),
branchFiltersList.ToArray());
- return new HandlerBranchDescriptor(branch, HandlingUpdateType, handlerAttribute.GetIndexer(), filtersSet);
+ return new HandlerBranchDescriptor(thisType, branch, HandlingUpdateType, handlerAttribute.GetIndexer(), filtersSet);
}
///
@@ -160,15 +152,15 @@ namespace Telegrator.Handlers.Components
private class HandlerBranchDescriptor : HandlerDescriptor
{
- public HandlerBranchDescriptor(MethodInfo method, UpdateType updateType, DescriptorIndexer indexer, DescriptorFiltersSet filters)
- : base(DescriptorType.General, method.DeclaringType, updateType, indexer, filters)
+ public HandlerBranchDescriptor(Type decalringType, MethodInfo method, UpdateType updateType, DescriptorIndexer indexer, DescriptorFiltersSet filters) : base(DescriptorType.General, decalringType, updateType, indexer, filters)
{
- DisplayString = string.Format("{0}+{1}", method.DeclaringType.Name, method.Name);
- InstanceFactory = () =>
+ DisplayString = HandlerInspector.GetDisplayName(method) ?? string.Format("{0}+{1}", method.DeclaringType.Name, method.Name);
+ LazyInitialization = handler =>
{
- BranchingUpdateHandler handler = (BranchingUpdateHandler)Activator.CreateInstance(method.DeclaringType);
- handler.branchMethodInfo = method;
- return handler;
+ if (handler is not BranchingUpdateHandler brancher)
+ throw new InvalidDataException();
+
+ brancher.branchMethodInfo = method;
};
}
}
diff --git a/Telegrator/MadiatorCore/Descriptors/HandlerDescriptor.cs b/Telegrator/MadiatorCore/Descriptors/HandlerDescriptor.cs
index 8de3142..6ceb42a 100644
--- a/Telegrator/MadiatorCore/Descriptors/HandlerDescriptor.cs
+++ b/Telegrator/MadiatorCore/Descriptors/HandlerDescriptor.cs
@@ -97,7 +97,7 @@ namespace Telegrator.MadiatorCore.Descriptors
public Func? InstanceFactory
{
get;
- set;
+ private set;
}
///
@@ -118,6 +118,15 @@ namespace Telegrator.MadiatorCore.Descriptors
set;
}
+ ///
+ /// Gets or sets a function for 'lazy' handlers initialization
+ ///
+ public Action? LazyInitialization
+ {
+ get;
+ set;
+ }
+
///
/// Initializes a new instance of the class with the specified descriptor type and handler type.
/// Automatically inspects the handler type to extract attributes, filters, and configuration.
diff --git a/Telegrator/Providers/HandlersProvider.cs b/Telegrator/Providers/HandlersProvider.cs
index 73dbf79..fed5f5f 100644
--- a/Telegrator/Providers/HandlersProvider.cs
+++ b/Telegrator/Providers/HandlersProvider.cs
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
+using System.Runtime.CompilerServices;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegrator.Configuration;
@@ -60,29 +61,32 @@ namespace Telegrator.Providers
public virtual UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
- switch (descriptor.Type)
- {
- case DescriptorType.Implicit:
- case DescriptorType.Singleton:
- {
- return descriptor.SingletonInstance ??= (descriptor.InstanceFactory != null
- ? descriptor.SingletonInstance = descriptor.InstanceFactory.Invoke()
- : descriptor.SingletonInstance = (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType));
- }
+ bool useSingleton = UseSingleton(descriptor);
- case DescriptorType.Keyed:
- case DescriptorType.General:
- {
- return descriptor.InstanceFactory == null
- ? (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType)
- : descriptor.InstanceFactory.Invoke();
- }
+ if (useSingleton && descriptor.SingletonInstance != null)
+ return descriptor.SingletonInstance;
- default:
- throw new Exception();
- }
+ UpdateHandlerBase instance = GetHandlerInstanceInternal(descriptor);
+ descriptor.SingletonInstance = useSingleton ? instance : null;
+ descriptor.LazyInitialization?.Invoke(instance);
+ return instance;
}
+ private static UpdateHandlerBase GetHandlerInstanceInternal(HandlerDescriptor descriptor)
+ {
+ if (descriptor.InstanceFactory != null)
+ return descriptor.InstanceFactory.Invoke();
+
+ return (UpdateHandlerBase)Activator.CreateInstance(descriptor.HandlerType);
+ }
+
+ private static bool UseSingleton(HandlerDescriptor descriptor) => descriptor.Type switch
+ {
+ DescriptorType.General or DescriptorType.Keyed => false,
+ DescriptorType.Implicit or DescriptorType.Singleton => true,
+ _ => throw new Exception()
+ };
+
///
public virtual bool TryGetDescriptorList(UpdateType updateType, out HandlerDescriptorList? list)
{