在我知道有这个的github库之前,我已经为Ninject 2.0实现了自己的WCF扩展。尽管我的实现略有不同,但我确实想出了一种对象作用域的解决方案:
using System;
using Ninject.Activation;
namespace Ninject.Contrib.Wcf {
public class NinjectWcfScopeCallbacks {
public static readonly Func<IContext, object> WcfContext =
ctx => (System.ServiceModel.OperationContext.Current != null
? System.ServiceModel.OperationContext.Current.
InstanceContext.
Extensions.Find<NinjectInstanceContext>()
: null);
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
可用,则一切都准备就绪。否则,我发现事情会更加复杂。请注意,上面的代码片段使用了一个附加到
OperationContext
的
NinjectInstanceContext
类。这是我编写的一个类,它使用Ninject 2.0的“缓存和收集”机制,允许对象被确定性地处理。基本上,该类实现了
IExtension<InstanceContext>
,这是一个WCF构造,用于将几乎任何内容附加到
OperationContext
。该类还实现了Ninject的
INotifyWhenDisposed
接口,这是提供确定性处理支持的原因。该类定义如下:
public class NinjectInstanceContext :
IExtension<InstanceContext>, INotifyWhenDisposed {
}
我的Ninject的WCF扩展与
Github上的相同。基本上发生的事情是创建了一个实例提供程序,该程序被插入到了WCF“激活”链中--我没有使用它们特定的术语,只是我理解的方式。因此,想法是您的实例提供程序应该提供请求的WCF服务类的实例。这就是我们使用Ninject生成服务实例的地方。通过这样做,我们还可以激活并注入任何依赖项。在我的实现中,实例提供程序所做的是将Ninject内核包装在
NinjectInstanceContext
的实例中,并将其附加到
OperationContext
。然后将服务的创建委托给此WCF扩展。当要求实例提供程序释放服务时,被附加到OperationContext的
NinjectInstanceContext
将被处理,从而通过实现
INotifyWhenDisposed
导致服务(以及可能的依赖项)被确定性地处理。希望这次讨论有所帮助。如果您感兴趣,我会尽力发布更多具体代码。