0

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

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

为了缩小错误来源,我使用标准实现了MSDN 教程ServiceHost中的 MSMQ 示例应用程序:

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

并且消息被成功拾取和消费。

但是一旦我使用UnityServiceHostby Unity.Wcf

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

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

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

我只能假设要么UnityServiceHost无法处理 MSMQ,要么我必须为我的UnityContainer.

有没有人设法让它工作?有什么建议或提示吗?

4

1 回答 1

0

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

事实:

  1. Unity.Wcf是第三方库,由于缺少所有者,目前不支持。
  2. Unity 文档已经展示了一种创建自己的UnityServiceHost用于 DI的方法。
  3. 执行前面提到的文档中的确切示例并替换Unity.Wcf为参考实现将解决问题并使服务器消耗队列。

解决方案相当简单。

为了节省您一些时间,这里是来自 Microsoft 的Unity 文档的示例代码:

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)
    {
    }
}
于 2014-03-28T10:46:51.117 回答