There are numerous blog posts available that explain how to hook up Unity with WCF. Unfortunately, many of these are incomplete, too basic or just plain wrong. Additionally, as far as I can tell, nobody has created a NuGet package to get you up and running as quickly as possible. This post introduces Unity.WCF, an open source NuGet package that (hopefully) just works in most situations, deals with cleaning up IDisposable instances and also provides a nice mechanism for automatically adding WCF behaviors to your services.
Instantiating a service contract without a parameterless constructorOut of the box, all service contracts require a default constructor which is obviously somewhat troublesome if you want to inject your dependencies. Making WCF work with IoC is not difficult but it does involve the creation of a few classes in order to hook into the WCF pipeline at the appropriate point. WCF is full of extensibility points and when it comes to service instantiation, the IInstanceProvider interface is what you need.
public interface IInstanceProvider
{
object GetInstance(InstanceContext instanceContext);
object GetInstance(InstanceContext instanceContext, Message message);
void ReleaseInstance(InstanceContext instanceContext, object instance);
}So, GetInstance needs to create the service instance and ReleaseInstance needs to tidy up afterwards. Virtually all implementations available on the web completely ignore the ReleaseInstance method or just call the TearDown method on the Unity container which looks as though it might do something useful, but in fact does absolutely nothing. The easiest way to dispose of items in Unity on a per client basis is to use child containers. This is exactly how our Unity.Mvc3 library works. Unity.WCF takes a similar approach. The complete UnityInstanceProvider is displayed below:
public class UnityInstanceProvider : IInstanceProvider
{
private readonly IUnityContainer _container;
private readonly Type _contractType;
public UnityInstanceProvider(IUnityContainer container, Type contractType)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
if (contractType == null)
{
throw new ArgumentNullException("contractType");
}
_container = container;
_contractType = contractType;
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
var childContainer =
instanceContext.Extensions.Find<UnityInstanceContextExtension>().GetChildContainer(_container);
return childContainer.Resolve(_contractType);
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
instanceContext.Extensions.Find<UnityInstanceContextExtension>().DisposeOfChildContainer();
}
}The code is quite self explanatory. We create a new child container whenever a new connection is made and then use the child container to resolve the service implementation. When the connection is terminated, we dispose of the child container, forcing all IDisposable dependencies to also be disposed (or to be more accurate, all dependencies registered with a HierarchicalLifetimeManager are disposed). Read more: DevTrends
QR:
Instantiating a service contract without a parameterless constructorOut of the box, all service contracts require a default constructor which is obviously somewhat troublesome if you want to inject your dependencies. Making WCF work with IoC is not difficult but it does involve the creation of a few classes in order to hook into the WCF pipeline at the appropriate point. WCF is full of extensibility points and when it comes to service instantiation, the IInstanceProvider interface is what you need.
public interface IInstanceProvider
{
object GetInstance(InstanceContext instanceContext);
object GetInstance(InstanceContext instanceContext, Message message);
void ReleaseInstance(InstanceContext instanceContext, object instance);
}So, GetInstance needs to create the service instance and ReleaseInstance needs to tidy up afterwards. Virtually all implementations available on the web completely ignore the ReleaseInstance method or just call the TearDown method on the Unity container which looks as though it might do something useful, but in fact does absolutely nothing. The easiest way to dispose of items in Unity on a per client basis is to use child containers. This is exactly how our Unity.Mvc3 library works. Unity.WCF takes a similar approach. The complete UnityInstanceProvider is displayed below:
public class UnityInstanceProvider : IInstanceProvider
{
private readonly IUnityContainer _container;
private readonly Type _contractType;
public UnityInstanceProvider(IUnityContainer container, Type contractType)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
if (contractType == null)
{
throw new ArgumentNullException("contractType");
}
_container = container;
_contractType = contractType;
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
var childContainer =
instanceContext.Extensions.Find<UnityInstanceContextExtension>().GetChildContainer(_container);
return childContainer.Resolve(_contractType);
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
instanceContext.Extensions.Find<UnityInstanceContextExtension>().DisposeOfChildContainer();
}
}The code is quite self explanatory. We create a new child container whenever a new connection is made and then use the child container to resolve the service implementation. When the connection is terminated, we dispose of the child container, forcing all IDisposable dependencies to also be disposed (or to be more accurate, all dependencies registered with a HierarchicalLifetimeManager are disposed). Read more: DevTrends
QR:
0 comments:
Post a Comment