MSMQ和Unity.Wcf - 服务永远不会消耗队列

时间:2014-03-28 09:06:33

标签: c# .net wcf unity-container msmq-wcf

有没有人设法使用Unity容器在WCF上实现MSMQ?

我的服务器启动,创建私人队列并公开mex。我的客户端可以解析服务引用,连接并成功将消息写入队列。然而,服务器从不接收任何消息,并将它们留在队列中。

为了缩小错误来源,我使用标准ServiceHostMSDN tutorial实现了MSMQ示例应用程序:

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{ 
    //... 
}

并且消息被获取并成功使用。

但是,只要UnityServiceHost使用Unity.Wcf

var container = new UnityContainer();
using (ServiceHost serviceHost = new UnityServiceHost(container, typeof(OrderProcessorService)))
{ 
    //... 
}

该服务不消耗任何消息,而这些消息又会堆积在队列中。

我浏览了官方Unity documentation(仅作为免费电子书提供),并使用Google搜索任何其他信息,但没有取得任何成功。

我只能假设UnityServiceHost无法处理MSMQ,或者我必须为UnityContainer应用特殊配置。

有没有人设法让这个工作?有任何建议或提示吗?

1 个答案:

答案 0 :(得分:0)

亲爱的,我在问题中发布了我的答案。

事实:

  1. Unity.Wcf是第三方库,由于缺少所有者而目前不受支持。
  2. Unity documentation已经显示了一种创建自己的UnityServiceHost用于DI的方法。
  3. 从前面提到的文档中做一个确切的示例,并用参考实现替换Unity.Wcf将解决问题并使服务器使用队列。
  4. 解决方案非常简单。

    为了节省您的时间,以下是Microsoft 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)
        {
        }
    }