1

我有一个自托管的 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 会话的正确方法吗?

更新

那我可以用这个吗:

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();
    }
});
4

1 回答 1

0

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

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

    //...

    public void Release(object instance)
    {
        this.kernel.Release(instance);
    }
}
于 2012-08-31T19:45:53.197 回答