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

在WebForm中使用DryIoc遇到实例复用异常问题

问题分析与解决方案

你当前的核心问题是混淆了DryIoc中Scoped和Singleton复用策略的区别,代码设置的复用模式和你的Singleton期望不匹配:

为什么当前代码不符合预期?

你把容器默认复用设为Reuse.Scoped,这种策略的规则是:同一个Scope内获取的实例唯一,不同Scope会生成新实例。而你想要的Singleton是整个容器生命周期内仅存在一个实例,两者逻辑完全不同。

另外看你的测试代码,在同一个using (var scope = container.OpenScope())块内两次Resolve<ScopeService>,理论上应该得到同一个实例。如果实际还是不同,检查ScopeService是否有以下情况:

  • 注册时被显式指定了Reuse.Transient(覆盖了默认Scoped)
  • 类构造函数或内部逻辑是否有强制生成新实例的操作

实现Singleton复用的两种方法

方法一:设置容器默认复用为Singleton

修改容器初始化代码,将默认复用改为Reuse.Singleton:

var container = new Container(rules => rules.WithDefaultReuse(Reuse.Singleton));
container.Register<ScopeService>();

// 无论是否开启Scope,获取的都是同一个实例
var oSingleton = container.Resolve<ScopeService>();
var oSingleton2 = container.Resolve<ScopeService>();

using (var scope = container.OpenScope())
{
    var scopedSingleton = scope.Resolve<ScopeService>();
    // scopedSingleton 和 oSingleton 是同一个实例
}

方法二:注册服务时显式指定Singleton复用

如果不想修改容器默认复用,注册服务时单独指定Singleton策略:

var container = new Container(); // 默认复用是Transient
container.Register<ScopeService>(Reuse.Singleton);

// 多次Resolve都会得到同一个实例
var oSingleton = container.Resolve<ScopeService>();
var oSingleton2 = container.Resolve<ScopeService>();

WebForm场景额外提示

在WebForm中,更常用的是请求级别的Scoped复用(每个请求对应一个实例),如果需要这种模式,要集成DryIoc与WebForm的请求生命周期:

  • 借助HttpContext.Current在请求开始时创建Scope,请求结束时释放
  • 使用DryIoc.Web包提供的Reuse.InWebRequest来注册服务,确保每个请求内实例唯一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:17:05