2010-01-12 19 views
11

J'ai un service WCF unidirectionnel utilisant la liaison MSMQ qui est activée à l'aide du service d'activation Windows dans IIS 7.0. Je suis un grand fan sur NInject donc j'utilise l'extension NInject pour WCF, qui pour un service HTTP WCF typique fonctionnerait très bien.Alternative à HttpContext lors de l'utilisation de NInject avec un service WCF hébergé dans WAS utilisant la liaison MSMQ

Cependant, dans les services d'activation WAS, il n'y a pas de pipeline HTTP, donc je ne peux pas utiliser InRequestScope lorsque je lie mes types car System.Web.HttpContext.Current est null. J'ai du mal à trouver une alternative en utilisant WAS qui me donnera ce que je veux. L'attribut AspCompatibility mode ne fonctionne pas non plus dans ce mode.

Je pensais que InThreadScope pourrait fonctionner, mais le service est créé dans un thread séparé de ce qu'il est exécuté.

Donc, fondamentalement, j'ai besoin l'équivalent du HttpContext pour WCF + WAS à portée mes objets au niveau de demande. Y a-t-il un objet statique dans ce monde qui fonctionnerait de la même manière ou est-ce que quelqu'un d'autre a des idées sur quelque chose que je peux pirater ensemble?

Répondre

9

j'ai mis mes propres extensions WCF pour Ninject 2.0 avant que je savais qu'il y avait un this sur GitHub. Ma mise en œuvre diffère légèrement, mais je ne viens avec une solution à des objets: détermination de la portée

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

Pour être complet, voici comment j'utiliser la fonction de rappel défini ci-dessus:

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

L'ont pas accueilli WCF services dans WAS, donc pas sûr de vouloir utiliser le WcfWebContext ou WcfContext défini ci-dessus, mais vous pouvez essayer de les voir. Si WebOperationContext fonctionne, alors vous êtes tous ensemble. Sinon, j'ai trouvé que les choses étaient un peu plus compliquées. Vous remarquerez que l'extrait de code ci-dessus utilise une classe NinjectInstanceContext attachée au OperationContext. C'est une classe que j'ai écrite qui utilise le mécanisme "cache and collect" de Ninject 2.0 qui permet de disposer les objets de façon déterministe. Fondamentalement, la classe implémente IExtension<InstanceContext> qui est une construction WCF pour attacher presque n'importe quoi au OperationContext. Cette classe met également en œuvre l'interface INotifyWhenDisposed de Ninject qui fournit un support pour la mise au rebut déterministe. Voici ce que la définition de classe ressemble à:

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

Le reste de mon extension WCF pour Ninject est le même que le one sur GitHub. Ce qui se passe fondamentalement, c'est qu'un fournisseur d'instance est créé, qui est branché sur la chaîne d'activation de la WCF - je n'utilise pas leur terminologie spécifique, juste comment je comprends les choses. Ainsi, l'idée est que votre fournisseur d'instance est supposé fournir des instances de la classe de service WCF demandée. Donc, voici où nous utilisons Ninject pour produire l'instance de service. Ce faisant, nous pouvons également activer et injecter des dépendances. Ce que le fournisseur d'instance fait dans mon implémentation est de terminer le noyau Ninject dans une instance si NinjectInstanceContext et de l'attacher au OperationContext. La création du service est ensuite déléguée à cette extension WCF. Lorsque le fournisseur d'instance est invité à libérer un service, le NinjectInstanceContext qui était attaché à OperationContext est éliminé, ce qui, en implémentant INotifyWhenDisposed, entraîne une élimination déterministe du service (et potentiellement de ses dépendances).

Espérons que cette discussion vous aide.Je vais voir si je peux obtenir un code plus concret ici si vous êtes intéressé.

+1

Lien brisé. Est-ce correct? https://github.com/ninject/ninject.extensions.wcf –

+0

Vous avez raison - j'ai corrigé le lien. –

0

Je suis sûr que OperationContext est ce que vous cherchez