< Summary

Information
Class: TeleFlow.Telegram.Internal.Handlers.TelegramRuntimeDependencyValidator
Assembly: TeleFlow.Framework
File(s): /_/src/TeleFlow.Framework/Internal/Handlers/TelegramRuntimeDependencyValidator.cs
Line coverage
96%
Covered lines: 59
Uncovered lines: 2
Coverable lines: 61
Total lines: 127
Line coverage: 96.7%
Branch coverage
84%
Covered branches: 22
Total branches: 26
Branch coverage: 84.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Validate(...)75%4486.66%
ValidateHandlers(...)91.66%1212100%
ValidateErrorHandlers(...)87.5%88100%
GetCustomFilterTypes(...)100%11100%
FormatErrorHandler(...)100%11100%
FormatType(...)50%22100%

File(s)

/_/src/TeleFlow.Framework/Internal/Handlers/TelegramRuntimeDependencyValidator.cs

#LineLine coverage
 1using Microsoft.Extensions.DependencyInjection;
 2using TeleFlow.Framework.Application;
 3
 4namespace TeleFlow.Telegram.Internal.Handlers;
 5
 6/// <summary>
 7/// Validates Telegram handler metadata against the final DI service provider so missing method-parameter
 8/// services and custom filters fail before an update reaches the dispatcher hot path.
 9/// </summary>
 10internal sealed class TelegramRuntimeDependencyValidator : ITeleFlowRuntimeValidator
 11{
 12    public void Validate(IServiceProvider services)
 13    {
 11414        ArgumentNullException.ThrowIfNull(services);
 15
 11416        var serviceAvailability = services.GetService<IServiceProviderIsService>();
 17
 11418        if (serviceAvailability is null)
 19        {
 020            throw new TeleFlowConfigurationException(
 021                "TeleFlow runtime validation requires a Microsoft.Extensions.DependencyInjection service provider.");
 22        }
 23
 11424        var errors = new List<string>();
 25
 11426        ValidateHandlers(services, serviceAvailability, errors);
 11427        ValidateErrorHandlers(services, serviceAvailability, errors);
 28
 11429        if (errors.Count == 0)
 30        {
 10831            return;
 32        }
 33
 634        throw new TeleFlowConfigurationException(
 635            "TeleFlow configuration is invalid." +
 636            Environment.NewLine +
 637            Environment.NewLine +
 638            string.Join(Environment.NewLine + Environment.NewLine, errors));
 39    }
 40
 41    private static void ValidateHandlers(
 42        IServiceProvider services,
 43        IServiceProviderIsService serviceAvailability,
 44        List<string> errors)
 45    {
 70246        foreach (var handler in services.GetServices<TelegramHandlerDescriptor>())
 47        {
 87448            foreach (var parameter in handler.Parameters.Where(static parameter =>
 71849                         parameter.Kind == TelegramHandlerParameterKind.Service))
 50            {
 20051                if (!serviceAvailability.IsService(parameter.ParameterType))
 52                {
 453                    errors.Add(
 454                        "Handler dependency was not registered." +
 455                        Environment.NewLine +
 456                        $"Handler: {TelegramHandlerDescriptorFormatter.GetDisplayName(handler)}" +
 457                        Environment.NewLine +
 458                        $"Parameter: {parameter.Name ?? "<unnamed>"}" +
 459                        Environment.NewLine +
 460                        $"Service type: {FormatType(parameter.ParameterType)}" +
 461                        Environment.NewLine +
 462                        $"Register {FormatType(parameter.ParameterType)} in IServiceCollection before building the TeleF
 63                }
 64            }
 65
 49466            foreach (var filterType in GetCustomFilterTypes(handler))
 67            {
 1068                if (!serviceAvailability.IsService(filterType))
 69                {
 270                    errors.Add(
 271                        "Custom filter was not registered." +
 272                        Environment.NewLine +
 273                        $"Handler: {TelegramHandlerDescriptorFormatter.GetDisplayName(handler)}" +
 274                        Environment.NewLine +
 275                        $"Filter type: {FormatType(filterType)}" +
 276                        Environment.NewLine +
 277                        $"Register {FormatType(filterType)} in IServiceCollection before building the TeleFlow applicati
 78                }
 79            }
 80        }
 11481    }
 82
 83    private static void ValidateErrorHandlers(
 84        IServiceProvider services,
 85        IServiceProviderIsService serviceAvailability,
 86        List<string> errors)
 87    {
 27088        foreach (var handler in services.GetServices<TelegramErrorHandlerDescriptor>())
 89        {
 8090            foreach (var parameter in handler.Parameters.Where(static parameter =>
 7191                         parameter.Kind == TelegramErrorHandlerParameterKind.Service))
 92            {
 1993                if (!serviceAvailability.IsService(parameter.ParameterType))
 94                {
 195                    errors.Add(
 196                        "Error handler dependency was not registered." +
 197                        Environment.NewLine +
 198                        $"Error handler: {FormatErrorHandler(handler)}" +
 199                        Environment.NewLine +
 1100                        $"Parameter: {parameter.Name ?? "<unnamed>"}" +
 1101                        Environment.NewLine +
 1102                        $"Service type: {FormatType(parameter.ParameterType)}" +
 1103                        Environment.NewLine +
 1104                        $"Register {FormatType(parameter.ParameterType)} in IServiceCollection before building the TeleF
 105                }
 106            }
 107        }
 114108    }
 109
 110    private static IEnumerable<Type> GetCustomFilterTypes(TelegramHandlerDescriptor handler)
 111    {
 237112        return handler.Route.Filters
 94113            .Select(static filter => filter.CustomFilterType)
 237114            .OfType<Type>()
 237115            .Distinct();
 116    }
 117
 118    private static string FormatErrorHandler(TelegramErrorHandlerDescriptor handler)
 119    {
 1120        return $"{handler.HandlerType.FullName}.{handler.MethodName}";
 121    }
 122
 123    private static string FormatType(Type type)
 124    {
 14125        return type.FullName ?? type.Name;
 126    }
 127}