Tuesday, May 27, 2008

Peter works on the web!

It seems that I managed to convince another one of my dear colleagues to start blogging (if my children thaught me one thing, it's that constant whining actually works!). Peter Eysermans, a real genius and quite popular with the ladies, has started a blog. The Internet has been an insignificant piece of network cable until this very day. If you're into web development, Brazilian waxing or unlimited self-cheering, then you definitely want to follow his blog ;-).

From your humble servant,

Jan

Wednesday, May 21, 2008

I'm on ...

... Twitter. Why? Because all the cool kids are doing it ;-) (yep, I have no spine). Let's see where this goes.

Sunday, May 18, 2008

Integrating Castle Windsor and NHibernate with WCF

Up until now, we were using the NHibernate facility of Castle Windsor for managing our NHibernate sessions in WCF. But, we want to have a session-per-request approach as one would use when integrating NHibernate with a regular web application.

Yesterday I did a small spike to figure out how this should work. It turned out to be pretty easy. I used this excellent blog post written by Oran Dennison as my guide.

First I created a class that implemented the IServiceBehavior interface.

public class DIServiceBehavior : IServiceBehavior { private readonly ISessionFactory _sessionFactory; public DIServiceBehavior() { _sessionFactory = new Configuration() .Configure() .BuildSessionFactory(); XmlConfigurator.Configure(); // Log4Net } public void ApplyDispatchBehavior( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach(ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) { ChannelDispatcher cd = cdb as ChannelDispatcher; if(cd != null) { foreach(EndpointDispatcher ed in cd.Endpoints) { ed.DispatchRuntime.InstanceProvider = new DIInstanceProvider (serviceDescription.ServiceType, _sessionFactory); } } } } public void AddBindingParameters( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } }

The SessionFactory is created in the constructor because the ApplyDispatchBehaviour method can be called multiple times (for each endpoint).

The next step is to create an instance provider by creating a class that implements the IInstanceProvider:

public class DIInstanceProvider : IInstanceProvider { private const String NHibernateSessionKey = "NHibernate.Session"; private readonly Type _serviceType; private IDependencyContainer _dependencyContainer; private readonly ISessionFactory _sessionFactory; private ISession _session; public DIInstanceProvider(Type serviceType, ISessionFactory sessionFactory) { Debug.Assert(null != serviceType, "null != serviceType"); _serviceType = serviceType; Debug.Assert(null != sessionFactory, "null = sessionFactory"); _sessionFactory = sessionFactory; } public Object GetInstance(InstanceContext instanceContext) { return GetInstance(instanceContext, null); } public Object GetInstance(InstanceContext instanceContext, Message message) { _dependencyContainer = new DependencyContainer(); _session = _sessionFactory.OpenSession(); _dependencyContainer .AddComponentInstance(NHibernateSessionKey, _session); return _dependencyContainer.Resolve(_serviceType); } public void ReleaseInstance(InstanceContext instanceContext, Object instance) { if(null != _session) { _session.Close(); _session = null; } if(null != _dependencyContainer) { _dependencyContainer.Dispose(); _dependencyContainer = null; } } }

I created a wrapper class around for Castle Windsor named DependencyContainer.  The GetInstance method opens a new session using the SessionFactory object we instantiated in the service behavior class. The session object is then registered with Castle Windsor. We can now implement our repositories like this:

public class SomeAggregateRepository { private ISession _session; public SomeAggregateRepository(ISession session) { _session = session; } public SomeAggregate Get(Int64 id) { return _session.Get<SomeAggregate>(id); } }

When our service operation has been executed, the NHibernate is released by the ReleaseInstance method. Finishing our example, we need to implement a custom ServiceHost and a ServiceHostFactory:

public class DIServiceHost : ServiceHost { public DependencyInjectionServiceHost() : base() { } public DIServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void OnOpening() { Description.Behaviors.Add(new DIServiceBehavior()); base.OnOpening(); } } public class DIServiceHostFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost( Type serviceType, Uri[] baseAddresses) { return new DIServiceHost(serviceType, baseAddresses); } }

The custom ServiceHostFactory class can now be used in the ServiceHost file required when doing IIS hosting:

<%@ ServiceHost Language="C#" Debug="true" Service="WindsorService.MyWindsorService" Factory="WindsorService.DIServiceHostFactory" CodeBehind="MyWindsorService.svc.cs" %>

There is also another way for achieving this that I will be investigating the next week or so using the WCF Integration Facility for Castle Windsor. For some reason it is not available in the current release of the Castle stack so I have to grab it from the trunk.

If you have any thoughts, improvements or suggestions I'm glad to hear them from you, my dear reader. It's the only way I'll ever learn :-).

Till next time.

Thursday, May 15, 2008

Implementing NHibernate Interceptors

One of the areas where NHibernate really shines is it's high extensibility features. The NHibernate API provides a massive amount of interfaces that can be implemented for your own custom extension pleasure.

For me this is a nice change as opposed to the many sealed API's put out by the Redmond collective (WCF being the exception, the Entity Framework confirming the rule).

Anyhow, with great power comes great responsibility. Today I encountered a rather difficult problem with NHibernate that could have been easily prevented by reading the documentation (note to self: use the CTRL-Q shortcut of Resharper more often).

We have implemented an interceptor for automatically configuring audit information as described by this great post from Ray Houston.

public class AuditInformationInterceptor : EmptyInterceptor { Boolean OnSave(Object entity, Object id, Object[] state, String[] propertyNames, IType[] types) { // Implementation } Boolean OnFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, IType[] types) { // Implementation } }

The mistake we made is that we manipulated the audit information of the entity directly in the OnSave and OnFlushDirty methods. This only became apparent when saving an aggregate root with his child entities. Everything worked fine until we wanted to persist one of the child entities that should have been a piece of cake but turned out to be the messenger of trouble. NHibernate refused to perform an INSERT statement, but instead threw an UPDATE statement at us.

After some debugging we found out that the audit information should have been manipulated through the state and currentState arguments of the OnSave and OnFlushDirty methods respectively.

The documentation of the OnSave method clearly states:

The interceptor may modify the state, which will be used for the SQL INSERT
and propagated to the persistent object

Lesson relearned.

I'm off, reading some docs. Until next time.

Tuesday, May 13, 2008

WCF friction

Today I spent some time (thank God no more than 15 minutes) tracking down a WCF issue from hell. Every time I made a call to the service I got the following exception:

System.ServiceModel.CommunicationException : The underlying connection was closed: The connection was closed unexpectedly.

This is really helpful, isn't it? Fortunately there is some tool that helped me out a great deal: Service Trace Viewer Tool (SvcTraceViewer.exe). Turns out that I forgot to place a DataContract attribute on one of my DTO objects.

Why am I too stupid to deduce this from the exception message in the first place?

Thursday, May 01, 2008

On Persistence

Earlier this week, I managed to convince our very wise decision makers to start using NHibernate for our persistence layer. My team mate on the project describes how it went. While I was reading Jeremy's train of thoughts, the following four lines made me realize we did the right thing:

Why are teams still writing persistence code by hand?  There's a bazillion persistence tools out there that all save development costs in some way over writing data access code by hand.  With very few exceptions, I'd say that at this point that if you're writing ADO.Net code or SQL by hand, you're stealing money from your employer. 

As another co-worker and NHibernate fan thoughtfully mentioned while congratulating us:

A small step for man, but a giant leap for mankind.

Few. What a week this turns out to be.