11

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

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

但是,在 WAS 激活服务中没有 HTTP 管道,因此在绑定我的类型时我不能使用 InRequestScope,因为 System.Web.HttpContext.Current 为空。在使用 WAS 时,我正在努力寻找能够满足我想要的替代方案。AspCompatibility 模式属性在此模式下也不起作用。

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

所以基本上我需要 WCF+WAS 的 HttpContext 等价物来在请求级别限定我的对象。这个世界上是否有一些静态对象可以以相同的方式工作,或者其他人对我可以一起破解的东西有任何想法吗?

4

2 回答 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有效,那么你就准备好了。否则,我发现事情有点复杂。您会注意到上面的代码片段使用了一个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 {
  }

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

希望本次讨论有所帮助。如果您有兴趣,我会看看是否可以在此处发布一些更具体的代码。

于 2010-01-12T15:18:21.127 回答
0

我确定OperationContext是你要找的

于 2010-01-12T06:03:06.690 回答