自助主机应用程序中的ServiceStack NHibernate和Ninject(请求上下文)

时间:2012-08-31 13:45:09

标签: nhibernate request ninject servicestack

我有一个自托管ServiceStack应用程序,我尝试按请求构建ISession。我想以下内容可行:

Bind<ISession>()
  .ToMethod(NapraviSesiju)
  .InNamedScope(ControllerScope)
  .InScope(s => ReuseScope.Request)
  .OnActivation(s => s.BeginTransaction())
  .OnDeactivation(s =>
{
  if (!s.Transaction.IsActive) return;
  try
  {
    s.Transaction.Commit();
  }
    catch (Exception e)
  {
    s.Transaction.Rollback();
  }
});

private ISession NapraviSesiju(IContext kontekst)
{
  var sesija = kontekst.Kernel.Get<ISessionFactory>().OpenSession();
  return sesija;
}

这样可行,但请求停用不是即时的(它发生在30秒或1分钟后,某些请求根本不会停用)。

有人可以告诉我以这种方式处理NHibernate Sessions的正确方法吗?

更新

我可以使用它吗:

public class AppHost : AppHostHttpListenerBase
{
    private IKernel _jezgro;

    public override void Configure(Container container)
    {
        _jezgro = new StandardKernel(new NHibernateModul());
        container.Adapter = new NinjectIocAdapter(_jezgro);
    }

    public override void Release(object instance)
    {
        _jezgro.Release(((IHasSession)instance).Sesija);    //Release Sesija from SomeServis object below
    }
}

public class SomeServis : RestServiceBase<Some>, IHasSession    //implements NHibernate Session
{
    public ISession Sesija { get; set; }    //IHasSession implementation. Injected by Ninject.
}

Bind<ISession>()
.ToMethod(NapraviSesiju)
.InScope(s => ReuseScope.Request)   //reuse per request scope. Is this really needed, since release is happening at Release in AppHost?
.OnActivation(s => s.BeginTransaction())
.OnDeactivation(s =>
{
    if (!s.Transaction.IsActive) return;
    try
    {
        s.Transaction.Commit();
    }
    catch (Exception)
    {
        s.Transaction.Rollback();
    }
});

1 个答案:

答案 0 :(得分:0)

IOC Container wiki page的底部解释了IOC资源的Release行为。处理已处置资源的最简单方法是实现IRelease方法并将已释放的实例委托回Ninject,例如:

public class NinjectIocAdapter : IContainerAdapter, IRelease
{
    private readonly IKernel kernel;

    //...

    public void Release(object instance)
    {
        this.kernel.Release(instance);
    }
}