MSMQ и Unity.Wcf — служба никогда не использует очередь

Кому-нибудь когда-нибудь удавалось реализовать MSMQ поверх WCF с использованием контейнера Unity?

Мой сервер запускается, создает частную очередь и выставляет файл mex. Мой клиент может разрешить ссылку на службу, подключиться и успешно записать сообщения в очередь. Однако сервер никогда не принимает сообщения и оставляет их неиспользованными в очереди.

Чтобы сузить источники ошибок, я реализовал пример приложения MSMQ из MSDN tutorial с использованием стандартного ServiceHost:

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

и сообщения принимаются и успешно потребляются.

Но как только я использую UnityServiceHost от Unity.Wcf:

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

служба не потребляет никаких сообщений, которые, в свою очередь, накапливаются в очереди.

Я просмотрел официальную документацию Unity (которая доступна только в виде бесплатной электронной версии). book) и безуспешно гуглил любую дополнительную информацию.

Я могу только предположить, что либо UnityServiceHost не может обрабатывать MSMQ, либо мне нужно применить специальную конфигурацию для моего UnityContainer.

Кому-нибудь удалось заставить это работать? Любые предложения или подсказки?


person Jan    schedule 28.03.2014    source источник


Ответы (1)


О боже, я разместил свой ответ прямо в вопросе.

Факты:

  1. Unity.Wcf — это сторонняя библиотека, которая в настоящее время не поддерживается из-за отсутствия владельца.
  2. В документации Unity уже показан способ создания собственного UnityServiceHost для использования с DI.
  3. Выполнение точного примера из ранее упомянутой документации и замена Unity.Wcf эталонной реализацией решит проблему и заставит сервер потреблять очередь.

Решение довольно простое.

Чтобы сэкономить ваше время, вот пример кода из документации Unity от Microsoft:

Хост UnityService:

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)
    {
    }
}
person Jan    schedule 28.03.2014