Skip to content

Commit 38df51f

Browse files
authored
Merge pull request #4 from yawaflua/develop
pre-v1.0.2 fix
2 parents 59a94c9 + 5507912 commit 38df51f

7 files changed

Lines changed: 113 additions & 112 deletions

File tree

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.Configuration;
2+
using Microsoft.Extensions.DependencyInjection;
23
using Microsoft.Extensions.Hosting;
34
using Microsoft.Extensions.Logging;
45
using Telegram.Net;
@@ -7,12 +8,11 @@
78
.ConfigureLogging(l => l.ClearProviders().AddConsole())
89
.ConfigureServices(k =>
910
{
10-
k.ConnectTelegram(new("TOKEN")
11-
{
12-
errorHandler = async (client, exception, ctx) =>
13-
{
14-
Console.WriteLine(exception);
15-
}
16-
});
11+
var _conf = new ConfigurationBuilder()
12+
.AddJsonFile("appsettings.json")
13+
.AddEnvironmentVariables()
14+
.Build();
15+
k.AddSingleton(_conf);
16+
k.ConnectTelegram(new(_conf.GetValue<string>("telegram_test_token")));
1717
});
1818
webHost.Build().Run();

Examples/Telegram.Examples/Telegram.Examples.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<ItemGroup>
1313
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
1414
<ProjectReference Include="..\..\Telegram.Net\Telegram.Net.csproj" />
15+
16+
<None CopyToOutputDirectory="Always" Include="appsettings.json"></None>
1517
</ItemGroup>
18+
1619

1720
</Project>

Examples/Telegram.Examples/UpdatePolling/Update.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Telegram.Bot;
1+
using Microsoft.Extensions.Configuration;
2+
using Telegram.Bot;
23
using Telegram.Bot.Types;
34
using Telegram.Net.Attributes;
45
using Telegram.Net.Interfaces;
@@ -7,6 +8,11 @@ namespace Telegram.Examples.UpdatePolling;
78

89
public class Update : IUpdatePollingService
910
{
11+
private static IConfiguration _conf;
12+
public Update(IConfiguration conf)
13+
{
14+
_conf = conf;
15+
}
1016
[Update]
1117
public async Task UpdateExample(ITelegramBotClient client, Bot.Types.Update update, CancellationToken ctx)
1218
{
@@ -31,6 +37,12 @@ public async Task StartCommand(ITelegramBotClient client, Message message, Cance
3137
await client.SendMessage(message.From!.Id, "Hello, I`m example bot.", cancellationToken: ctx);
3238
}
3339

40+
[Command("/test_conf")]
41+
public async Task TestConfigurationBuilder(ITelegramBotClient client, Message message, CancellationToken cts)
42+
{
43+
await client.SendMessage(message.Chat.Id, _conf.GetValue<string>("ExampleMessage") ?? throw new Exception("Not found"));
44+
}
45+
3446
[EditMessage]
3547
public async Task EditMessageExmaple(ITelegramBotClient client, Message message, CancellationToken ctx)
3648
{
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"ExampleMessage": "Test!",
3+
"telegram_test_token": "PROVIDE_TOKEN"
4+
}

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@ Ensure you have the required dependencies installed:
2020

2121
## Usage
2222

23+
### Provide dependencies in class
24+
You can provide dependencies in class from constructor, and after it use it like `static`.
25+
```csharp
26+
public class Example : IUpdatePollingService
27+
{
28+
private static MyCoolService _service; // It should to be static!
29+
30+
public Example(MyCoolService service)
31+
{
32+
_service = service;
33+
}
34+
}
35+
```
36+
2337
### Inline Query Handling
2438
Use the `InlineAttribute` to register a method as an inline query handler.
2539

@@ -91,4 +105,4 @@ public static async Task HandleUpdate(ITelegramBotClient bot, Update update, Can
91105
Try to not use provided dependencies in class. We are should to fix it in v1.0.2.
92106

93107
## License
94-
This project is open-source and available under the [Apache 2.0 License](LICENSE).
108+
This project is open-source and available under the [Apache 2.0 License](LICENSE).

Telegram.Net/Services/TelegramHostedService.cs

Lines changed: 69 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using Telegram.Bot.Types.Payments;
1010
using Telegram.Net.Attributes;
1111
using Telegram.Net.Interfaces;
12+
using static System.Reflection.BindingFlags;
13+
1214
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
1315

1416
namespace Telegram.Net.Services;
@@ -18,12 +20,12 @@ public class TelegramHostedService : IHostedService
1820
private IServiceCollection isc { get; }
1921
internal TelegramBotClient Client { get; set; }
2022
private ITelegramBotConfig Config { get; }
21-
internal Dictionary<string, Func<ITelegramBotClient, Message, CancellationToken, Task>> CommandHandler { get; } = new();
22-
internal List<Func<ITelegramBotClient, Message, CancellationToken, Task>> EditedMessageHandler { get; } = new();
23-
internal Dictionary<string, Func<ITelegramBotClient, CallbackQuery,CancellationToken, Task>> CallbackQueryHandler { get; } = new();
24-
internal Dictionary<string, Func<ITelegramBotClient, InlineQuery ,CancellationToken, Task>> InlineHandler { get; } = new();
23+
internal Dictionary<string, Func<ITelegramBotClient, Message, CancellationToken, Task>> CommandHandler { get; set; } = new();
24+
internal List<Func<ITelegramBotClient, Message, CancellationToken, Task>> EditedMessageHandler { get; set; } = new();
25+
internal Dictionary<string, Func<ITelegramBotClient, CallbackQuery,CancellationToken, Task>> CallbackQueryHandler { get; set; } = new();
26+
internal Dictionary<string, Func<ITelegramBotClient, InlineQuery ,CancellationToken, Task>> InlineHandler { get; set; } = new();
2527
internal Func<ITelegramBotClient, PreCheckoutQuery,CancellationToken, Task>? PreCheckoutHandler { get; set; }
26-
internal List<Func<ITelegramBotClient, Update, CancellationToken, Task>> DefaultUpdateHandler { get; } = new();
28+
internal List<Func<ITelegramBotClient, Update, CancellationToken, Task>> DefaultUpdateHandler { get; set; } = new();
2729
internal static ILogger<TelegramHostedService> _logger;
2830

2931
public TelegramHostedService(ITelegramBotConfig config, IServiceCollection isc, ILogger<TelegramHostedService> logger)
@@ -73,116 +75,82 @@ internal static Func<ITelegramBotClient, T, CancellationToken, Task> CreateDeleg
7375
}
7476

7577
}
76-
78+
79+
80+
7781
internal async Task AddAttributes(CancellationToken cancellationToken)
7882
{
7983
await Task.Run(async () =>
8084
{
8185
try
8286
{
83-
var implementations = AppDomain.CurrentDomain.GetAssemblies()
84-
.SelectMany(a => a.GetTypes())
85-
.Where(t => typeof(IUpdatePollingService).IsAssignableFrom(t) && !t.IsInterface);
86-
87-
foreach (var implementation in implementations)
87+
var attributeTypes = new HashSet<Type>
8888
{
89-
isc.AddScoped(implementation);
90-
}
91-
92-
var methods = implementations
93-
.SelectMany(t => t.GetMethods(
94-
BindingFlags.Instance |
95-
BindingFlags.Public | BindingFlags.NonPublic |
96-
BindingFlags.DeclaredOnly))
97-
.Where(m =>
98-
m.GetCustomAttribute<CommandAttribute>() != null ||
99-
m.GetCustomAttribute<CallbackAttribute>() != null ||
100-
m.GetCustomAttribute<EditMessageAttribute>() != null ||
101-
m.GetCustomAttribute<InlineAttribute>() != null ||
102-
m.GetCustomAttribute<PreCheckoutAttribute>() != null ||
103-
m.GetCustomAttribute<UpdateAttribute>() != null);
104-
105-
if (methods.Count() == 0)
89+
typeof(CommandAttribute),
90+
typeof(CallbackAttribute),
91+
typeof(EditMessageAttribute),
92+
typeof(InlineAttribute),
93+
typeof(PreCheckoutAttribute),
94+
typeof(UpdateAttribute)
95+
};
96+
97+
var methods = AppDomain.CurrentDomain.GetAssemblies()
98+
.SelectMany(a => a.GetTypes())
99+
.Where(t => typeof(IUpdatePollingService).IsAssignableFrom(t) && !t.IsInterface)
100+
.SelectMany(t => t.GetMethods(Instance |
101+
Public |
102+
NonPublic |
103+
DeclaredOnly))
104+
.Where(m => m.GetCustomAttributes().Any(a => attributeTypes.Contains(a.GetType())))
105+
.ToList();
106+
107+
if (methods.Count == 0)
106108
{
107-
_logger.LogWarning("Not founded methods with attributes.");
109+
_logger.LogWarning("No methods found with required attributes");
108110
}
109111

110-
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
112+
var isp = isc.BuildServiceProvider();
111113
foreach (var method in methods)
112114
{
113-
var commandAttr = method.GetCustomAttribute<CommandAttribute>();
114-
if (commandAttr != null)
115-
{
116-
if (IsValidHandlerMethod(method, typeof(Message)))
117-
{
118-
var handler = CreateDelegate<Message>(method);
119-
if (!CommandHandler.TryAdd(commandAttr.Command, handler))
120-
throw new Exception($"Failed to add in commandHandler: {commandAttr.Command}");
121-
}
122-
123-
continue;
124-
}
125-
126-
var callbackAttr = method.GetCustomAttribute<CallbackAttribute>();
127-
if (callbackAttr != null)
128-
{
129-
if (IsValidHandlerMethod(method, typeof(CallbackQuery)))
130-
{
131-
var handler = CreateDelegate<CallbackQuery>(method);
132-
if (!CallbackQueryHandler.TryAdd(callbackAttr.QueryId, handler))
133-
throw new Exception($"Failed to add in callbacKQuery: {callbackAttr.QueryId}");;
134-
}
135-
136-
continue;
137-
}
138-
139-
var editMessageAttr = method.GetCustomAttribute<EditMessageAttribute>();
140-
if (editMessageAttr != null)
141-
{
142-
if (IsValidHandlerMethod(method, typeof(Message)))
143-
{
144-
var handler = CreateDelegate<Message>(method);
145-
EditedMessageHandler.Add(handler);
146-
}
147-
148-
continue;
149-
}
150-
151-
var inlineAttr = method.GetCustomAttribute<InlineAttribute>();
152-
if (inlineAttr != null)
153-
{
154-
if (IsValidHandlerMethod(method, typeof(InlineQuery)))
155-
{
156-
var handler = CreateDelegate<InlineQuery>(method);
157-
if (!InlineHandler.TryAdd(inlineAttr.InlineId, handler))
158-
throw new Exception($"Failed to add in inlineHandler: {inlineAttr.InlineId}");;
159-
}
160-
161-
continue;
162-
}
163-
164-
var preCheckoutAttr = method.GetCustomAttribute<PreCheckoutAttribute>();
165-
if (preCheckoutAttr != null)
166-
{
167-
if (IsValidHandlerMethod(method, typeof(PreCheckoutQuery)))
168-
{
169-
var handler = CreateDelegate<PreCheckoutQuery>(method);
170-
PreCheckoutHandler = handler;
171-
}
172-
173-
continue;
174-
}
115+
var declaringType = method.DeclaringType!;
116+
var constructor = declaringType.GetConstructors()[0];
117+
var parameters = constructor.GetParameters()
118+
.Select(param => isp.GetRequiredService(param.ParameterType))
119+
.ToArray();
120+
121+
constructor.Invoke(parameters);
175122

176-
var updateAttr = method.GetCustomAttribute<UpdateAttribute>();
177-
if (updateAttr != null)
123+
switch (method.GetCustomAttributes().First(t => attributeTypes.Contains(t.GetType())))
178124
{
179-
if (IsValidHandlerMethod(method, typeof(Update)))
180-
{
181-
var handler = CreateDelegate<Update>(method);
182-
DefaultUpdateHandler.Add(handler);
183-
}
184-
185-
continue;
125+
case CommandAttribute command when IsValidHandlerMethod(method, typeof(Message)):
126+
var commandHandler = CreateDelegate<Message>(method);
127+
if (!CommandHandler.TryAdd(command.Command, commandHandler))
128+
throw new Exception($"Failed to add command: {command.Command}");
129+
break;
130+
131+
case CallbackAttribute callback when IsValidHandlerMethod(method, typeof(CallbackQuery)):
132+
var callbackHandler = CreateDelegate<CallbackQuery>(method);
133+
if (!CallbackQueryHandler.TryAdd(callback.QueryId, callbackHandler))
134+
throw new Exception($"Failed to add callback: {callback.QueryId}");
135+
break;
136+
137+
case EditMessageAttribute _ when IsValidHandlerMethod(method, typeof(Message)):
138+
EditedMessageHandler.Add(CreateDelegate<Message>(method));
139+
break;
140+
141+
case InlineAttribute inline when IsValidHandlerMethod(method, typeof(InlineQuery)):
142+
var inlineHandler = CreateDelegate<InlineQuery>(method);
143+
if (!InlineHandler.TryAdd(inline.InlineId, inlineHandler))
144+
throw new Exception($"Failed to add inline: {inline.InlineId}");
145+
break;
146+
147+
case PreCheckoutAttribute _ when IsValidHandlerMethod(method, typeof(PreCheckoutQuery)):
148+
PreCheckoutHandler = CreateDelegate<PreCheckoutQuery>(method);
149+
break;
150+
151+
case UpdateAttribute _ when IsValidHandlerMethod(method, typeof(Update)):
152+
DefaultUpdateHandler.Add(CreateDelegate<Update>(method));
153+
break;
186154
}
187155
}
188156
}

Telegram.Net/Telegram.Net.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<TargetFramework>net7.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8-
<Version>1.0.0</Version>
8+
<Version>1.0.2</Version>
99
<Authors>yawaflua</Authors>
1010
<Title>yawaflua.Telegram.Net</Title>
1111
<Description>Telegram.Bots extender pack, what provides to user attributes, which can used with services</Description>

0 commit comments

Comments
 (0)