在我知道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 服务,因此不确定您是否会使用上面定义的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 {
}
我的 Ninject 的 WCF 扩展的其余部分与github 上的相同。基本上发生的是创建了一个实例提供程序,该提供程序插入到 WCF“激活”链中——我没有使用他们的特定术语,只是我理解事物的方式。因此,想法是您的实例提供程序应该提供所请求的 WCF 服务类的实例。所以,这里是我们使用 Ninject 来生成服务实例的地方。通过这样做,我们还可以激活和注入任何依赖项。实例提供程序在我的实现中所做的是将 Ninject 内核包装在一个实例中 ifNinjectInstanceContext
并将其附加到OperationContext
. 然后将服务的创建委托给此 WCF 扩展。当实例提供者被告知发布服务时,NinjectInstanceContext
附加到 OperationContext 的被释放,通过实现INotifyWhenDisposed
导致服务的确定性释放(以及潜在的依赖关系)。
希望本次讨论有所帮助。如果您有兴趣,我会看看是否可以在此处发布一些更具体的代码。