pondělí 3. března 2014

Sharing an instance of uow inside one http request


In previous blog posts we outlined a solution with EF, DI and unit of work pattern. This post describes how to configure a particular DI container for sharing an instance of uow in one http request. We use Spring.NET as a DI container, it’s configuration sits in a external xml file. Most of DI containers does offer similar scoping capabilities, I’m showing here only how to do it in spring.

First of all, the DI container needs to be configured as a web aware container, instead standard ContextHandler from sping.core user WebContextHandler from Spring.Web.


<sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
      <!--<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />-->
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
      <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
 </sectionGroup>

Next, set the context type to WebApplicationContext:
<spring>
    <context type="Spring.Context.Support.WebApplicationContext, Spring.Web">
    <!--<context>-->
      <resource uri="~/objects.config" />
   <parsers>
      <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" />
    </parsers>
</spring>

Add a new Http module to the web application.
<modules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</modules>

This was only a required configuration burden In order to have the request scoping working in spring.net.

Spring has a configuration property at the level of object definition named scope which we can set to request value. The request value means that the container will supply the same instance of object during one http request to every client who asks for it. Detailed description is here:

An example of a particular object is below.

<object id="HighRiskPersonDbContext" type="Aegon.Xing.Modules.PortalServices.DAL.Database.HighRiskPersonDbContext, Aegon.Xing.Modules.PortalServices.DAL" singleton="false" scope="request" />
       
      <object id="IHighRiskPersonServiceUoW" type="Aegon.Xing.Modules.PortalServices.DAL.UOW.HighRiskPersonUoW, Aegon.Xing.Modules.PortalServices.DAL" singleton="false" scope="request" >
          <constructor-arg name="dbContext" ref="HighRiskPersonDbContext" />
      </object>
<object id="IHighRiskPersonService" type="Aegon.Xing.Modules.PortalServices.Services.HighRiskPerson.HighRiskPersonService, Aegon.Xing.Modules.PortalServices" singleton="false">
          <constructor-arg name="uow" ref="IHighRiskPersonServiceUoW" />
      </object>

When DI is asked for an instance of IHighRiskPersonService it injects an instance of IHighRiskPersonServiceUow into it which is request scoped. It means that if the DI is asked twice during one request for an instance of IHighRiskService the same instance of IHighRiskPersonServiceUow will be injected.  Actually you can have other object definitions having dependency on IHighRiskPersonServiceUow too, in one request, all their instances will share the same instance of IHighRiskPersonServiceUow (=database in this case).

Žádné komentáře:

Okomentovat