2010-01-12 8 views
11

Ho un servizio WCF unidirezionale utilizzando il Binding MSMQ attivato tramite il servizio di attivazione di Windows in IIS 7.0.Alternativa a HttpContext quando si utilizza NInject con un servizio WCF ospitato in WAS utilizzando il binding MSMQ

Sono un grande fan su NInject, quindi ho utilizzato l'estensione NInject per WCF, che per un tipico servizio WCF HTTP funzionerebbe benissimo.

Tuttavia, nei servizi di attivazione WAS non è presente alcuna pipeline HTTP, quindi non è possibile utilizzare InRequestScope durante il binding dei tipi poiché System.Web.HttpContext.Current è null. Sto lottando per trovare un'alternativa quando uso WAS che mi darà quello che voglio. Anche l'attributo della modalità AspCompatibility non funziona in questa modalità.

ho pensato InThreadScope potrebbe funzionare, ma il servizio è stato creato in un thread separato di quello che viene eseguita in.

Quindi, in pratica ho bisogno l'equivalente del HttpContext per WCF + era di portata miei oggetti al livello di richiesta. C'è qualche oggetto statico in questo mondo che funzionerebbe allo stesso modo o qualcun altro ha qualche idea su qualcosa che posso hackerare insieme?

risposta

9

ho implementato le mie estensioni di WCF per Ninject 2.0 prima sapevo che c'era un this su GitHub. La mia implementazione leggermente diverso, ma mi è venuto su con una soluzione per gli oggetti di scoping:

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

Per completezza, questo è il modo che uso la richiamata sopra definito:

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

Il non hanno ospitato WCF servizi in WAS, quindi non sei sicuro di utilizzare lo WcfWebContext o WcfContext definito in precedenza, ma puoi provarli e vedere. Se WebOperationContext funziona, allora tutto è pronto. Altrimenti, ho trovato che le cose sono un po 'più complicate. Noterai che lo snippet di codice sopra utilizza una classe NinjectInstanceContext collegata allo OperationContext. Questa è una classe che ho scritto che usa il meccanismo "cache and collect" di Ninject 2.0 che consente agli oggetti di essere disposti in modo deterministico. Fondamentalmente, la classe è implementa IExtension<InstanceContext> che è un costrutto WCF per il collegamento di quasi qualsiasi cosa allo OperationContext. Questa classe implementa anche l'interfacciadi Ninject, che fornisce supporto per lo smaltimento deterministico. Ecco cosa la definizione di classe si presenta come:

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

Il resto della mia estensione WCF per Ninject è lo stesso del one su GitHub. Quello che succede di base è che viene creato un provider di istanze che è collegato alla catena di "attivazione" della WCF - non sto usando la loro terminologia specifica, solo come capisco le cose. Quindi, l'idea è che il tuo provider di istanze debba fornire istanze della classe di servizio WCF richiesta. Quindi, ecco dove usiamo Ninject per produrre l'istanza del servizio. Così facendo, possiamo anche attivare e iniettare qualsiasi dipendenza. Cosa fa il provider di istanze nella mia implementazione è racchiudere il kernel di Ninject in un'istanza se NinjectInstanceContext e collegarlo allo OperationContext. La creazione del servizio è quindi delegata a questa estensione WCF. Quando al provider di istanza viene richiesto di rilasciare un servizio, viene eliminato il numero NinjectInstanceContext allegato a OperationContext che, implementando INotifyWhenDisposed, determina lo smaltimento deterministico del servizio (e potenzialmente le sue dipendenze).

Spero che questa discussione aiuti.Vedrò se riesco a ottenere un codice più concreto pubblicato qui se sei interessato.

+1

Collegamento interrotto. È corretto? https://github.com/ninject/ninject.extensions.wcf –

+0

Hai ragione - Ho corretto il collegamento. –

0

Sono sicuro OperationContext è quello che stai cercando