当使用NInject与使用MSMQ绑定在WAS中托管的WCF服务时,替代HttpContext

Ray*_*its 11 wcf ninject was msmqbinding

我有一个使用MSMQ绑定的单向WCF服务,它使用IIS 7.0中的Windows激活服务激活.

我是NInject的忠实粉丝,所以我一直在使用NCF的NInject扩展,这对于典型的HTTP WCF服务来说效果会很好.

但是,在WAS激活服务中没有HTTP管道,因此在绑定我的类型时我不能使用InRequestScope,因为System.Web.HttpContext.Current为null.我在努力寻找替代方案时使用WAS会给我我想要的东西.AspCompatibility模式属性也不适用于此模式.

我认为InThreadScope可能会工作,但服务是在一个单独的线程中创建的,而不是它执行的.

所以基本上我需要相当于WCF + WAS的HttpContext来在请求级别范围我的对象.在这个世界上是否存在一些静态对象可以以相同的方式工作,或者其他任何人对我可以破解的东西有任何想法?

Pet*_*yer 9

在我知道github上有这个之前,我为Ninject 2.0实现了自己的WCF扩展.我的实现稍有不同,但我确实提出了一个范围对象的解决方案:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这是我使用上面定义的回调的方式:

Bind<IHelloWorldService>()
        .To<HelloWorldService>()
        .InScope(NinjectWcfScopeCallbacks.WcfWebContext);
Run Code Online (Sandbox Code Playgroud)

在没有托管WCF服务在WAS,所以不知道你是否愿意使用WcfWebContextWcfContext以上定义,但你可以尝试"时间出去看看.如果WebOperationContext有效,那么你就完成了.否则,我发现事情有点复杂.你会注意到上面的代码片段使用了一个NinjectInstanceContext附加到的代码OperationContext.这是我写的一个类,它使用Ninject 2.0的"缓存和收集"机制,允许对象被确定性地处理.基本上,类是implements 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 {
  }
Run Code Online (Sandbox Code Playgroud)

我的WCF扩展Ninject的其余部分是一样的一个在github上.基本上发生的是创建了一个插入WCF"激活"链的实例提供程序 - 我没有使用他们的特定术语,只是我如何理解事物.因此,我们的想法是您的实例提供程序应该提供所请求的WCF服务类的实例.所以,这是我们使用Ninject生成服务实例的地方.通过这样做,我们还可以激活和注入任何依赖项.实例提供程序在我的实现中所做的是将Ninject内核包装在一个实例中NinjectInstanceContext,并将其附加到OperationContext.然后,将服务的创建委托给此WCF扩展.当实例提供者被告知要发布服务时,NinjectInstanceContext附加到OperationContext的是通过实现的方式INotifyWhenDisposed导致服务的确定性处理(以及可能的依赖性).

希望这个讨论有所帮助 如果你有兴趣的话,我会看看我是否可以在这里找到更具体的代码.