当前位置: 首页 > news >正文

.Net 中的 ActivatorUtilitiesConstructor 特性

.Net 中的 ActivatorUtilitiesConstructor 特性

[ActivatorUtilitiesConstructor]是 .NET 依赖注入中的一个特性,用于指导 Microsoft.Extensions.DependencyInjection(MSDI)在类型有多个构造函数时,选择哪个构造函数进行实例化。

主要用途

1.解决构造函数选择歧义

当一个类有多个构造函数时,MSDI 默认选择参数最多且都能从容器中解析的构造函数。但有时这会导致问题:

publicclassMyService{// 默认情况下,DI 会选择这个构造函数(参数最多)publicMyService(IService1s1,IService2s2,stringconfigValue){// configValue 无法从容器解析,会抛出异常!}// 实际上我们想用这个publicMyService(IService1s1,IService2s2){// 只有可解析的参数}}

2.明确指定构造函数

使用[ActivatorUtilitiesConstructor]明确告诉 DI 使用哪个:

publicclassMyService{publicMyService(IService1s1,IService2s2,stringconfigValue){// 这个不会被 DI 使用}[ActivatorUtilitiesConstructor]publicMyService(IService1s1,IService2s2){// DI 会优先使用这个构造函数}}

工作原理

  1. 标记优先级:标记的构造函数会被优先考虑
  2. 兼容性检查:只考虑标记的构造函数能否从容器解析所有参数
  3. 回退机制:如果标记的构造函数参数无法全部解析,会尝试其他构造函数

常见场景

场景1:有可选参数时

publicclassReportService{privatereadonlyILogger_logger;privatereadonlystring_format;publicReportService(ILogger<ReportService>logger){_logger=logger;_format="Default";}[ActivatorUtilitiesConstructor]publicReportService(ILogger<ReportService>logger,IOptions<ReportOptions>options){_logger=logger;_format=options.Value.Format;}}

场景2:第三方库扩展

// 扩展第三方库的类publicclassExtendedThirdPartyService:ThirdPartyService{// 第三方库可能没有无参构造函数publicExtendedThirdPartyService():base("default"){}[ActivatorUtilitiesConstructor]publicExtendedThirdPartyService(IConfigurationconfig):base(config.GetValue<string>("ApiKey")){}}

使用注意事项

1.仅用于ActivatorUtilities.CreateInstance

// 这个特性主要影响以下方法:varinstance=ActivatorUtilities.CreateInstance<MyService>(serviceProvider);varinstance=ActivatorUtilities.CreateInstance(serviceProvider,typeof(MyService));

2.与直接容器解析的区别

// 使用特性 - 受 [ActivatorUtilitiesConstructor] 影响services.AddTransient<MyService>();varservice=serviceProvider.GetService<MyService>();// 直接注册实例工厂 - 不使用该特性services.AddTransient(sp=>newMyService("hardcoded"));

3.多个标记会报错

publicclassBadExample{[ActivatorUtilitiesConstructor]publicBadExample(IService1s1){}[ActivatorUtilitiesConstructor]// ❌ 运行时错误:多个标记publicBadExample(IService2s2){}}

实际示例

publicclassPaymentProcessor{privatereadonlyIPaymentGateway_gateway;privatereadonlybool_useSandbox;// 用于测试或特定场景publicPaymentProcessor(IPaymentGatewaygateway){_gateway=gateway;_useSandbox=false;}// 生产环境使用 - 从配置读取[ActivatorUtilitiesConstructor]publicPaymentProcessor(IPaymentGatewaygateway,IConfigurationconfig){_gateway=gateway;_useSandbox=config.GetValue<bool>("Payment:UseSandbox");}}// 注册services.AddScoped<IPaymentGateway,StripeGateway>();services.AddScoped<PaymentProcessor>();// 使用时,DI 会自动选择带 [ActivatorUtilitiesConstructor] 的构造函数

替代方案

如果不想使用特性,也可以:

  1. 使用工厂方法注册
services.AddScoped(sp=>newMyService(sp.GetRequiredService<IService1>(),sp.GetRequiredService<IService2>()));
  1. 简化设计(推荐):尽量保持单个构造函数,使用 Options 模式处理配置。

总结

[ActivatorUtilitiesConstructor]是一个解决构造函数选择问题的工具,但在良好设计的应用中应该很少需要。优先考虑通过单一构造函数Options 模式来简化设计,这会使代码更清晰且易于测试。

http://www.cnnetsun.cn/news/636530.html

相关文章:

  • 什么是SR-MPLS
  • 救命神器10个一键生成论文工具,专科生毕业论文轻松搞定!
  • gru 记忆是记当前episode的内容吗
  • 全网最全本科生必用TOP10 AI论文网站测评
  • django基于python的旅游服务管理系统
  • 653653
  • 人行道检测数据集介绍-3819张图片 智慧城市管理 自动驾驶辅助系统 无障碍导航应用 城市规划与设计 智能监控系统 移动机器人导航
  • 还在为高AI率烦恼?6款亲测有效的降AI工具推荐,手把手教你ai率轻松降到10%以下
  • 大数据脱敏与数据匿名化的区别与联系
  • 【毕业设计】基于python-CNN深度学习卷神经网络的常见中草药识别
  • 【毕业设计】基于python-CNN深度学习的水稻是否伏倒识别
  • Java毕设项目推荐-基于java的车辆违章信息管理系统的设计与实现基于JavaEE的车辆违章信息管理系统的设计与实现【附源码+文档,调试定制服务】
  • 深度学习毕设项目推荐-基于python-pytorch训练识别舌头是否健康
  • 亲测好用9个AI论文工具,继续教育学生轻松写论文!
  • 深度学习计算机毕设之基于python深度学习人工智能的道路车辆内有无佩戴安全带识别
  • 【C++入门】编译期的代码义体植入——【inline内联函数】(宏定义的面试考点)(C++分文件编写的知识点)
  • Java毕设项目推荐-基于SpringBoot+Vue的旅游管理系统涵盖旅游攻略、酒店、美食、景点等管理功能【附源码+文档,调试定制服务】
  • 计算机Java毕设实战-基于SpringBoot的养老服务平台设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • vue基于python的宠物领养付费系统
  • 什么是SPFC
  • UNC团队“零数据“突破:AI智能体从无到有自我进化的奇迹
  • 港中大联合研究揭示:AI视觉语言模型存在严重安全漏洞
  • atl90.dll文件丢失找不到怎么办? 免费下载方法分享
  • 大数据领域MongoDB的集群搭建与管理指南
  • 【毕业设计】基于Springboot的体育赛事视频管理系统(源码+文档+远程调试,全bao定制等)
  • (新卷,100分)- 矩阵稀疏扫描(Java JS Python C)
  • 特价股票与公司现金流管理效率的关系
  • Coding Agent 中 Skills、MCP、Prompt、SubAgent 的基本概念和定义
  • 【车间调度】基于粒子群算法求解置换流水车间调度问题PFSP附Matlab代码
  • 【计算机毕业设计案例】基于JavaSpribgBoot的水果生鲜团购平台基于SpribgBoot的生鲜团购平台(程序+文档+讲解+定制)