views:

244

answers:

2

In my DefaultRegistry I have this configuration:

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

At some point in the web application flow I want to change the InstanceScope to HttpSession to obtain a long conversation, so I do this:

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

This seems to replace the initial InstanceScope, unfortunately it lasts only for the current request. When the next request arrives, the initial configuration is active again and the session information is lost.

Later I also want to be able to revert the change with something like this:

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

but if I will make it work in one direction it will probably work in both.

Is it possible to replace the initial InstanceScope permanently at runtime? How should this be implemented? Also, do you think this a good way to obtain a long conversation or there is a better / simpler way to do it with StructureMap & NHibernate?

+1  A: 

Take a look at Ayende's detailed explanation on how to enable long running conversations and UnitOfWork:

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

I would recommend creating a UnitOfWorkApplication module and make it responsible for creating a UnitOfWork instance and adding it to the container before your code executes (before the request is processed, like in the example). This way you have more flexibility and control over how unit of work is created.

bbmud
Creating a UnitOfWorkApplication class to handle the UnitOfWork creation and letting StructureMap inject UnitOfWorkApplication instances instead of UnitOfWork instances solved the problem. Thanks a lot, your explanation was exactly what I needed.
abutnaru
A: 

It sounds slightly strange to me what you are trying to do. Routes I'd try would be

  • Configure a named instance in StructureMap that also implements said interface but is scoped differently. You can inject different dependencies for different interface consumer, maybe that helps?
  • Write your own CacheInterceptor that effectively implements your specific lifecycle.

The latter is done e.g. here for WCF lifecycle: http://blogs.rpionline.com/post/2009/02/How-to-use-NHibernate-and-StructureMap-in-a-WCF-application.aspx

flq