在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
相关产品推荐
相关产品推荐

