You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构造函数注入API代理与添加作用域服务的性能对比

两种LogicAPI实现方式的优劣对比分析

我们目前同时采用两种LogicAPI的实现方式,想了解二者在性能等方面的优劣差异,以下是具体对比:

性能差异

从性能角度看,两者几乎没有本质区别:

  • 示例1通过DI容器的Scoped生命周期注册,每个HTTP请求会创建一个新的LogicAPI实例;
  • 示例2在控制器构造函数中直接实例化,同样是每个请求创建一次实例。

唯一需要注意的是示例1中使用了IHttpClientFactory来创建HttpClient,它会自动管理HttpClient的连接池,避免频繁创建销毁导致的socket资源耗尽问题。如果示例2中的SurveyApiSettings是直接创建HttpClient而非复用连接池,长期运行可能会出现性能瓶颈。

可维护性与扩展性

  • 示例1采用依赖注入,控制器依赖的是抽象接口ILogicAPI而非具体实现类,符合依赖倒置原则。后续如果需要替换LogicAPI的实现(比如换成MockLogicAPI、CachedLogicAPI),只需要修改DI注册代码,不需要改动控制器,扩展性极强。
  • 示例2直接在控制器中new具体类,代码耦合度极高。一旦LogicAPI的构造函数参数变化或者需要替换实现,所有手动实例化的控制器都要逐一修改,维护成本随着项目规模扩大急剧上升。

测试友好性

  • 示例1的方式天生适合单元测试:在测试时可以轻松注入ILogicAPI的Mock对象,完全隔离真实业务逻辑,快速验证控制器的逻辑正确性。
  • 示例2直接实例化具体类,单元测试时无法隔离依赖,必须依赖LogicAPI的真实实现(甚至可能依赖外部服务),测试速度慢、不稳定,还容易出现测试污染。

依赖管理与生命周期控制

  • 示例1由DI容器统一管理所有依赖:如果LogicAPI后续新增了依赖(比如需要IConfiguration、ILogger),只需要在注册时添加对应的服务,控制器代码完全不需要修改,容器会自动注入所有依赖。同时如果LogicAPI实现了IDisposable,容器会在请求结束后自动调用Dispose方法释放资源,避免内存泄漏。
  • 示例2需要手动管理所有依赖:每次新增依赖都要在控制器构造函数中手动传递,容易遗漏;如果LogicAPI需要释放资源,还要手动在控制器中处理,增加了出错的风险。

总结

如果只看性能,两种方式差异极小,但从长期维护、测试、扩展性角度来看,示例1的依赖注入方式绝对是更优选择。示例2的硬编码实例化方式只适合极小的Demo项目,在生产环境中会带来大量技术债,建议逐步统一为DI注入的实现方式。

示例代码

示例1:将ILogicAPI注入控制器构造函数

注册服务代码:

services.AddScoped<ILogicAPI, LogicAPI>(sp =>
{
    var httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient();
    return new LogicAPI(surveyConfig.SurveyApiProxyConfiguration(httpClient));
});

控制器代码:

public AssessmentController(
    SurveyUIConfiguration configuration,
    IAssessmentAPI assessmentApi,
    ISurveyReviewAPI surveyReviewApi,
    IAnswerAPI answerApi,
    ITakerScreenAPI screenApi,
    ILogicAPI logicApi,
    IMasterSurveyErrorMessageTextsAPI errorAPI
)
{
    this.assessmentApi = assessmentApi;
    this.surveyReviewApi = surveyReviewApi;
    this.answerApi = answerApi;
    viewModelService = new ViewModelService(configuration, answerApi, screenApi, logicApi, errorAPI);
}

示例2:在控制器中实例化LogicAPI

控制器代码:

public AssessmentController(
    IMasterSurveyErrorMessageTextsAPI errorAPI,
    IBaseSurveyControllerServices services
) : base(services)
{
    this.assessmentApi = new AssessmentAPI(SurveyApiSettings);
    this.surveyReviewApi = new SurveyReviewAPI(SurveyApiSettings);
    this.answerApi = new AnswerAPI(SurveyApiSettings);
    var screenApi = new TakerScreenAPI(SurveyApiSettings);
    var logicApi = new LogicAPI(SurveyApiSettings);
    viewModelService = new ViewModelService(Configuration, answerApi, screenApi, logicApi, errorAPI);
}

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:07:20