The power of WCF behaviors 1 – Operation Behavior

The typical NHibernate WCF service method should look like this:

NHibernate.Session.Transaction.Begin();
DomainService.DoWork();
NHibernate.Session.Transaction.Commit();
// Rollback if exception happened.

This piece of code will appear in every service method, but the transaction setup/teardown code is exactly the same.

IglooCoder.Commons library can extract those setup/teardown code into NHibernateContext extension. The method will be simplified to:

[NHibernateContext(Rollback.Automatically)]
public class Service : IService{
    pulic void DoWork(){
       DomainService.DoWork();
    }
}

Cool! But, what about Exception thrown by Session.Commit()? We need to handle some database exception, like validation, security errors, and leave the else to UnhandleDatabaseException. Explain it in code, we need this piece of code triggered when GenericADOException happened.

        public void HandleDatabaseException(Exception ex)
        {
            if (ex is GenericADOException)
            {
                if (ex.InnerException.GetType() == typeof (SqlException))
                {
                    SqlException sqlEx = (SqlException) ex.InnerException;
                    // convert validation error to ValidationException
                     ...
                    // convert security error to SecurityException
                     ...
                    // re-throw a new exception to allow client display/report it
                    throw new MyUnhandledDatabaseException(sqlEx.Message, sqlEx);
                }
            }
            throw ex;
        }

We could put it into our baseRepository class, but due to NHibernate auto flush feature, NH won’t issue the sql command for most of the update() operations, until the Flush()/Commit() called. see details

Adding a flush() to each Repository method is very ugly.

We can use WCF OperationBehavior to make this happen.

OperationBehavior

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)<br />
        {
            foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)<br />
            {
                foreach (var endpoint in channelDispatcher.Endpoints)
                {
                    foreach (var dispatchOperation in endpoint.DispatchRuntime.Operations)
                    {
                        dispatchOperation.ParameterInspectors.Add(new NHibernateTransactionCommiter());
                        dispatchOperation.ParameterInspectors.Add(new EvilEntityValidator());
                    }
                }
            }
        }
Advertisements

One thought on “The power of WCF behaviors 1 – Operation Behavior

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s