2010-12-15 152 views
5

Je voudrais utiliser un module de démarrage NHibernate pour mon projet WCF comme celui que j'utilise pour mes projets ASP.NET MVC. Jeffery Palermo décrit le module de démarrage que j'utilise dans son article ASP.NET MVC HttpModule Registration. Essentiellement le code se résume à l'ajout d'un module de démarrage dans le web.config qui ressemble à ceci:Un moyen facile de démarrer NHibernate dans un projet WCF

<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"> 
    <add name="StartupModule" type="Infrastructure.NHibernateModule, Infrastructure, Version=1.0.0.0, Culture=neutral" /> 
    </modules> 
    </system.webServer> 

Ce ne fonctionne pas lorsque je tente d'exécuter le service avec le WCF Test Client ou directement contre le point final avec SoapUI. Quelles sont mes options pour un mécanisme de démarrage simple pour NHibernate dans un projet WCF?

Répondre

6

Vous pouvez résoudre le problème en utilisant un Message Inspector. Sur votre outil NHibernateModule IDispatchMessageInspector. Cela vous permettra d'ouvrir votre session NHibernate à chaque réception d'une requête et de la fermer juste avant l'envoi de votre réponse.

La démo de Palerme indique que vous aurez IHttpModule étendu. Si tel est le cas, vous allez ajouter deux méthodes pour l'interface IDispatchMessageInspector:

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
{ 
    context_BeginRequest(null, null); 
    return null; 
} 

et

public void BeforeSendReply(ref Message reply, object correlationState) 
{ 
    context_EndRequest(null, null); 
} 

Cela mettra en œuvre la nouvelle interface en utilisant votre ancien code. Vous devrez également implémenter l'interface IServiceBehavior. Cela vous permettra d'utiliser le module sur une extension de comportement dans votre web.config. Le IServiceBehavior exige trois méthodes, une seule ne fait rien:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
{ 
    foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers) 
    { 
     foreach (EndpointDispatcher ed in cd.Endpoints) 
     { 
      ed.DispatchRuntime.MessageInspectors.Add(this); 
     } 
    } 
} 

Cela ajoutera votre nouvel inspecteur à chacun des points d'extrémité. Vous devrez ensuite ajouter un BehaviorExtensionElement. Ce BehaviorExtensionElement doit renvoyer le type et une nouvelle instance de votre NHibernateModule. Cela vous permettra de créer un nouveau comportement qui renvoie le NHibernateModule dans votre fichier web.config.

public class NHibernateWcfBehaviorExtension : BehaviorExtensionElement 
{ 
    public override Type BehaviorType 
    { 
     get { return typeof(NHibernateModule); } 
    } 

    protected override object CreateBehavior() 
    { 
     return new NHibernateModule(); 
    } 
} 

Maintenant vous avez toutes les pièces dans l'ordre, vous pouvez les utiliser dans votre web.config. Pour les appliquer à tous les services, votre web.config devrait ressembler à ceci.

<system.serviceModel> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior> 
     <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
     <serviceMetadata httpGetEnabled="true"/> 
     <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
     <NHibernateSessionStarter /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
    <extensions> 
    <behaviorExtensions> 
     <add name="NHibernateSessionStarter" type="Infrastructure.NHibernateWcfBehaviorExtension, Infrastructure, Version=1.0.0.0, Culture=neutral" /> 
    </behaviorExtensions> 
    </extensions> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
</system.serviceModel>