For a while I’ve been wondering about the lifetime behavior of custom ServiceHostFactory classes hosted in IIS. Does IIS create an instance per request? Or a single instance to handle all requests?
I decided to find out, so I wrote a little test service. The conclusion seems to be that there is only a single instance that servers as a factory for all requests. This is very fortunate, since it gives us an excellent place to host a DI Container. The container can then manage the lifetime of all components, including Singletons that will live for the duration of the process.
If you are curious how I arrived at this conclusion, here’s the code I wrote. I started out with this custom ServiceHostFactory:
public class PocServiceHostFactory : ServiceHostFactory
{
private static int number = 1;
public PocServiceHostFactory()
Interlocked.Increment(
ref PocServiceHostFactory.number);
}
protected override ServiceHost CreateServiceHost(
Type serviceType, Uri[] baseAddresses)
return new PocServiceHost(
PocServiceHostFactory.number, serviceType,
baseAddresses);
The idea is that every time a new instance of ServiceHostFactory is created, the static number is incremented.
The PocServiceHostFactory just forwards the number to the PocServiceHost:
public class PocServiceHost : ServiceHost
public PocServiceHost(int number, Type serviceType,
Uri[] baseAddresses)
: base(serviceType, baseAddresses)
foreach (var cd in
this.ImplementedContracts.Values)
cd.Behaviors.Add(
new NumberServiceInstanceProvider(
number));
The PocServiceHost just forwards the number to the NumberServiceInstanceProvider:
public class NumberServiceInstanceProvider :
IInstanceProvider, IContractBehavior
private readonly int number;
public NumberServiceInstanceProvider(int number)
this.number = number;
#region IInstanceProvider Members
public object GetInstance(
InstanceContext instanceContext,
Message message)
return this.GetInstance(instanceContext);
InstanceContext instanceContext)
return new NumberService(this.number);
public void ReleaseInstance(
object instance)
#endregion
#region IContractBehavior Members
public void AddBindingParameters(
ContractDescription contractDescription,
ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
public void ApplyClientBehavior(
ClientRuntime clientRuntime)
public void ApplyDispatchBehavior(
DispatchRuntime dispatchRuntime)
dispatchRuntime.InstanceProvider = this;
public void Validate(
ServiceEndpoint endpoint)
The relevant part of NumberServiceInstanceProvider is the GetInstanceMethod that simply forwards the number to the NumberService:
public class NumberService : INumberService
public NumberService(int number)
#region INumberService Members
public int GetNumber()
return this.number;
As you can see, NumberService simply returns the injected number.
The experiment is now to host NumberService in IIS using PocServiceHostFactory. If there is only one ServiceHostFactory per application process, we would expect that the same number (2) is returned every time we invoke the GetNumber operation. If, on the other hand, a new instance of ServiceHostFactory is created per request, we would expect the number to increase for every request.
To test this I spun up a few instances of WcfTestClient.exe and invoked the operation. It consistently returns 2 across multiple clients and multiple requests. This supports the hypothesis that there is only one ServiceHostFactory per service process.
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Saturday, February 04, 2012 10:24:49 PM (Romance Standard Time, UTC+01:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.