Fix error with broken dependencies.

This commit is contained in:
Dmitri Shimanski
2025-03-21 00:49:01 +02:00
parent f82f5cd291
commit 3094fcbabe
7 changed files with 108 additions and 104 deletions

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Telegram.Net; using Telegram.Net;
@@ -7,12 +8,11 @@ var webHost = Host.CreateDefaultBuilder()
.ConfigureLogging(l => l.ClearProviders().AddConsole()) .ConfigureLogging(l => l.ClearProviders().AddConsole())
.ConfigureServices(k => .ConfigureServices(k =>
{ {
k.ConnectTelegram(new("TOKEN") var _conf = new ConfigurationBuilder()
{ .AddJsonFile("appsettings.json")
errorHandler = async (client, exception, ctx) => .AddEnvironmentVariables()
{ .Build();
Console.WriteLine(exception); k.AddSingleton(_conf);
} k.ConnectTelegram(new(_conf.GetValue<string>("telegram_test_token")));
});
}); });
webHost.Build().Run(); webHost.Build().Run();

View File

@@ -11,6 +11,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<ProjectReference Include="..\..\Telegram.Net\Telegram.Net.csproj" /> <ProjectReference Include="..\..\Telegram.Net\Telegram.Net.csproj" />
<None CopyToOutputDirectory="Always" Include="appsettings.json"></None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,4 +1,5 @@
using Telegram.Bot; using Microsoft.Extensions.Configuration;
using Telegram.Bot;
using Telegram.Bot.Types; using Telegram.Bot.Types;
using Telegram.Net.Attributes; using Telegram.Net.Attributes;
using Telegram.Net.Interfaces; using Telegram.Net.Interfaces;
@@ -7,6 +8,11 @@ namespace Telegram.Examples.UpdatePolling;
public class Update : IUpdatePollingService public class Update : IUpdatePollingService
{ {
private static IConfiguration _conf;
public Update(IConfiguration conf)
{
_conf = conf;
}
[Update] [Update]
public async Task UpdateExample(ITelegramBotClient client, Bot.Types.Update update, CancellationToken ctx) public async Task UpdateExample(ITelegramBotClient client, Bot.Types.Update update, CancellationToken ctx)
{ {
@@ -31,6 +37,12 @@ public class Update : IUpdatePollingService
await client.SendMessage(message.From!.Id, "Hello, I`m example bot.", cancellationToken: ctx); await client.SendMessage(message.From!.Id, "Hello, I`m example bot.", cancellationToken: ctx);
} }
[Command("/test_conf")]
public async Task TestConfigurationBuilder(ITelegramBotClient client, Message message, CancellationToken cts)
{
await client.SendMessage(message.Chat.Id, _conf.GetValue<string>("ExampleMessage") ?? throw new Exception("Not found"));
}
[EditMessage] [EditMessage]
public async Task EditMessageExmaple(ITelegramBotClient client, Message message, CancellationToken ctx) public async Task EditMessageExmaple(ITelegramBotClient client, Message message, CancellationToken ctx)
{ {

View File

@@ -0,0 +1,4 @@
{
"ExampleMessage": "Test!",
"telegram_test_token": "PROVIDE_TOKEN"
}

View File

@@ -20,6 +20,20 @@ Ensure you have the required dependencies installed:
## Usage ## Usage
### Provide dependencies in class
You can provide dependencies in class from constructor, and after it use it like `static`.
```csharp
public class Example : IUpdatePollingService
{
private static MyCoolService _service; // It should to be static!
public Example(MyCoolService service)
{
_service = service;
}
}
```
### Inline Query Handling ### Inline Query Handling
Use the `InlineAttribute` to register a method as an inline query handler. Use the `InlineAttribute` to register a method as an inline query handler.
@@ -87,4 +101,4 @@ public static async Task HandleUpdate(ITelegramBotClient bot, Update update, Can
``` ```
## License ## License
This project is open-source and available under the MIT License. This project is open-source and available under the [Apache 2.0 license](LICENSE)

View File

@@ -9,6 +9,8 @@ using Telegram.Bot.Types;
using Telegram.Bot.Types.Payments; using Telegram.Bot.Types.Payments;
using Telegram.Net.Attributes; using Telegram.Net.Attributes;
using Telegram.Net.Interfaces; using Telegram.Net.Interfaces;
using static System.Reflection.BindingFlags;
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
namespace Telegram.Net.Services; namespace Telegram.Net.Services;
@@ -73,116 +75,85 @@ public class TelegramHostedService : IHostedService
} }
} }
internal async Task AddAttributes(CancellationToken cancellationToken) internal async Task AddAttributes(CancellationToken cancellationToken)
{ {
await Task.Run(async () => await Task.Run(async () =>
{ {
try try
{ {
var implementations = AppDomain.CurrentDomain.GetAssemblies() var attributeTypes = new HashSet<Type>
{
typeof(CommandAttribute),
typeof(CallbackAttribute),
typeof(EditMessageAttribute),
typeof(InlineAttribute),
typeof(PreCheckoutAttribute),
typeof(UpdateAttribute)
};
var methods = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes()) .SelectMany(a => a.GetTypes())
.Where(t => typeof(IUpdatePollingService).IsAssignableFrom(t) && !t.IsInterface); .Where(t => typeof(IUpdatePollingService).IsAssignableFrom(t) && !t.IsInterface)
.SelectMany(t => t.GetMethods(Instance |
Public |
NonPublic |
DeclaredOnly))
.Where(m => m.GetCustomAttributes().Any(a => attributeTypes.Contains(a.GetType())))
.ToList();
foreach (var implementation in implementations) if (methods.Count == 0)
{ {
isc.AddScoped(implementation); _logger.LogWarning("No methods found with required attributes");
}
var methods = implementations
.SelectMany(t => t.GetMethods(
BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly))
.Where(m =>
m.GetCustomAttribute<CommandAttribute>() != null ||
m.GetCustomAttribute<CallbackAttribute>() != null ||
m.GetCustomAttribute<EditMessageAttribute>() != null ||
m.GetCustomAttribute<InlineAttribute>() != null ||
m.GetCustomAttribute<PreCheckoutAttribute>() != null ||
m.GetCustomAttribute<UpdateAttribute>() != null);
if (methods.Count() == 0)
{
_logger.LogWarning("Not founded methods with attributes.");
} }
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); var isp = isc.BuildServiceProvider();
foreach (var method in methods) foreach (var method in methods)
{ {
var commandAttr = method.GetCustomAttribute<CommandAttribute>(); var declaringType = method.DeclaringType!;
if (commandAttr != null) var constructor = declaringType.GetConstructors()[0];
{ var parameters = constructor.GetParameters()
if (IsValidHandlerMethod(method, typeof(Message))) .Select(param => isp.GetRequiredService(param.ParameterType))
{ .ToArray();
var handler = CreateDelegate<Message>(method);
if (!CommandHandler.TryAdd(commandAttr.Command, handler)) constructor.Invoke(parameters);
throw new Exception($"Failed to add in commandHandler: {commandAttr.Command}");
}
continue; void AddHandler<T>(Dictionary<string, Func<ITelegramBotClient, T, CancellationToken, Task>> dictionary, string key) where T : class
{
if (!IsValidHandlerMethod(method, typeof(T))) return;
var handler = CreateDelegate<T>(method);
if (!dictionary.TryAdd(key, handler))
throw new Exception($"Failed to add {key} to {dictionary.GetType().Name}");
} }
var callbackAttr = method.GetCustomAttribute<CallbackAttribute>(); switch (method.GetCustomAttributes().FirstOrDefault())
if (callbackAttr != null)
{ {
if (IsValidHandlerMethod(method, typeof(CallbackQuery))) case CommandAttribute command:
{ AddHandler(CommandHandler, command.Command);
var handler = CreateDelegate<CallbackQuery>(method); break;
if (!CallbackQueryHandler.TryAdd(callbackAttr.QueryId, handler))
throw new Exception($"Failed to add in callbacKQuery: {callbackAttr.QueryId}");; case CallbackAttribute callback:
} AddHandler(CallbackQueryHandler, callback.QueryId);
break;
continue;
} case EditMessageAttribute _ when IsValidHandlerMethod(method, typeof(Message)):
EditedMessageHandler.Add(CreateDelegate<Message>(method));
var editMessageAttr = method.GetCustomAttribute<EditMessageAttribute>(); break;
if (editMessageAttr != null)
{ case InlineAttribute inline:
if (IsValidHandlerMethod(method, typeof(Message))) AddHandler(InlineHandler, inline.InlineId);
{ break;
var handler = CreateDelegate<Message>(method);
EditedMessageHandler.Add(handler); case PreCheckoutAttribute _ when IsValidHandlerMethod(method, typeof(PreCheckoutQuery)):
} PreCheckoutHandler = CreateDelegate<PreCheckoutQuery>(method);
break;
continue;
} case UpdateAttribute _ when IsValidHandlerMethod(method, typeof(Update)):
DefaultUpdateHandler.Add(CreateDelegate<Update>(method));
var inlineAttr = method.GetCustomAttribute<InlineAttribute>(); break;
if (inlineAttr != null)
{
if (IsValidHandlerMethod(method, typeof(InlineQuery)))
{
var handler = CreateDelegate<InlineQuery>(method);
if (!InlineHandler.TryAdd(inlineAttr.InlineId, handler))
throw new Exception($"Failed to add in inlineHandler: {inlineAttr.InlineId}");;
}
continue;
}
var preCheckoutAttr = method.GetCustomAttribute<PreCheckoutAttribute>();
if (preCheckoutAttr != null)
{
if (IsValidHandlerMethod(method, typeof(PreCheckoutQuery)))
{
var handler = CreateDelegate<PreCheckoutQuery>(method);
PreCheckoutHandler = handler;
}
continue;
}
var updateAttr = method.GetCustomAttribute<UpdateAttribute>();
if (updateAttr != null)
{
if (IsValidHandlerMethod(method, typeof(Update)))
{
var handler = CreateDelegate<Update>(method);
DefaultUpdateHandler.Add(handler);
}
continue;
} }
} }
} }

View File

@@ -5,7 +5,7 @@
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>1.0.0</Version> <Version>1.0.1</Version>
<Authors>yawaflua</Authors> <Authors>yawaflua</Authors>
<Title>Telegram.Net</Title> <Title>Telegram.Net</Title>
<Description>Telegram.Bots extender pack, what provides to user attributes, which can used with services</Description> <Description>Telegram.Bots extender pack, what provides to user attributes, which can used with services</Description>