0

初始化我的 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; 没有添加上述注册,问题只是没有出现。

4

1 回答 1

1

这一行:

container.Configure(x => x.For<IMyInterface>().HttpContextScoped().Use(this));

具有误导性。它使您认为您将其注册为,HttpContextScoped但实际上它已注册为单例。

您可以使用 lambda 来“创建”对象:

container.Configure(x => x.For<IMyInterface>().HttpContextScoped().Use(c => this));

lambda 方法用于创建对象,但仍应适用正常的范围规则。事实上,如果你使用工厂,你甚至可能根本不需要范围规则(因为 lambda 是懒惰地评估的)。

于 2012-08-11T01:03:33.603 回答