在StructureMap中,如何在运行时更改InstanceScope?

时间:2009-05-24 13:51:00

标签: c# dependency-injection inversion-of-control structuremap

在我的DefaultRegistry中,我有这样的配置:

ForRequestedType<INHUnitOfWork>().CacheBy(InstanceScope.HttpContext)
        .TheDefault.Is.OfConcreteType<NHibernateUnitOfWork>();

在Web应用程序流程中的某个时刻,我想将InstanceScope更改为HttpSession以获得长对话,所以我这样做:

PluginTypeConfiguration config = ObjectFactory.Model.PluginTypes.FirstOrDefault(p => p.PluginType.FullName.Contains("INHUnitOfWork"));
config.Lifecycle.EjectAll();
config.Lifecycle = StructureMap.Pipeline.Lifecycles.GetLifecycle(InstanceScope.HttpSession);

这似乎取代了最初的InstanceScope,遗憾的是它只能用于当前的请求。当下一个请求到达时,初始配置再次激活,会话信息丢失。

稍后我还希望能够通过以下方式恢复更改:

PluginTypeConfiguration config = ObjectFactory.Model.PluginTypes.FirstOrDefault(p => p.PluginType.FullName.Contains("INHUnitOfWork"));
config.Lifecycle.EjectAll();
config.Lifecycle = StructureMap.Pipeline.Lifecycles.GetLifecycle(InstanceScope.HttpContext);

但如果我让它在一个方向上工作,它可能会在两者中都有效。

是否可以在运行时永久替换初始InstanceScope?该如何实施? 另外,你认为这是一个很好的方式来获得一个长时间的对话,或者有一个更好/更简单的方法来使用StructureMap&amp; NHibernate的?

2 个答案:

答案 0 :(得分:1)

看看Ayende关于如何启用长时间运行对话和UnitOfWork的详细说明:

http://ayende.com/Wiki/Default.aspx?Page=HttpModules&AspxAutoDetectCookieSupport=1

我建议创建一个UnitOfWorkApplication模块,并让它负责创建一个UnitOfWork实例并在代码执行之前将其添加到容器中(在处理请求之前,如示例中所示)。通过这种方式,您可以更灵活地控制工作单元的创建方式。

答案 1 :(得分:0)

对我来说,你想要做的事情听起来有点奇怪。我试过的路线是

  • 在StructureMap中配置一个也实现所述接口的命名实例,但其范围不同。您可以为不同的接口使用者注入不同的依赖关系,这可能有帮助吗?
  • 编写自己的CacheInterceptor,有效地实现您的特定生命周期。

后者完成,例如这里是WCF生命周期:http://blogs.rpionline.com/post/2009/02/How-to-use-NHibernate-and-StructureMap-in-a-WCF-application.aspx