I stumbled upon an interesting problem this morning where Castle ActiveRecord was being initialised correctly in the development environment, but as soon as everything was rolled out to the lab environment, the application would throw errors about AR not being initialised. The error message was along the lines of:
An ActiveRecord class (Darkside.Domain.Person) was used but the framework seems not properly initialized. Did you forget about ActiveRecordStarter.Initialize() ?
A bit of background info: As is custom in our web projects, we use an HttpModule to do the AR initialisation. In this case, the web project is actually a WAS host for our WCF services. After doing a bit of research, I found out that HttpModules are not executed when running WCF services. The reason we had the illusion it was working in dev is because of a default page that was started when the project was run. This caused the HttpModule to run, which in turn initialised AR for that session.
Our solution to this problem was to make use of a custom service host factory. I’ve touched on the custom service host factory subject here before, and this solution is just another use of it.
public class CustomServiceHostFactory : ServiceHostFactory
{
private static readonly object m_InitActiveRecordLock = new object();
public override System.ServiceModel.ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
//Initialise ActiveRecord...
if (!ActiveRecordStarter.IsInitialized)
{
lock (m_InitActiveRecordLock)
{
if (!ActiveRecordStarter.IsInitialized)
{
ActiveRecordStarter.Initialize(Assembly.Load("Darkside.Domain"), ActiveRecordSectionHandler.Instance);
}
}
}
//Hand off the real host creation to the base class..
return (base.CreateServiceHost(constructorString, baseAddresses));
}
}
You then need to add the Factory attribute into your .SVC file
<%@ ServiceHost Language="C#" Debug="false" Service="Darkside.Services.CRUDService, Darkside.Services" Factory="Darkside.WAS.CustomServiceHostFactory" %>
Now, if a new service host is created in your app, AR will be initialised first, if needed.