C# 如何使用WebAPI/NHibernate实现会话模式

C# 如何使用WebAPI/NHibernate实现会话模式,c#,asp.net-mvc,nhibernate,dependency-injection,asp.net-web-api,C#,Asp.net Mvc,Nhibernate,Dependency Injection,Asp.net Web Api,我有一个MVC项目,我专门使用一个定制的“工作单元”模式,在后端使用NHibernate,我将其作为IUnitOfWork和IUnitOfWorkFactory接口公开给我的应用程序;这些接口通过Ninject作为我的NHibernate实现注入 我在修改后的“每请求会话”样式中使用UOW。。。当我需要执行数据库操作时,我从注入的IUnitOfWorkFactory显式生成我的IUnitOfWork;将CRUD保留在它所属的位置(在我的视图和控制器之外)似乎容易得多,并且可以有效地防止意外的N+

我有一个MVC项目,我专门使用一个定制的“工作单元”模式,在后端使用NHibernate,我将其作为
IUnitOfWork
IUnitOfWorkFactory
接口公开给我的应用程序;这些接口通过Ninject作为我的NHibernate实现注入

我在修改后的“每请求会话”样式中使用UOW。。。当我需要执行数据库操作时,我从注入的
IUnitOfWorkFactory
显式生成我的
IUnitOfWork
;将CRUD保留在它所属的位置(在我的视图和控制器之外)似乎容易得多,并且可以有效地防止意外的N+1编码问题。当然,实现起来有点困难,但到目前为止,我对它非常满意

现在我想实现一个WebAPI,它提供
IQueryable
风格的REST调用,而我的UOW模式并没有挖掘它。Queryables总是爆炸,试图调用已处理的NHibernate会话

我在网上读了一些关于如何实现
DelegatingHandler
来管理WebAPI调用的会话的内容。。。但我看到了几个问题:

  • 似乎所有的例子都假设“每个请求会话”模式。。。这是目前为止最流行的模式,但不是我正在使用的模式,所以我甚至不确定这是正确的方向
  • 目前还不清楚如何专门为这些Web API调用实现这个处理程序
  • 我已经看到很多关于使用“每会话会话”模式的建议,它可能比“每请求会话”模式寿命更长。。。听起来它可能适合这项工作,但是关于如何实现它的文档有点少
  • 我看到的所有示例实现都使用内置的NHibernate机制(
    CurrentSessionContext.Bind(ISession)
    )将NHibernate
    ISession
    与web应用程序紧密耦合;我更愿意引用我的
    IUnitOfWork
    接口,并相信它能够维护它需要的会话

  • 因此,我的问题是,如何使用我自己的
    IUnitOfWork
    接口实现
    IQueryable
    RESTful API,以对抗松散耦合的NHibernate后端?

    对于每个请求实现一个简单的会话,您将面临同样的问题。例如:

    // GET api/companies
    public IQueryable<Company> GetCompanies()
    {
        return _session.Query<Company>();
    }
    
    //获取api/公司
    上市公司()
    {
    返回_session.Query();
    }
    
    我通常在事务中包装所有数据库操作,包括selects,但由于查询执行被延迟,所以我不能用这种方法执行。通过创建ActionFilter并重写OnActionExecuted可以做到这一点,但困难在于获取对ISession的引用或过滤器中的IUnitOfWork实现。有一些例子说明了如何在web上使用Ninject和其他依赖项注入框架来实现这一点

    就我个人而言,我不认为抽象ISession有什么价值,特别是在WebAPI中,很少有资源不执行数据库操作。每次会话绝对不是一个很好的模式;它通常指在多个服务器往返过程中保持会话打开


    我首选的体系结构是使用Ninject管理ISessionFactory和ISession生存期(分别为单例和每个请求),并将ISession注入Api控制器。但是,您也可以将其注入到存储库或工作单元实现中。

    您看过这个使用WebApi的问答示例吗?这很有趣,但我不认为我能从中收集到我需要的东西。拥抱而不是抽象似乎是人们目前的行为方式。我想抽象
    ISession
    的主要原因是因为它闻起来像一个紧密耦合,我的应用程序中的所有其他内容都是通过干净的接口处理的。到目前为止,我的申请根本没有提到NHibernate。。。我希望保持这种方式。我认为我的答案仍然是相关的,你可以使用描述的ActionFilter。还有另一个答案,将你的web API移动到它自己项目中的另一个端点(另一个有效的url),并接受NH而不是抽象。通过抽象,您将失去延迟加载和返回
    IQueryable
    供以后使用的能力。这是一个“我不喜欢回答问题…”你真的不喜欢;我没有太多选择。@Rippo是的,我不喜欢这个答案。。。但这可能是一件实际的事情。