繁体   English   中英

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

[英]How to implement event handler in a separate file and attach it by using dependency injection?

我正在使用 Discord.Net 创建 C# Discord 机器人。 我的应用程序正在使用依赖注入,并且在 Program.cs 文件中我可以访问 DiscordSocketClient 的DiscordSocketClient实例。

这个实例提供了许多事件,例如

discordSocketClient.UserJoined += async socketGuildUser =>
{
    // do things here
};

这似乎是一个与 C# 相关的问题。 我想为每个文件创建一个带有一个事件处理程序的单独文件,以保持代码井井有条。 示例事件处理程序可能看起来像

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;
    }
}

附加此事件侦听器的最佳/最简单方法是什么? 我想到的第一个解决方案是将此处理程序注册为 singleton 服务

serviceCollection.AddSingleton<UserJoinedHandler>();

然后在我的 Program.cs 文件中我可以这样做

discordSocketClient.UserJoined += serviceProvider.GetService<UserJoinedHandler>().OnUserJoined;


注册处理程序有更好的解决方案吗? 例如,使用像[ThisClassHandlesTheUserJoinedEvent]这样的反射或注释,并让客户端通过添加像discordSocketClient.SearchForEventHandlingAnnotations()这样的扩展方法来搜索这些?

我知道这听起来像是过度工程,但这个项目很大,我喜欢有组织的代码。

这更像是一半的答案/一半的评论。

注意不要过度使用依赖注入。 它是一个很好的工具,可以帮助您避免代码中的紧密耦合,并使依赖服务的测试更容易,但它并不意味着帮助您组织代码。

在您的情况下,您实际上并没有依赖服务 - 即依赖于您的处理程序的服务。 这意味着实际上没有任何东西可以注入它们。 是的,您可以创建一个包装器 class 您可以注入其中收集并注册所有处理程序,但它真的为您增加了任何价值吗?

如果我是你,我只会有一个助手 class 到RegisterClientHandlers ,然后为你的处理程序订阅那里的所有事件。 如果您随后认为您需要能够测试处理程序的不同组合(例如UserJoinedHandler_v2UserLeftHandler_v1 ),那么您可以开始考虑使用通用处理程序接口将它们注入到帮助程序 class 中。

暂无
暂无

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

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