質問

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:

  1. Unity.Wcf is a third-party library, which is currently unsupported due to a missing owner.
  2. The Unity documentation already shows a way to create your own UnityServiceHost for use with DI.
  3. Doing the exact example from the before-mentioned documentation and replacing 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)
    {
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top