UnitOfWork (NHibernate), only one active UoW / session at a time? (need advice)

I am using NHibernate, DI / IoC and the work pattern.

In most UoW examples I've seen, make sure that there can only be one active UoW / session at a time, for example this and this .

Unfortunately, I still do not quite understand how I should handle two services that use UoW, but one calls the other.
Take this example:

Logger that uses UoW:

public class LoggerService : ILoggerService
{
    private ILoggerRepository repo;

    public LoggerService(ILoggerRepository Repo)
    {
        this.repo = Repo;
    }

    public void WriteLog(string message)
    {
        using (UnitOfWork.Start())
        {
            // write log
        }
    }
}

... and another service that also uses UoW AND calls the log:

public class PlaceOrderService : IPlaceOrderService
{
    private IOrderRepository repo;
    private ILoggerService service;

    public PlaceOrderService(IOrderRepository Repo, ILoggerService Service)
    {
        this.repo = Repo;
        this.service = Service;
    }

    public int PlaceOrder(int orderNumber)
    {
        using (UnitOfWork.Start())
        {           
            // do stuff

            this.service.WriteLog("Order placed!");  // will throw exception!!

            // do more stuff
        }
    }
}

UoW , UoW ( , , ), this.service.WriteLog PlaceOrder:
UoW, PlaceOrder, WriteLog , UoW - .

, ?
, - "" .

  • UoW LoggerService, , .
    , . using (UnitOfWork.Start()) LoggerService , LoggerService .
    , , LoggerService , UoW, LoggerService , .

  • , UoW.Start() :
    ) UoW,
    ) UoW, LoggerService AND , , UoW .
    .

( . , PlaceSpecialOrderService, , PlaceOrderService.PlaceOrder()...)

? !


EDIT:

.

, , .
, .

, .
, , PlaceSpecialOrderService, .

, , UoW - , :
, , , , , , , . , , - (: , , , ).

( UoW ) ?
UoW ?

+3
5

, .

, :

, UoW.Start() :
) UoW,
) UoW, LoggerService AND , , UoW .
.

, , , , UoW , .

- , - :-)
, .
UoW bool "isRootUnitOfWork".
():

if (HasActiveSession)
{
    isRootUnitOfWork = false;
    session = GetActiveSession();
}
else
{
    isRootUnitOfWork = true;
    session = CreateSession();
}

, . ... , - UoW.

+1

, , . UnitOfWork - "-", . - , ! ( , ).

+3

UOW , -. UOW. UOW HTTP WCF, MessageModule (, NserviceBus).

DI .

- - . log4net nlog , , , .

+2

, - . , - :

public int PlaceOrder(int orderNumber)
    {
        using (UnitOfWork.Start())
        {           
            repository.SaveOrder(order)

            repository.SaveOrderStatus(order,"Order placed")

        }
    }

, , ..

+2

I recommend starting and stopping your UnitOfWork outside the Services. I don't know the right tools for the .net world, but you should look for some Aspekt Oriented programming tools. Or, manually create a foreach wrapper service that starts only part of the work, then delegates the real service and then closes the work block. If one service calls another, it uses the actual implementation, not the unit of the work wrapper.

0
source

All Articles