Un modo semplice per l'avvio NHibernate in un progetto WCF
-
10-10-2019 - |
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?
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>