UnitOfWork in Contrib - how do I get this to work?

20 views
Skip to first unread message

Dave Harms

unread,
Dec 2, 2009, 11:26:12 AM12/2/09
to S#arp Architecture
I'm using the Contrib approach to adding NH support to a web service,
and I'd like to use the UnitOfWork attribute but I can't seem to get
it working.

First, although the wiki talks about PostSharp, Tom's blog entry
(http://tomcabanski.spaces.live.com/blog/cns!E0D3617496209F45!
220.entry) says to ignore the PostSharp info for Windows Services.

But whether or not I include the PostSharp build task, I can't get
UnitOfWork to work. But maybe I'm not clear on the concept.

Let's say I have a method:

[UnitOfWork]
public void SomeMethod()
{
// do something
}

Presumably, if I'm not using a S#arpish repository and I need the
session, I use NHibernateSession.Current. Is that correct? Because I
can do that, only no transaction every gets initiated or committed.

From the blog entry, commits appear automatic unless I throw an
AbortTransactionException.

But even if this was working as expected I'd still have a concern. My
web service monitors a table in a database, looking for emails to
send. There's a lot I don't know about NHibernate sessions, but it
seems to me unwise to use a single session indefinitely. So what I'm
doing at present (in the absence of a working UnitOfWork) is wrapping
my periodic database access in a

using (var session = NHibernateSession.GetDefaultSessionFactory
().OpenSession())

call, and then manually creating and committing the transaction.

That works fine, but I'm concerned I'm missing out on some benefit of
the Contrib code. And I would like to know why UnitOfWork doesn't
appear to be doing anything. Thanks!

Tom Cabanski

unread,
Dec 2, 2009, 11:33:16 AM12/2/09
to sharp-arc...@googlegroups.com
Dave,

You have to get latest from the repo and build against the latest SharpArch.  Then you can use UnitOfWork.  UnitOfWork does both transaction and session management.  At the end of each unit of work, the session is closed so there is no reason to wrap things in another using.  

The version of UnitOfWork in the repo relies on Castle and does not use PostSharp at all.  However, because of the way castle interceptors work, you must define an interface, register it with castle and get your application service object via the service locator.  Castle will only intercept the methods that are defined in the registered interface.
---------------------------------------------------------
Tom Cabanski
Vice President of Technology
Onpoint On Demand (Houston Office)
4801 Woodway Drive
Suite 300 East
Houston, TX 77056
832-766-5961
http://www.onpointod.com



--

You received this message because you are subscribed to the Google Groups "S#arp Architecture" group.
To post to this group, send email to sharp-arc...@googlegroups.com.
To unsubscribe from this group, send email to sharp-architect...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sharp-architecture?hl=en.



Dave Harms

unread,
Dec 2, 2009, 11:42:10 AM12/2/09
to S#arp Architecture
Thanks Tom, will do. And do I use NHibernateSession.Current?

Dave

On Dec 2, 10:33 am, Tom Cabanski <t...@cabanski.com> wrote:
> Dave,
>
> You have to get latest from the repo and build against the latest SharpArch.
>  Then you can use UnitOfWork.  UnitOfWork does both transaction and session
> management.  At the end of each unit of work, the session is closed so there
> is no reason to wrap things in another using.
>
> The version of UnitOfWork in the repo relies on Castle and does not use
> PostSharp at all.  However, because of the way castle interceptors work, you
> must define an interface, register it with castle and get your application
> service object via the service locator.  Castle will only intercept the
> methods that are defined in the registered interface.
> ---------------------------------------------------------
> Tom Cabanski
> Vice President of Technology
> Onpoint On Demand (Houston Office)
> 4801 Woodway Drive
> Suite 300 East
> Houston, TX 77056
> 832-766-5961http://www.onpointod.com
> > sharp-architect...@googlegroups.com<sharp-architecture%2Bunsubs­cr...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/sharp-architecture?hl=en.- Hide quoted text -
>
> - Show quoted text -

Tom Cabanski

unread,
Dec 2, 2009, 3:00:51 PM12/2/09
to sharp-arc...@googlegroups.com
The following is an example from a Windows service I am working on. This class is registered with castle as the implementation of the interface and it is instantiated ands called in the service container like this:

var pollerService = ServiceLocator.Current.GetInstance<IPollerService>();
pollerService.Poll();

The class has dependencies on a repository and another service that both get taken care of by Castle.  The interface simply defines the Poll() method.  The UnitOfWork takes care of wrapping a transaction and closing the session at the end.  The session will get re-opened the next time somebody uses it.  Note that services should use ThreadSessionStorage from Contrib as defined in the docs.  Here's the class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Symbio.Printable.Core.DataInterfaces;
using SharpArchContrib.Core;
using log4net;
using Symbio.Printable.Core;
using SharpArchContrib.Castle.NHibernate;

namespace Symbio.Printable.ApplicationServices.Poller {
    public class SymbioOrderCreatorPollingService : IPollerService {
        private IOrderRepository orderRepository;
        private ISymbioOrderCreatorService symbioOrderCreatorService;
        private ILog logger = LogManager.GetLogger(typeof(SymbioOrderCreatorPollingService));

        public SymbioOrderCreatorPollingService(IOrderRepository orderRepository, ISymbioOrderCreatorService symbioOrderCreatorService) {
            ParameterCheck.ParameterRequired(orderRepository, "orderRepository");
            ParameterCheck.ParameterRequired(symbioOrderCreatorService, "symbioOrderCreatorService");

            this.orderRepository = orderRepository;
            this.symbioOrderCreatorService = symbioOrderCreatorService;
        }

        public string DescriptiveName { get; set; }

        [UnitOfWork]
        public void Poll() {
            logger.Info("Polling for order to send to Symbio");
            var orders = orderRepository.GetOrdersToSendToSymbio();
            logger.InfoFormat("There are {0} orders to send to Symbio", orders.Count());
            foreach (var order in orders) {
                var polledOrder = new PolledOrder(order.PrintableInstance.Id, order.PrintableOrderId, order.OrderXml);
                var result = symbioOrderCreatorService.CreateSymbioOrder(polledOrder, order.PrintableInstance);
                if (result.IsSuccess) {
                    logger.DebugFormat("Order {0} successfully created Symbio order {1}", order.PrintableOrderId, result.SymbioOrderId);
                    order.SymbioOrderId = result.SymbioOrderId;
                    order.UtcDateTimeSentToSymbio = DateTime.UtcNow;
                    order.ErrorMessage = null;
                }
                else {
                    order.ErrorMessage = result.ErrorMessage;
                }
                orderRepository.SaveOrUpdate(order);
            }
        }
    }
}


---------------------------------------------------------
Tom Cabanski


To unsubscribe from this group, send email to sharp-architect...@googlegroups.com.

Dave Harms

unread,
Dec 2, 2009, 5:12:22 PM12/2/09
to S#arp Architecture
Thanks Tom, much appreciated. The reason I asked about the session var
is that I'm finding I use the Criteria API a fair bit. Although I like
the repository pattern, I'm not so excited about the idea of having a
bazillion repository methods to cover every eventuality. Ironically
I'm very happy with the abstraction NH gives me<g>. And I'm keeping my
eyes open, knowing that someday I may want to swap out NH for
something else.

Dave
> > > >http://groups.google.com/group/sharp-architecture?hl=en.-Hide quoted

Tom Cabanski

unread,
Dec 2, 2009, 6:53:34 PM12/2/09
to sharp-arc...@googlegroups.com
Yep, you can use the current session inside a UnitOfWork.

The idea behind the repository pattern is to keep a layer of abstraction between the application and the data access technology.   I tend to use Linq to NHibernate quite a bit now but used criteria in the past.  I've always used repositories and it has not really been much of a burden.  If you're doing reporting, you should look at some of the things Billy has been talking about in terms of command query.  

---------------------------------------------------------
Tom Cabanski
Vice President of Technology
Onpoint On Demand (Houston Office)
4801 Woodway Drive
Suite 300 East
Houston, TX 77056
832-766-5961
http://www.onpointod.com


To unsubscribe from this group, send email to sharp-architect...@googlegroups.com.

Dave Harms

unread,
Dec 3, 2009, 10:20:03 AM12/3/09
to S#arp Architecture
Yep, I follow the concept.

Is there anything about the Criteria API you miss in L2NH? Any
gotchas?

Dave

On Dec 2, 5:53 pm, Tom Cabanski <t...@cabanski.com> wrote:
> Yep, you can use the current session inside a UnitOfWork.
>
> The idea behind the repository pattern is to keep a layer of abstraction
> between the application and the data access technology.   I tend to use Linq
> to NHibernate quite a bit now but used criteria in the past.  I've always
> used repositories and it has not really been much of a burden.  If you're
> doing reporting, you should look at some of the things Billy has been
> talking about in terms of command query.
> ---------------------------------------------------------
> Tom Cabanski
> Vice President of Technology
> Onpoint On Demand (Houston Office)
> 4801 Woodway Drive
> Suite 300 East
> Houston, TX 77056
Reply all
Reply to author
Forward
0 new messages