Domanda

Vorrei utilizzare il modulo di NHibernate di avvio per il mio progetto WCF come l'uso che ho per i miei progetti ASP.NET MVC. Jeffery Palermo delinea il modulo di avvio che uso nel suo post ASP.NET MVC HttpModule registrazione . In sostanza il codice si riduce a l'aggiunta di un modulo di avvio nel web.config che assomiglia a questo:

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

Questo non funziona quando si tenta di eseguire il servizio con la prova WCF client o direttamente contro l'endpoint con SoapUI . Quali sono le opzioni per un semplice meccanismo di avvio per NHibernate in un progetto WCF?

È stato utile?

Soluzione

È possibile risolvere il problema utilizzando un Message Inspector . Sul vostro NHibernateModule implementare IDispatchMessageInspector . Questo vi permetterà di aprire la sessione di NHibernate quando si riceve ogni richiesta e chiude a destra prima la risposta viene inviata fuori.

demo di Palermo indica che si dovrà IHttpModule estesa. Se questo è il caso, si aggiungono due metodi per l'interfaccia IDispatchMessageInspector:

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

e

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

In questo modo implementare la nuova interfaccia con il vecchio codice. Sarà inoltre necessario per l'attuazione del IServiceBehavior interfaccia . Questo vi permetterà di utilizzare il modulo su un'estensione di comportamento nel web.config. L'IServiceBehavior richiede tre metodi, solo uno sarà in realtà fare nulla:

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

Questo aggiungerà il nuovo commissario a ciascuno dei punti finali.

Si dovrà poi aggiungere una BehaviorExtensionElement . Questo BehaviorExtensionElement deve restituire il tipo e una nuova istanza del vostro NHibernateModule. Questo vi permetterà di creare un nuovo comportamento che restituisce il NHibernateModule nel web.config.

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

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

Ora avete tutti i pezzi in ordine, è possibile utilizzare nel vostro web.config. Per applicarle a tutti i servizi web.config dovrebbe essere simile alla seguente.

<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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top