使用MSMQ绑定在WAS中托管WCF服务时,与HttpContext相对应的替代方案

11

我正在使用MSMQ绑定激活的单向WCF服务,使用IIS 7.0中的Windows Activation Service。

我非常喜欢NInject,所以一直在使用NInject扩展来处理WCF服务。对于典型的HTTP WCF服务来说,这个扩展很好用。

然而,在WAS激活服务中没有HTTP管道,因此我无法在绑定我的类型时使用InRequestScope,因为System.Web.HttpContext.Current为空。我正在寻找在使用WAS时可以给我想要的东西的替代方案。在此模式下,AspCompatibility模式属性也不起作用。

我认为InThreadScope可能有效,但是该服务是在一个不同的线程中创建的,而不是在执行线程中。

因此,基本上我需要与WCF+WAS等效的HttpContext来对我的对象进行请求级别的范围限定。在这个世界中是否有一些静态对象可以像它一样工作,或者其他人有任何想法可以帮我解决问题吗?

2个回答

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;
  }
}

为了完整起见,以下是我如何使用上述定义的回调函数:

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

他们还没有在WAS中托管WCF服务,所以不确定是否使用上面定义的WcfWebContextWcfContext,但你可以尝试使用它们并查看结果。如果WebOperationContext可用,则一切都准备就绪。否则,我发现事情会更加复杂。请注意,上面的代码片段使用了一个附加到OperationContextNinjectInstanceContext类。这是我编写的一个类,它使用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 {
  }

我的Ninject的WCF扩展与Github上的相同。基本上发生的事情是创建了一个实例提供程序,该程序被插入到了WCF“激活”链中--我没有使用它们特定的术语,只是我理解的方式。因此,想法是您的实例提供程序应该提供请求的WCF服务类的实例。这就是我们使用Ninject生成服务实例的地方。通过这样做,我们还可以激活并注入任何依赖项。在我的实现中,实例提供程序所做的是将Ninject内核包装在NinjectInstanceContext的实例中,并将其附加到OperationContext。然后将服务的创建委托给此WCF扩展。当要求实例提供程序释放服务时,被附加到OperationContext的NinjectInstanceContext将被处理,从而通过实现INotifyWhenDisposed导致服务(以及可能的依赖项)被确定性地处理。希望这次讨论有所帮助。如果您感兴趣,我会尽力发布更多具体代码。

0

我相信OperationContext就是你要找的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接