using System.Net.Http;
using Dpz.Core.Infrastructure.BotProtection;
using Dpz.Core.MessageQueue.Extensions;
using Dpz.Core.Public.ViewModel.Messages;
using Dpz.Core.Service.Network;
using Dpz.Core.Service.ObjectStorage;
using Dpz.Core.Shard.Implement.Service;
using Dpz.Core.Shard.Service;
using Dpz.Core.Web.EventHandlers;
using Dpz.Core.Web.Library.Api;
using Dpz.Core.Web.Library.Api.Service;

namespace Dpz.Core.Web.Library;

public static class DependencyInjectionExtensions
{
    public static IServiceCollection AddInject(this IServiceCollection services)
    {
        services.AddDpzAspNetCoreServices();
        services.AddShardCloudFileService();

        services.AddScoped<IHomeCacheService, HomeCacheService>();
        services.AddScoped<IApplicationSignInManager, ApplicationSignInManager>();
        services.AddScoped<
            IUserClaimsPrincipalFactory<VmUserInfo>,
            UserInfoClaimsPrincipalFactory
        >();
        services.AddHttpClient();

        services
            .AddHttpClient(
                "edge",
                httpClient =>
                {
                    httpClient.DefaultRequestHeaders.Add("User-Agent", EnvironmentInfo.UserAgent);
                }
            )
            .ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
            });

        services
            .AddHttpClient(
                "WebAPI",
                (sp, httpClient) =>
                {
                    var configuration = sp.GetService<IConfiguration>();
                    var apiAddress =
                        configuration?["WebApi"] ?? throw new Exception("web api address is null");
                    httpClient.BaseAddress = new Uri(apiAddress);
                }
            )
            .ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
            });

        //添加 腾讯云COS储存 S3兼容
        services.AddS3ObjectStorage();

        services.AddNetworkServices();

        services.AddScoped<IVideoShardService, VideoShardService>();
        services.AddScoped<ToolService>();
        services.AddScoped<MumbleViewHelper>();
        services.AddSingleton<AssetService>();

        // services.AddHostedService<AssetUploadHostedService>();
        services.AddHostedService<PageRouteCatalogScannerService>();

        // 机器人拦截:Web 面向现代浏览器,启用浏览器版本判定
        services.AddBotProtection(o => o.CheckBrowserVersion = true);
        return services;
    }

    /// <summary>
    /// 注册需要消费的消息队列处理器和 Outbox 后台补发服务。
    /// </summary>
    /// <param name="services">服务集合。</param>
    /// <returns>注册后的服务集合。</returns>
    public static IServiceCollection AddMessageQueueServices(this IServiceCollection services)
    {
        // 注册消息消费者
        // 注册消息消费者
        services.AddMessageConsumer<ClearCacheMessage, ClearCacheMessageHandler>();
        services.AddMessageConsumer<RefreshUserProfileMessage, RefreshUserProfileMessageHandler>();

        services.AddMessageOutboxRetryWorker();

        return services;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 ASP.NET Core 应用程序的依赖注入配置扩展类,用于集中管理和注册应用所需的各种服务。

整体结构

该文件包含一个静态类 DependencyInjectionExtensions,提供了两个扩展方法来配置服务容器。


主要方法

1. AddInject 方法

这是主要的服务注册方法,按功能分为以下几个部分:

基础服务注册

services.AddDpzAspNetCoreServices();  // 添加Dpz框架的ASP.NET Core服务
services.AddShardCloudFileService();  // 添加分片云文件服务

业务服务注册(Scoped生命周期)

services.AddScoped<IHomeCacheService, HomeCacheService>();
services.AddScoped<IApplicationSignInManager, ApplicationSignInManager>();
services.AddScoped<IUserClaimsPrincipalFactory<VmUserInfo>, UserInfoClaimsPrincipalFactory>();
services.AddScoped<IVideoShardService, VideoShardService>();
services.AddScoped<ToolService>();
services.AddScoped<MumbleViewHelper>();

这些服务在每个HTTP请求中创建一次实例。

HTTP客户端配置

配置了三个不同用途的HTTP客户端:

  1. 默认客户端
services.AddHttpClient();
  1. Edge客户端 - 用于特定场景(可能是边缘节点通信)
services.AddHttpClient("edge", ...)
    .DefaultRequestHeaders.Add("User-Agent", EnvironmentInfo.UserAgent)
    .ServerCertificateCustomValidationCallback = (_, _, _, _) => true  // 忽略SSL证书验证
  1. WebAPI客户端 - 用于调用后端API
services.AddHttpClient("WebAPI", ...)
    .BaseAddress = new Uri(apiAddress)  // 从配置读取API地址
    .ServerCertificateCustomValidationCallback = (_, _, _, _) => true

⚠️ 注意:这里禁用了SSL证书验证,仅应在开发/测试环境使用。

对象存储和网络服务

services.AddS3ObjectStorage();      // 添加腾讯云COS(S3兼容)
services.AddNetworkServices();      // 添加网络相关服务

单例服务

services.AddSingleton<AssetService>();  // 资产服务,全局共享实例

后台服务

services.AddHostedService<PageRouteCatalogScannerService>();  // 页面路由扫描服务
// services.AddHostedService<AssetUploadHostedService>();     // 已注释的资产上传服务

机器人防护

services.AddBotProtection(o => o.CheckBrowserVersion = true);  // 启用浏览器版本检查

2. AddMessageQueueServices 方法

配置消息队列相关服务:

// 注册消息消费者(处理特定类型的消息)
services.AddMessageConsumer<ClearCacheMessage, ClearCacheMessageHandler>();
services.AddMessageConsumer<RefreshUserProfileMessage, RefreshUserProfileMessageHandler>();

// 注册Outbox模式的消息重试工作线程
services.AddMessageOutboxRetryWorker();

功能说明

  • ClearCacheMessage: 清除缓存消息的处理器
  • RefreshUserProfileMessage: 刷新用户资料消息的处理器
  • Outbox重试机制: 确保消息可靠发送(事务性消息模式)

设计模式与最佳实践

  1. 扩展方法模式:通过扩展 IServiceCollection 提供链式调用
  2. 关注点分离:将不同功能的服务注册分组管理
  3. 配置外部化:API地址等配置从 IConfiguration 读取
  4. 依赖注入:遵循ASP.NET Core的DI容器规范
  5. 生命周期管理:合理使用 Scoped、Singleton 等生命周期

潜在问题

  1. SSL验证被禁用:生产环境应启用证书验证
  2. 硬编码字符串"WebApi" 配置键建议定义为常量
  3. 异常处理:API地址为空时抛出异常,可能需要更优雅的处理
评论加载中...