简体   繁体   English

如何在单独的文件中实现事件处理程序并使用依赖注入附加它?

[英]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_v2UserLeftHandler_v1 ),那么您可以开始考虑使用通用处理程序接口将它们注入到帮助程序 class 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM