Альтернатива HttpContext при использовании NInject со службой WCF, размещенной в WAS с использованием привязки MSMQ - PullRequest
11 голосов
/ 12 января 2010

У меня есть односторонняя служба WCF, использующая привязку MSMQ, которая активируется с помощью службы активации Windows в IIS 7.0.

Я большой поклонник NInject, поэтому я использую расширение NInject для WCF, которое для типичной службы HTTP WCF будет работать отлично.

Однако в сервисах активации WAS нет конвейера HTTP, поэтому я не могу использовать InRequestScope при связывании моих типов, поскольку System.Web.HttpContext.Current равен нулю. Я изо всех сил пытаюсь найти альтернативу при использовании WAS, которая даст мне то, что я хочу. Атрибут режима AspCompatibility также не работает в этом режиме.

Я думал, что InThreadScope может работать, но служба создается в отдельном потоке, а не в том, в котором она выполняется.

Так что в основном мне нужен эквивалент HttpContext для WCF + WAS, чтобы охватить мои объекты на уровне запроса. Есть ли в этом мире какой-то статический объект, который работал бы так же, или у кого-то есть идеи о том, что я могу взломать вместе?

Ответы [ 2 ]

9 голосов
/ 12 января 2010

Я реализовал свои собственные расширения WCF для Ninject 2.0 до того, как узнал, что на github this . Моя реализация немного отличается, но я нашел решение для определения объема объектов:

using System;
using Ninject.Activation;

namespace Ninject.Contrib.Wcf {
  /// <summary>
  /// Defines Scope Callbacks for WCF Context.
  /// </summary>
  public class NinjectWcfScopeCallbacks {
    /// <summary>
    /// Defines WCF Context scope.
    /// </summary>
    public static readonly Func<IContext, object> WcfContext =
      ctx => (System.ServiceModel.OperationContext.Current != null
                ? System.ServiceModel.OperationContext.Current.
                    InstanceContext.
                    Extensions.Find<NinjectInstanceContext>()
                : null);

    /// <summary>
    /// Defines WCF Web Context scope.
    /// </summary>
    public static readonly Func<IContext, object> WcfWebContext = 
               ctx => System.ServiceModel.Web.WebOperationContext.Current;
  }
}

Для полноты, вот как я использую обратный вызов, определенный выше:

Bind<IHelloWorldService>()
        .To<HelloWorldService>()
        .InScope(NinjectWcfScopeCallbacks.WcfWebContext);

Они не размещали службы WCF в WAS, поэтому не уверены, будете ли вы использовать WcfWebContext или WcfContext, определенные выше, но вы можете попробовать их и посмотреть. Если WebOperationContext работает, то все готово. В противном случае я обнаружил, что все немного сложнее. Вы заметите, что фрагмент кода выше использует класс NinjectInstanceContext, который присоединен к OperationContext. Это класс, который я написал, который использует механизм «кэширования и сбора» в Ninject 2.0, который позволяет детерминистически удалять объекты. По сути, класс реализует IExtension<InstanceContext>, который является конструкцией WCF для присоединения почти всего к OperationContext. Этот класс также реализует интерфейс Ninject INotifyWhenDisposed, который обеспечивает поддержку детерминированного удаления. Вот как выглядит определение класса:

  /// <summary>
  /// Defines a custom WCF InstanceContext extension that resolves service instances
  /// using Ninject.  
  /// <remarks>
  /// The custom InstanceContext extension provides support for deterministic disposal
  /// of injected dependencies and service instances themselves by being hook into 
  /// Ninject's "cache and collect" mechanism (new in Ninject 2.0) for object life cycle 
  /// management.  This allows binding object instances to the lifetime of a WCF context
  /// and having them deterministically deactivated and disposed.
  /// </remarks>
  /// </summary>
  public class NinjectInstanceContext : 
                IExtension<InstanceContext>, INotifyWhenDisposed {
  }

Остальная часть моего расширения WCF для Ninject такая же, как one на github. Что в основном происходит, так это то, что создается поставщик экземпляров, который подключен к цепочке «активации» WCF - я не использую их конкретную терминологию, просто как я понимаю вещи. Итак, идея заключается в том, что ваш поставщик экземпляров должен предоставлять экземпляры запрашиваемого класса обслуживания WCF. Итак, вот где мы используем Ninject для создания экземпляра сервиса. Таким образом, мы также можем активировать и вводить любые зависимости. В моей реализации провайдер экземпляров заключает в себе ядро ​​Ninject, если оно NinjectInstanceContext, и присоединяет его к OperationContext. Создание службы затем делегируется этому расширению WCF. Когда провайдеру экземпляра предписывается освободить службу, NinjectInstanceContext, который был присоединен к OperationContext, удаляется, что в результате реализации INotifyWhenDisposed вызывает детерминированное удаление службы (и, возможно, ее зависимости).

Надеюсь, это обсуждение поможет. Я посмотрю, смогу ли я разместить здесь более конкретный код, если вам интересно.

0 голосов
/ 12 января 2010

Я уверен, OperationContext это то, что вы ищете

...