2010-01-12 9 views
11

Ich habe einen einseitigen WCF-Dienst mit der MSMQ-Bindung, die mit dem Windows-Aktivierungsdienst in IIS 7.0 aktiviert wird.Alternative zu HttpContext bei Verwendung von NInject mit einem in WAS gehosteten WCF-Dienst mit MSMQ-Bindung

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 großartig funktionieren würde.

Allerdings gibt es in WAS activate services keine HTTP-Pipeline, daher kann ich InRequestScope nicht verwenden, wenn ich meine Typen binde, weil System.Web.HttpContext.Current null ist. Ich habe Probleme, eine Alternative zu finden, wenn ich WAS verwende, was mir das geben wird, was ich will. Das AspCompatibility-Modusattribut funktioniert auch in diesem Modus nicht.

Ich dachte InThreadScope funktionieren könnte, aber der Service ist in einem separaten Thread erstellt als das, was sie in ausgeführt wird.

Also im Grunde muss ich das Äquivalent der die Httpcontext für WCF + war meine Objekte Umfang an die Anfrageebene Gibt es in dieser Welt ein statisches Objekt, das genauso funktioniert oder hat jemand anderes Ideen für etwas, das ich zusammenhacken kann?

Antwort

9

ich meine eigene WCF-Erweiterungen für Ninject 2.0 implementiert, bevor ich dort ein this bis auf Github kannte. Meine Implementierung unterscheidet sich leicht, aber ich habe mit einer Lösung zu 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; 
    } 
} 

Für Vollständigkeit, das ist, wie ich den Rückruf verwenden oben definiert:

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

Die haben WCF nicht gehostet Dienste in WAS, also nicht sicher, ob Sie die oben definierten WcfWebContext oder WcfContext verwenden würden, aber Sie können es ausprobieren und sehen. Wenn WebOperationContext funktioniert, dann sind Sie fertig. Ansonsten finde ich die Dinge etwas komplizierter. Sie werden feststellen, dass das obige Code-Snippet eine Klasse NinjectInstanceContext verwendet, die an die OperationContext angehängt ist. Dies ist eine Klasse, die ich geschrieben habe und die Ninject 2.0s "Cache and Collect" -Mechanismus verwendet, der Objekte deterministisch entsorgt. Grundsätzlich ist die Klasse implementiert IExtension<InstanceContext>, die ein WCF-Konstrukt für die Befestigung fast alles an die OperationContext ist. Diese Klasse implementiert auch die INotifyWhenDisposed Schnittstelle von Ninject, die Unterstützung für deterministische Entsorgung bietet. Hier ist, was die Klassendefinition wie folgt aussieht:

/// <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 die gleiche wie die one auf Github ist. Was grundsätzlich passiert, ist, dass ein Instanz-Provider erstellt wird, der an die "Aktivierungs" -Kette der WCF angeschlossen ist - ich verwende nicht ihre spezifische Terminologie, nur wie ich Dinge verstehe. Die Idee ist also, dass Ihr Instanz-Provider Instanzen der angeforderten WCF-Serviceklasse bereitstellen soll. Also, hier verwenden wir Ninject, um die Dienstinstanz zu erzeugen. Auf diese Weise können wir auch Abhängigkeiten aktivieren und injizieren. Was der Instanzprovider in meiner Implementierung tut, ist den Ninject-Kernel in einer Instanz einzubinden, wenn NinjectInstanceContext und an die OperationContext angehängt wird. Die Erstellung des Dienstes wird dann an diese WCF-Erweiterung delegiert. Wenn der Instanzprovider aufgefordert wird, einen Dienst freizugeben, wird die NinjectInstanceContext, die dem OperationContext beigefügt wurde, entsorgt, was durch Implementierung von INotifyWhenDisposed eine deterministische Entsorgung des Dienstes (und möglicherweise seiner Abhängigkeiten) verursacht.

Hoffe, diese Diskussion hilft.Ich werde sehen, ob ich hier etwas konkreteren Code bekommen kann, wenn Sie interessiert sind.

+1

Unterbrochene Verbindung. Ist das richtig? https://github.com/ninject/ninject.extensions.wcf –

+0

Sie haben Recht - ich habe den Link korrigiert. –

0

ich bin sicher, OperationContext ist das, was Sie suchen