Has anyone ever managed to implement MSMQ over WCF using a Unity container?
My server starts up, creates the private queue and exposes the mex. My client can resolve the service reference, connect, and successfully write messages to the queue. The server however never picks up any of the messages and leaves them unconsumed in the queue.
To narrow down the error sources, I implemented the MSMQ example application from the MSDN tutorial using the standard ServiceHost
:
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
//...
}
and messages get picked up and consumed successfully.
But as soon as I use the UnityServiceHost
by Unity.Wcf
:
var container = new UnityContainer();
using (ServiceHost serviceHost = new UnityServiceHost(container, typeof(OrderProcessorService)))
{
//...
}
the service is not consuming any messages, which in turn pile up in the queue.
I went through the official Unity documentation (which is only available as a free e-book) and googled for any additional information without any success.
I can only presume that either UnityServiceHost
cannot handle MSMQ, or I have to apply a special configuration for my UnityContainer
.
Has anyone managed to get this to work? Any suggestions or hints?
Oh dear, I posted my answer right within the question.
Facts:
UnityServiceHost
for use with DI.Unity.Wcf
by the reference implementation will solve the issue and make the server consume the queue.The solution is fairly simple.
To save you some time, here is the example code from Microsoft's Unity documentation:
UnityServiceHost:
public class UnityServiceHost : ServiceHost
{
public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
foreach (var contractDescription in ImplementedContracts.Values)
{
contractDescription.Behaviors.Add(new UnityInstanceProvider(container));
}
}
}
UnityInstanceProvider
public class UnityInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IUnityContainer container;
public UnityInstanceProvider(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
return container.Resolve(instanceContext.Host.Description.ServiceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
}