[英]How to implement event handler in a separate file and attach it by using dependency injection?
I'm using Discord.Net to create a C# Discord bot.我正在使用 Discord.Net 创建 C# Discord 机器人。 My application is using Dependency Injection and in the Program.cs file I have access to the singleton instance of
DiscordSocketClient
.我的应用程序正在使用依赖注入,并且在 Program.cs 文件中我可以访问 DiscordSocketClient 的
DiscordSocketClient
实例。
This instance provides many events eg这个实例提供了许多事件,例如
discordSocketClient.UserJoined += async socketGuildUser =>
{
// do things here
};
This seems to be a more C# related question.这似乎是一个与 C# 相关的问题。 I want to create separate files with one event handler per file to keep the code organized.
我想为每个文件创建一个带有一个事件处理程序的单独文件,以保持代码井井有条。 A sample event handler could look like
示例事件处理程序可能看起来像
public class UserJoinedHandler
{
// Use the constructor to get access to services by using DI
public Task OnUserJoined(SocketGuildUser socketGuildUser)
{
// Do things here
return Task.CompletedTask;
}
}
What is the best / easiest way to attach this event listener?附加此事件侦听器的最佳/最简单方法是什么? The first solution coming to my mind would be to register this handler as a singleton service
我想到的第一个解决方案是将此处理程序注册为 singleton 服务
serviceCollection.AddSingleton<UserJoinedHandler>();
and in my Program.cs file I could then do this然后在我的 Program.cs 文件中我可以这样做
discordSocketClient.UserJoined += serviceProvider.GetService<UserJoinedHandler>().OnUserJoined;
Are there any better solutions to register handlers?注册处理程序有更好的解决方案吗? Eg using reflection or annotations like
[ThisClassHandlesTheUserJoinedEvent]
and let the client search for those by adding an extension method like discordSocketClient.SearchForEventHandlingAnnotations()
?例如,使用像
[ThisClassHandlesTheUserJoinedEvent]
这样的反射或注释,并让客户端通过添加像discordSocketClient.SearchForEventHandlingAnnotations()
这样的扩展方法来搜索这些?
I know this sounds like overengineering but this project is a big one and I like organized code.我知道这听起来像是过度工程,但这个项目很大,我喜欢有组织的代码。
This is more of a half answer/half comment.这更像是一半的答案/一半的评论。
Be careful not to overuse dependency injection.注意不要过度使用依赖注入。 It's a great tool to help you avoid tight coupling in your code and make testing of dependent services easier but it's not meant to help you organize your code.
它是一个很好的工具,可以帮助您避免代码中的紧密耦合,并使依赖服务的测试更容易,但它并不意味着帮助您组织代码。
In your case you don't really have a dependent service - ie a service that depends on your handlers.在您的情况下,您实际上并没有依赖服务 - 即依赖于您的处理程序的服务。 This means there's really nothing to inject them into.
这意味着实际上没有任何东西可以注入它们。 Yes, you could create a wrapper class you can inject into that collects and registers all the handlers but does it really add any value to you?
是的,您可以创建一个包装器 class 您可以注入其中收集并注册所有处理程序,但它真的为您增加了任何价值吗?
If I were you I would just have a helper class to RegisterClientHandlers
and then subscribe your handlers to all the events in there.如果我是你,我只会有一个助手 class 到
RegisterClientHandlers
,然后为你的处理程序订阅那里的所有事件。 If you then down the line think you need to be able to test different combinations of handlers (say UserJoinedHandler_v2
together with UserLeftHandler_v1
), then you could start to think about making those injectable into the helper class using a common handler-interface.如果您随后认为您需要能够测试处理程序的不同组合(例如
UserJoinedHandler_v2
和UserLeftHandler_v1
),那么您可以开始考虑使用通用处理程序接口将它们注入到帮助程序 class 中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.