首页 短视频

Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践

分类:短视频
字数: (5113)
阅读: (2245)
内容摘要:Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践,

在构建 AI 驱动的命令行交互程序时,我们常常会遇到代码耦合度高、可测试性差等问题。直接硬编码各种服务依赖,就像一碗意大利面,难以维护和扩展。本文将探讨如何使用 Dotnet 的依赖注入(DI)容器,为 AI 控制台对话添加依赖注入等集成,从而构建更健壮、可维护的应用程序。

问题场景重现:没有 DI 的控制台应用

想象一个简单的 AI 问答控制台程序,直接在 Main 函数中实例化所有依赖项:

public class Program
{
    public static void Main(string[] args)
    {
        var httpClient = new HttpClient(); // 直接创建 HttpClient
        var aiService = new AIService(httpClient); // 直接创建 AIService
        var consoleHandler = new ConsoleHandler(aiService); // 直接创建 ConsoleHandler

        consoleHandler.Run();
    }
}

public class AIService
{
    private readonly HttpClient _httpClient;

    public AIService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetResponseAsync(string query)
    {
        // 调用 AI 模型的逻辑
        // 假设使用 OpenAI 或 Azure OpenAI 服务
        // 实际实现省略
        return "AI 回复: " + query;
    }
}

public class ConsoleHandler
{
    private readonly AIService _aiService;

    public ConsoleHandler(AIService aiService)
    {
        _aiService = aiService;
    }

    public void Run()
    {
        while (true)
        {
            Console.Write("请输入问题:");
            string? question = Console.ReadLine();

            if (string.IsNullOrEmpty(question))
            {
                break;
            }

            string answer = _aiService.GetResponseAsync(question).Result;
            Console.WriteLine(answer);
        }
    }
}

这种方式存在明显的问题:

Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践
  • 耦合度高: Program 类直接依赖于 AIServiceConsoleHandler 的具体实现。
  • 可测试性差: 难以对 ConsoleHandler 进行单元测试,因为无法轻松地替换 AIService
  • 难以维护: 如果需要修改 AIService 的实现,可能需要修改 Program 类。

底层原理深度剖析:依赖注入与控制反转

依赖注入(DI)是一种设计模式,用于解耦软件组件之间的依赖关系。它的核心思想是:不让类自己创建它所依赖的对象,而是通过外部(通常是 DI 容器)将依赖项注入到类中。

控制反转(IoC)是 DI 的一种实现方式。IoC 容器负责创建和管理应用程序中的对象,并将这些对象注入到需要它们的其他对象中。

Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践

在 Dotnet 中,可以使用内置的 DI 容器,也可以使用第三方 DI 库,如 Autofac 或 Ninject。本文将使用 Dotnet 内置的 DI 容器。

代码/配置解决方案:使用 Dotnet 内置 DI 容器

  1. 安装 Microsoft.Extensions.DependencyInjection 包:

    Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践

dotnet add package Microsoft.Extensions.DependencyInjection ```

  1. 注册服务:

    Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践

    修改 Program 类,使用 ServiceCollection 注册服务:

    using Microsoft.Extensions.DependencyInjection;
    
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var services = new ServiceCollection();
            services.AddHttpClient(); // 注册 HttpClient
            services.AddSingleton<AIService>(); // 注册 AIService
            services.AddSingleton<ConsoleHandler>(); // 注册 ConsoleHandler
    
            var serviceProvider = services.BuildServiceProvider();
    
            var consoleHandler = serviceProvider.GetRequiredService<ConsoleHandler>();
            consoleHandler.Run();
        }
    }
    
  2. 修改构造函数:

    AIServiceConsoleHandler 的构造函数不再直接创建依赖项,而是通过构造函数注入:

    public class AIService
    {
        private readonly HttpClient _httpClient;
    
        public AIService(HttpClient httpClient)
        {
            _httpClient = httpClient; // 通过构造函数注入 HttpClient
        }
    
        public async Task<string> GetResponseAsync(string query)
        {
            // ...
            return "AI 回复: " + query;
        }
    }
    
    public class ConsoleHandler
    {
        private readonly AIService _aiService;
    
        public ConsoleHandler(AIService aiService)
        {
            _aiService = aiService; // 通过构造函数注入 AIService
        }
    
        public void Run()
        {
            // ...
        }
    }
    

实战避坑经验总结

  • 生命周期管理: AddSingleton 注册的服务在应用程序的整个生命周期内只有一个实例。AddScoped 注册的服务在每个作用域内创建一个实例。AddTransient 注册的服务每次请求都会创建一个新的实例。根据实际情况选择合适的生命周期。
  • HttpClient 的正确使用: HttpClient 应该被注册为单例(Singleton),避免频繁创建和销毁,导致端口耗尽。在上面的代码中,我们使用 AddHttpClient() 来注册 HttpClient,它会自动处理生命周期。
  • 配置文件的集成: 可以使用 Microsoft.Extensions.Configuration 包将配置信息(如 OpenAI API Key)从配置文件中读取,并通过依赖注入注入到服务中,避免硬编码敏感信息。
  • 异步编程: AI 服务的调用通常是异步的,使用 asyncawait 关键字可以避免阻塞主线程,提高程序的响应速度。需要注意的是,控制台程序中使用 Task.ResultTask.Wait() 可能会导致死锁,建议使用 Task.Run() 配合 ConfigureAwait(false)

通过使用依赖注入,我们可以提高 Dotnet 为 AI 控制台对话添加依赖注入等集成后,程序的模块化程度,降低耦合度,提高可测试性和可维护性。这对于构建复杂的 AI 驱动的命令行应用程序至关重要。

Dotnet控制台应用:依赖注入驱动的 AI 对话系统架构实践

转载请注明出处: 青衫落拓

本文的链接地址: http://m.acea5.store/blog/070619.SHTML

本文最后 发布于2026-04-02 05:31:11,已经过了25天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 风一样的男子 6 天前
    配置文件的集成那部分能不能详细讲一下,比如怎么把 OpenAI API Key 注入到 AIService 里?
  • 绿豆汤 6 天前
    请问如果我想用 Autofac 替换 Dotnet 内置的 DI 容器,代码需要做哪些修改呢?