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

View File

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

View File

@@ -1,4 +1,5 @@
using Telegram.Bot;
using Microsoft.Extensions.Configuration;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Net.Attributes;
using Telegram.Net.Interfaces;
@@ -7,6 +8,11 @@ namespace Telegram.Examples.UpdatePolling;
public class Update : IUpdatePollingService
{
private static IConfiguration _conf;
public Update(IConfiguration conf)
{
_conf = conf;
}
[Update]
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);
}
[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]
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
### 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
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
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.Net.Attributes;
using Telegram.Net.Interfaces;
using static System.Reflection.BindingFlags;
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
namespace Telegram.Net.Services;
@@ -73,116 +75,85 @@ public class TelegramHostedService : IHostedService
}
}
internal async Task AddAttributes(CancellationToken cancellationToken)
{
await Task.Run(async () =>
{
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())
.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);
}
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.");
_logger.LogWarning("No methods found with required attributes");
}
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
var isp = isc.BuildServiceProvider();
foreach (var method in methods)
{
var commandAttr = method.GetCustomAttribute<CommandAttribute>();
if (commandAttr != null)
{
if (IsValidHandlerMethod(method, typeof(Message)))
{
var handler = CreateDelegate<Message>(method);
if (!CommandHandler.TryAdd(commandAttr.Command, handler))
throw new Exception($"Failed to add in commandHandler: {commandAttr.Command}");
}
var declaringType = method.DeclaringType!;
var constructor = declaringType.GetConstructors()[0];
var parameters = constructor.GetParameters()
.Select(param => isp.GetRequiredService(param.ParameterType))
.ToArray();
constructor.Invoke(parameters);
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>();
if (callbackAttr != null)
switch (method.GetCustomAttributes().FirstOrDefault())
{
if (IsValidHandlerMethod(method, typeof(CallbackQuery)))
{
var handler = CreateDelegate<CallbackQuery>(method);
if (!CallbackQueryHandler.TryAdd(callbackAttr.QueryId, handler))
throw new Exception($"Failed to add in callbacKQuery: {callbackAttr.QueryId}");;
}
continue;
}
var editMessageAttr = method.GetCustomAttribute<EditMessageAttribute>();
if (editMessageAttr != null)
{
if (IsValidHandlerMethod(method, typeof(Message)))
{
var handler = CreateDelegate<Message>(method);
EditedMessageHandler.Add(handler);
}
continue;
}
var inlineAttr = method.GetCustomAttribute<InlineAttribute>();
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;
case CommandAttribute command:
AddHandler(CommandHandler, command.Command);
break;
case CallbackAttribute callback:
AddHandler(CallbackQueryHandler, callback.QueryId);
break;
case EditMessageAttribute _ when IsValidHandlerMethod(method, typeof(Message)):
EditedMessageHandler.Add(CreateDelegate<Message>(method));
break;
case InlineAttribute inline:
AddHandler(InlineHandler, inline.InlineId);
break;
case PreCheckoutAttribute _ when IsValidHandlerMethod(method, typeof(PreCheckoutQuery)):
PreCheckoutHandler = CreateDelegate<PreCheckoutQuery>(method);
break;
case UpdateAttribute _ when IsValidHandlerMethod(method, typeof(Update)):
DefaultUpdateHandler.Add(CreateDelegate<Update>(method));
break;
}
}
}

View File

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