A very common thing you want to do when creating WCF services is to hook them up to a Dependency Injection container (such as Unity, nInject, Structure Map etc). Thankfully, WCF is quite easy to extend - and this is one way of doing it:
The first thing you need is the actual InstanceProvider. This will do the buildup. I'm using the ServiceLocator library from Microsoft P&P.
public class InjectedInstanceProvider : IInstanceProvider
{
private readonly Type _serviceType;
public InjectedInstanceProvider(Type serviceType)
{
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return ServiceLocator.Current.GetInstance( _serviceType );
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
The next thing you need is a Service Behavior that makes sure that the new Instance Provider is being used.
public class InjectedBehavior : IServiceBehavior
{
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { }
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach(var cdb in serviceHostBase.ChannelDispatchers)
{
var cd = cdb as ChannelDispatcher;
if (cd == null)
continue;
foreach (var endpoint in cd.Endpoints)
{
endpoint.DispatchRuntime.InstanceProvider =
new InjectedInstanceProvider(serviceDescription.ServiceType);
}
}
}
}
You'll need a Service Host that applies the behavior:
public class InjectedServiceHost : ServiceHost
{
protected InjectedServiceHost()
{
}
public InjectedServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
}
protected override void OnOpening()
{
Description.Behaviors.Add(new InjectedBehavior());
base.OnOpening();
}
}
And a Service Host Factory that creates the new Host:
public class InjectedServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new InjectedServiceHost(serviceType, baseAddresses);
}
}
And in order to use the new Service Host Factory, your .svc file should include the Factory attribute:
<%@ ServiceHost Language="C#" Debug="true" Service="MyServiceType" Factory="MyNamespace.InjectedServiceHostFactory" %>
Finally, you'll need to wire up the Dependency Injection container to the ServiceLocator. But I'll leave that bit for a separate post.
Fork
3 Feedback
We're using a SL-framework to get a DI-framework make our framework work. :D - @abratland Sunday 11, 2010 7:54 PM
So basically the samething that the Common Service Factory does? =) http://commonservicefactory.codeplex.com/ - @TheCodeJunkie Monday 12, 2010 10:12 PMYou must log in before you can give any feedback
You must log in before you can post a comment


1.16k
0



Mark 'dependency-injection' tag as 'like'
Mark 'dependency-injection' tag as 'ignore'