Simple Injector如何在Scoped生命周期下多次复用同一装饰器类
解决方案
方案1:派生空装饰器子类(推荐)
通过派生两个仅身份不同、逻辑完全复用原有埋点装饰器的空类,绕开同实现类型多次注册的冲突检测,无侵入性且不需要修改验证逻辑:
// 内层埋点装饰器,统计Target本身耗时 public class InnerInstrumentationTargetDecorator : InstrumentationTargetDecorator { public InnerInstrumentationTargetDecorator(ITarget target) : base(target) { } } // 外层埋点装饰器,统计包含容错逻辑的全链路耗时 public class OuterInstrumentationTargetDecorator : InstrumentationTargetDecorator { public OuterInstrumentationTargetDecorator(ITarget target) : base(target) { } }
调整注册逻辑即可消除警告:
container.Register<ITarget, Target>(Lifestyle.Scoped); // 注册顺序从内到外 container.RegisterDecorator( typeof(ITarget), typeof(InnerInstrumentationTargetDecorator), Lifestyle.Scoped); container.RegisterDecorator( typeof(ITarget), typeof(ResilienceTargetDecorator), Lifestyle.Scoped); container.RegisterDecorator( typeof(ITarget), typeof(OuterInstrumentationTargetDecorator), Lifestyle.Scoped);
方案2:批量抑制指定诊断警告
如果不想新增子类,可以直接遍历容器诊断结果,针对性抑制所有和InstrumentationTargetDecorator相关的歧义生命周期警告:
// 先执行预验证生成诊断结果 container.Verify(VerificationOption.VerifyOnly); // 筛选所有目标警告 var relatedWarnings = container.GetDiagnosticResults() .Where(res => res.DiagnosticType == DiagnosticType.AmbiguousLifestyles && res.ImplementationType == typeof(InstrumentationTargetDecorator)); // 批量抑制 foreach (var warning in relatedWarnings) { warning.Suppress("预期复用同一埋点装饰器统计分层耗时,无生命周期冲突风险"); } // 执行最终验证 container.Verify();
原因说明
SimpleInjector的诊断逻辑默认假设同一个实现类型的装饰器只会注册一次,多次注册时会将两个装饰器的注册实例误判为存在生命周期冲突的不同服务注册,哪怕两次注册指定了完全相同的生命周期,也会触发Ambiguous Lifestyles警告。
内容的提问来源于stack exchange,提问作者ambidexterous
相关产品推荐
相关产品推荐

