11

IIS 7.0 の Windows Activation Service を使用してアクティブ化される MSMQ Binding を使用する一方向の WCF サービスがあります。

私は NInject の大ファンなので、WCF 用の NInject 拡張機能を使用してきました。これは、典型的な HTTP WCF サービスではうまく機能します。

ただし、WAS アクティブ化サービスには HTTP パイプラインがないため、System.Web.HttpContext.Current が null であるため、型をバインドするときに InRequestScope を使用できません。WAS を使用するときに、必要なものを提供してくれる代替手段を見つけるのに苦労しています。AspCompatibility モード属性もこのモードでは機能しません。

InThreadScope が機能する可能性があると思いましたが、サービスは実行されるスレッドとは別のスレッドで作成されます。

したがって、基本的には、WCF+WAS の HttpContext に相当するオブジェクトを要求レベルでスコープする必要があります。この世界に同じように機能する静的なオブジェクトはありますか、それとも私が一緒にハッキングできる何かについて何かアイデアを持っている人はいますか?

4

2 に答える 2

9

github にこれがあることを知る前に、Ni​​nject 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は、準備完了です。そうでなければ、物事はもう少し複雑であることがわかりました。上記のコード スニペットはNinjectInstanceContextOperationContext. これは私が書いたクラスで、Ninject 2.0 の「キャッシュと収集」メカニズムを使用して、オブジェクトを決定論的に破棄できるようにします。基本的に、クラスは実装されますIExtension<InstanceContext>。これは、ほとんどすべてのものを にアタッチするための WCF コンストラクトですOperationContextINotifyWhenDisposedこのクラスは、決定論的破棄のサポートを提供するNinject のインターフェースも実装します。クラス定義は次のようになります。

  /// <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 カーネルをインスタンス if にラップしNinjectInstanceContextOperationContext. サービスの作成は、この WCF 拡張機能に委任されます。インスタンス プロバイダーがサービスをリリースするように指示されると、NinjectInstanceContextOperationContext にアタッチされたものは破棄されます。これは、実装INotifyWhenDisposedによって、サービス (および潜在的にその依存関係) の決定論的な破棄を引き起こします。

この議論が役立つことを願っています。興味があれば、ここに投稿された具体的なコードを取得できるかどうかを確認します。

于 2010-01-12T15:18:21.127 に答える
0

私はOperationContextあなたが探しているものだと確信しています

于 2010-01-12T06:03:06.690 に答える