8

アプリの作成を開始しており、ServiceStackを使用する予定です。NHibernate ISession、またはその他の「リクエストごとの」コンテキスト固有のセッションオブジェクトを処理するためのベストプラクティス/優れたアプローチを知りたいだけです。

IocにISessionFactoryを登録するのは次のように思いました。

container.Register<ISessionFactory>(sessionFactory);

そして、必要に応じて新しいSessionオブジェクトを取得します...または、セッションオブジェクトを直接提供します。

container.Register<ISession>(c => sessionFactory.OpenSession()).ReusedWithin(ReuseScope.None);

または、Global.asaxBeginRequestイベントを介してISessionとデフォルトトランザクションを処理します。

protected void Application_BeginRequest(object sender, EventArgs e)
{
    var session = factory.OpenSession();
    ITransaction itrans = session.BeginTransaction();
    Context.Items.Add("session", session);
    Context.Items.Add("trans", itrans);
}

それで、私はちょっと迷っています、上記のテクノロジー、またはEFや別のRest-Servicesフレームワークのような同様のテクノロジーを考えると、ベストプラクティスは何ですか?

前もって感謝します

4

3 に答える 3

4

HttpHandlerを使用してリクエストごとにセッションを作成することは、私が見つけた最も一般的な方法です。Ayendeは、セッションの作成は非常に軽量であると説明しています。http://ayende.com/blog/4123/what-is-the-cost-of-opening-a-session

Ayendeには実際に一連の投稿があり、データアクセスソリューションを徐々に構築しています。各投稿では、彼がやったことをした理由と、これまでに行った手順で解決する必要のある問題について説明しています。ここから開始:http://ayende.com/blog/4803/refactoring-toward-frictionless-odorless-code-the-baseline

最後に、http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

上記はすべて、リクエストごとのセッションのバリエーションです。すべてに共通することは、セッション/トランザクションの作成について手動で心配する必要がないことです。トランザクションを自動的にコミット/ロールバックします。

于 2012-07-06T04:08:32.683 に答える
3

See this blog post for a complete example of how to optimally use ServiceStack and NHibernate together:

http://www.philliphaydon.com/2012/06/using-nhibernate-with-servicestack/ Here's the AppHost example used in the above post:

public class Global : HttpApplication
{
    public class SampleServiceAppHost : AppHostBase
    {
        private readonly IContainerAdapter _containerAdapter;
        public SampleServiceAppHost(ISessionFactory sessionFactory)
            : base("Service Stack with Fluent NHibernate Sample", typeof(ProductFindService).Assembly)
        {
            base.Container.Register<ISessionFactory>(sessionFactory);
        }

        public override void Configure(Funq.Container container)
        {
            container.Adapter = _containerAdapter;
        }
    }

    void Application_Start(object sender, EventArgs e)
    {
        var factory = new SessionFactoryManager().CreateSessionFactory();

        (new SampleServiceAppHost(factory)).Init();
    }
}
于 2012-07-06T03:55:38.243 に答える
3

これは古い質問ですが、私は先に進んで、別の答えにまだ興味がある人に、これをどのように行ったかを示したいと思いました。

したがって、新しいServiceStackAPIでServiceRunnerを使用しています。

public class BaseServiceRunner<TRequest> : ServiceRunner<TRequest>
{
    public BaseServiceRunner(AppHost appHost, ActionContext actionContext)
    : base(appHost, actionContext) { }

    public override void OnBeforeExecute(IRequestContext requestContext, TRequest request)
    {
        var req = request as MyRequestType;

        if(req == null)
            base.OnBeforeExecute(requestContext, request);

        var factory = TryResolve<NHibernate.ISessionFactory>();
        var session = factory.OpenSession();
        var trans = session.BeginTransaction(IsolationLevel.ReadCommitted);

        requestContext.SetItem("session", session);
        requestContext.SetItem("transaction", trans);
    }        

    public override object OnAfterExecute(IRequestContext requestContext, object response)
    {
        var trans = requestContext.GetItem("transaction") as ITransaction;
        if (trans != null && trans.IsActive)
            trans.Commit();

        var session = requestContext.GetItem("session") as ISession;
        if (session != null)
        {
            session.Flush();
            session.Close();
        }

        return base.OnAfterExecute(requestContext, response);
    }

    public override object HandleException(IRequestContext requestContext, TRequest request, Exception ex)
    {
        var req = request as MyRequestType;
        if(req != null)
        {
            var trans = requestContext.GetItem("transaction") as ITransaction;
            if (trans != null && trans.IsActive)
                trans.Rollback();

            var session = requestContext.GetItem("session") as ISession;
            if (session != null)
            {
                session.Flush();
                session.Close();
            }
        }
        return base.HandleException(requestContext, request, ex);
    }        
}   
于 2013-03-20T20:50:47.153 に答える