11 Stimmen

Alternative zu HttpContext bei Verwendung von NInject mit einem in WAS gehosteten WCF-Dienst mit MSMQ-Bindung

Ich habe einen Einweg-WCF-Dienst, der die MSMQ-Bindung verwendet, die mit Windows-Aktivierungsdienst in IIS 7.0 aktiviert ist.

Ich bin ein großer Fan von NInject, also habe ich die NInject-Erweiterung für WCF verwendet, die für einen typischen HTTP-WCF-Dienst hervorragend funktionieren würde.

In WAS activate services gibt es jedoch keine HTTP-Pipeline, so dass ich InRequestScope beim Binden meiner Typen nicht verwenden kann, weil System.Web.HttpContext.Current null ist. Ich kämpfe, um eine Alternative zu finden, wenn Sie WAS verwenden, die mir geben wird, was ich will. AspCompatibility-Modus-Attribut funktioniert nicht in diesem Modus entweder.

Ich dachte, dass InThreadScope funktionieren könnte, aber der Dienst wird in einem anderen Thread als dem, in dem er ausgeführt wird, erstellt.

Also im Grunde brauche ich das Äquivalent der HttpContext für WCF + WAS, um meine Objekte auf der Anforderungsebene Umfang. Gibt es einige statische Objekt in dieser Welt, die die gleiche Weise funktionieren würde, oder hat jemand sonst irgendwelche Ideen auf etwas, das ich zusammen hacken kann?

9voto

Peter Meyer Punkte 25181

Ich habe meine eigenen WCF-Erweiterungen für Ninject 2.0 implementiert, bevor ich wusste, dass es eine ce auf Github. Meine Implementierung unterscheidet sich geringfügig, aber ich habe mit einer Lösung für Scoping-Objekte kommen:

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

Der Vollständigkeit halber: So verwende ich den oben definierten Callback:

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

Sie haben keine WCF-Dienste in WAS gehostet, daher bin ich nicht sicher, ob Sie die WcfWebContext o WcfContext oben definiert, aber Sie können sie ausprobieren und sehen. Wenn WebOperationContext funktioniert, dann sind Sie bereit. Andernfalls sind die Dinge ein bisschen komplizierter. Sie werden feststellen, dass der obige Codeschnipsel eine NinjectInstanceContext Klasse, die mit der OperationContext . Dies ist eine Klasse, die ich geschrieben habe und die den "cache and collect"-Mechanismus von Ninject 2.0 nutzt, der es ermöglicht, Objekte deterministisch zu entsorgen. Im Grunde implementiert die Klasse IExtension<InstanceContext> ist ein WCF-Konstrukt, mit dem sich fast alles an die OperationContext . Diese Klasse implementiert auch Ninjects INotifyWhenDisposed Schnittstelle, die die deterministische Entsorgung unterstützt. So sieht die Klassendefinition aus:

  /// <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 {
  }

Der Rest meiner WCF-Erweiterung für Ninject ist der gleiche wie der eine auf github. Was im Grunde passiert ist, dass eine Instanz Anbieter erstellt wird, die in die WCF "Aktivierung" Kette eingesteckt wird - ich bin nicht mit ihren spezifischen Terminologie, nur wie ich die Dinge verstehen. Die Idee ist also, dass Ihr Instanzanbieter Instanzen der angeforderten WCF-Serviceklasse bereitstellen soll. Hier verwenden wir also Ninject, um die Dienstinstanz zu erzeugen. Auf diese Weise können wir auch alle Abhängigkeiten aktivieren und injizieren. Was der Instanzanbieter in meiner Implementierung tut, ist den Ninject-Kernel in eine Instanz zu verpacken, wenn NinjectInstanceContext und befestigen Sie es an der OperationContext . Die Erstellung des Dienstes wird dann an diese WCF-Erweiterung delegiert. Wenn der Instanzanbieter angewiesen wird, einen Dienst freizugeben, wird die NinjectInstanceContext die an den OperationContext angehängt wurde, wird entsorgt, was durch die Implementierung von INotifyWhenDisposed bewirkt eine deterministische Beseitigung des Dienstes (und möglicherweise seiner Abhängigkeiten).

Ich hoffe, diese Diskussion ist hilfreich. Ich werde sehen, wenn ich einige konkretere Code hier gepostet bekommen können, wenn Sie interessiert sind.

0voto

Neil Punkte 1902

Ich bin sicher OperationContext ist das, wonach Sie suchen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X