在 WCF 项目中启动 NHibernate 的简单方法

发布于 2024-10-08 00:29:53 字数 826 浏览 8 评论 0原文

我想为我的 WCF 项目使用 NHibernate 启动模块,就像我在 ASP.NET MVC 项目中使用的那样。 Jeffery Palermo 概述了我在他的文章中使用的启动模块 ASP.NET MVC HttpModule 注册。本质上,代码归结为在 web.config 中添加一个启动模块,如下所示:

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

当我尝试使用 WCF 测试客户端 或使用 SoapUI 直接针对端点。对于 WCF 项目中的 NHibernate 简单启动机制,我有哪些选择?

I'd like to use an NHibernate startup module for my WCF project like the one I use for my ASP.NET MVC projects. Jeffery Palermo outlines the startup module that I use in his post ASP.NET MVC HttpModule Registration. Essentially the code boils down to adding a startup module in the web.config that looks like this:

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

This is not working when I try to run the service with the WCF Test Client or directly against the endpoint with SoapUI. What are my options for a simple startup mechanism for NHibernate in a WCF project?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天赋异禀 2024-10-15 00:29:53

您可以使用消息检查器解决该问题。在 NHibernateModule 上实现 IDispatchMessageInspector。这将允许您在收到每个请求时打开 NHibernate 会话,并在发送回复之前关闭它。

Palermo 的演示表明您将扩展 IHttpModule。如果是这种情况,您将为 IDispatchMessageInspector 接口添加两个方法:

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

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

这将使用旧代码实现新接口。您还需要实现 IServiceBehavior 接口。这将允许您在 web.config 中的行为扩展上使用该模块。 IServiceBehavior 需要三种方法,只有一种方法实际上会执行任何操作:

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

这会将新检查器添加到每个端点。

然后,您必须添加 BehaviorExtensionElement。这个BehaviorExtensionElement应该返回NHibernateModule的类型和一个新实例。这将允许您创建一个新行为,在 web.config 中返回 NHibernateModule。

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

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

现在您已按顺序排列了所有部分,您可以在 web.config 中使用它们。要将它们应用到所有服务,您的 web.config 应如下所示。

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

You can resolve the issue by using a Message Inspector. On your NHibernateModule implement IDispatchMessageInspector. This will allow you to open your NHibernate session as each request is received and close it right before your reply is sent out.

Palermo's demo indicates that you will have extended IHttpModule. If that is the case, you will add two methods for the IDispatchMessageInspector interface:

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

and

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

This will implement the new interface using your old code. You will also need to implement the IServiceBehavior interface. This will allow you to use the module on a behavior extension in your web.config. The IServiceBehavior requires three methods, only one will actually do anything:

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

This will add your new inspector to each of the endpoints.

You will then have to add a BehaviorExtensionElement. This BehaviorExtensionElement should return the type and a new instance of your NHibernateModule. This will allow you to create a new behavior that returns the NHibernateModule in your web.config.

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

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

Now you have all the pieces in order, you can use them in your web.config. To apply them to all services your web.config should look like the following.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文