Initialization and disposing of services in a WCF application is a bit of a hassle to control when running on an IIS instance, since the application starts and stops every now and then based on server requests. It doesnt make it easier when using an IOC, as in our case MEF.
To have total control of the startup and shutdown events we began with adding a service factory to all our WCF services.
When ever the application gets woke up by a request to any of the services, the service factory will be used to instantiate the service. This means we can add any logic to these methods to have full control of the WCF application initialization. Here is what a service factory class could look like. (Composition is a static class containing a reference to the MEF container)
Since there are more than one service running we have to make sure the factory is thread safe and only does the initialization and disposing once. You should also note the order in which the methods are executed. The initialization are done in the constructor, but if you want something done when initialization is completed you should use the ServiceHost.Opened event, which is accessible by overriding the CreateServiceHost method.
To have total control of the startup and shutdown events we began with adding a service factory to all our WCF services.
<%@ ServiceHost Language="C#" Debug="true" Service="WcfService" Factory="CustomServiceHostFactory" %>
When ever the application gets woke up by a request to any of the services, the service factory will be used to instantiate the service. This means we can add any logic to these methods to have full control of the WCF application initialization. Here is what a service factory class could look like. (Composition is a static class containing a reference to the MEF container)
public class CustomServiceHostFactory : ServiceHostFactory { private static readonly object SynchronizationContext = new object(); public CustomServiceHostFactory () { ApplicationInitialize(); } protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { var serviceHost = base.CreateServiceHost(serviceType, baseAddresses); serviceHost.Opened += (s, a) => ApplicationStarted(); serviceHost.Closed += (s, a) => ApplicationDispose(); return serviceHost; } private void ApplicationInitialize() { if (Composition.Container != null) return; lock (SynchronizationContext) { if (Composition.Container == null) { // Initialize container Composition.Initialize(); } } } private void ApplicationStarted() { // Do anything after application has been started } private void ApplicationDispose() { lock (SynchronizationContext) { if (Composition.Container != null) Composition.Dispose(); } } }
Since there are more than one service running we have to make sure the factory is thread safe and only does the initialization and disposing once. You should also note the order in which the methods are executed. The initialization are done in the constructor, but if you want something done when initialization is completed you should use the ServiceHost.Opened event, which is accessible by overriding the CreateServiceHost method.
Comments
Post a Comment