初始化我的aspx页面时,我在StructureMap容器中声明它(在OnInit内部)以将其注入适当的演示者:
container.Configure(x => x.For<IMyInterface>().HttpContextScoped().Use(this));
HttpContextScope应强制在当前请求结束时从容器中删除“this”(即页面对象)。为了证明这一点,我在上面的行之后添加了以下代码:
IEnumerable<InstanceRef> refs = container.Model.InstancesOf<IMyInterface>();
foreach (InstanceRef r in refs)
{
Type t = r.ConcreteType;
}
问题是:
为什么refs收集在每次回发中增加1?
它不仅会增加,而且r.ConcreteType不会引发任何异常 - 这意味着底层对象确实存在。页面被注入到演示者中,演示者本身在HttpContext范围内声明。
HttpContext范围似乎工作不正确,我做错了什么?
提前致谢
我已经考虑过了,结果如下。如果我将容器配置为创建我的类的新实例(它(配置)将只在Application_Start期间完成一次),容器将创建一个实例然后 - 在最后真正删除它的Http请求。但我只注册此类的现有实例。容器不是实例的所有者,因此它可能不会删除它 - 但配置会保留对它的引用(因此根本不能删除它)。另一方面,任何人都不会随时删除配置项(但在每个Http请求中都会添加)。
所以这一切都有效。当然,这是我对“HttpContextScoped”(以及其他一些东西:-()的误解。
所以,我正处于起点:有没有办法从配置中删除这样的注册?
将帖子 好像我无法删除这样的注册。解决方案是:使用手动属性注入替换自动构造函数注入。即:创建演示者(没有其视图)然后 - 手动设置视图:thePresenter.View = this; 上述注册没有添加,问题就不会出现了。
答案 0 :(得分:1)
这一行:
container.Configure(x => x.For<IMyInterface>().HttpContextScoped().Use(this));
具有误导性。它会让您认为您将其注册为HttpContextScoped
,但实际上它已注册为单身人士。
您可以使用lambda“创建”对象:
container.Configure(x => x.For<IMyInterface>().HttpContextScoped().Use(c => this));
lambda方法用于创建对象,但仍应适用正常的范围规则。事实上,如果你使用工厂,你甚至可能根本不需要范围规则(因为lambda被懒惰地评估)。