views:

226

answers:

1

I've implemented some components to use WCF with both an IoC Container (StructureMap) and the Session per Call pattern. The NHibernate stuff is most taken from here: http://realfiction.net/Content/Entry/133.

It seems to be OK, but I want to open a transaction with each call and commit at the end, rather than just Flush() which how its being done in the article.

Here's where I am running into some problems and could use some advice. I haven't figured out a good way to rollback. I realize I can check the CommunicationState and if there's an exception, rollback, like so:

        public void Detach(InstanceContext owner)
        {
            if (Session != null)
            {
                try
                {
                    if(owner.State == CommunicationState.Faulted)
                        RollbackTransaction();
                    else
                        CommitTransaction();
                }
                finally
                {
                  Session.Dispose();  
                }

            }
        }

       void CommitTransaction()
        {
            if(Session.Transaction != null && Session.Transaction.IsActive)
                Session.Transaction.Commit();
        }

        void RollbackTransaction()
        {
            if (Session.Transaction != null && Session.Transaction.IsActive)
                Session.Transaction.Rollback();
        }

However, I almost never return a faulted state from a service call. I would typically handle the exception and return an appropriate indicator on my response object and rollback the transaction myself.

The only way I can think of handling this would be to inject not only repositories into my WCF services, but also an ISession so I can rollback and handle the way I want. That doesn't sit well with me and seems kind of leaky.

Anyone else handling the same problem?

A: 

After further consideration, it seems like the only way to handle this is to inject the ISession into my service. The session is the same one injected to all my repositories and since a WCF service is an Application Service, I've decided it's not really leaky or bad to allow my service to manage the transactions. In fact, that's the whole purpose of an application service - coordinate between infrastructure and domain.

I still get many benefits from using the techniques in this article http://realfiction.net/Content/Entry/133, I'm just not going to implement the automatic transaction start/commit/rollback.

Corey Coogan