كيف يمكنني تطبيق نمط قوي للجلسة لكل طلب في مشروعي، مع التركيز على المعلومات التي تختبئ؟

StackOverflow https://stackoverflow.com/questions/2046168

سؤال

أقوم حاليا ببناء مشروع ASP.NET MVC، مع أحمق كطبقة ثابتة.

في الوقت الحالي، تم تنفيذ بعض الوظائف، ولكن فقط استخدم جلسات Locibernate المحلية: تحتاج كل طريقة تم الوصول إليها قاعدة البيانات (القراءة أو الكتابة) إنشاء جلسة LIMENATE الخاصة بها، مع جملة "استخدام ()".

المشكلة هي أنني أرغب في الاستفادة من قدرات التحميل الكسول في Thhibernate لتحسين أداء مشروعي.

هذا يعني جلسة أحذية مفتوحة لكل طلب حتى يتم تقديم الرأي. علاوة على ذلك، يجب دعم الطلبات المتزامنة (جلسات متعددة في نفس الوقت).

كيف يمكنني تحقيق ذلك نظيفة قدر الإمكان؟

لقد بحثت على شبكة الإنترنت قليلا وتعلمت عن نمط الجلسة لكل طلب. تستخدم معظم التطبيقات التي رأيتها نوعا من كائن HTTP * (HTTPCONTEXT، وما إلى ذلك) لتخزين الجلسة. أيضا باستخدام وظائف Application_BeGinRequest / Application_endRequest معقدة، نظرا لأنها تطلق سراحها لكل طلب HTTP (ملفات ASPX وملفات CSS وملفات JS وغيرها)، عندما أريد إرساء إنشاء جلسة مرة واحدة لكل طلب.

والقلق الذي لدي هو أنه لا أرغب في الحصول على وجهات نظري أو وحدات تحكم إمكانية الوصول إلى جلسات أحذية (أو، وأكثر عموما، مساحات الأسماء والأحذية). هذا يعني أنني لا أريد التعامل مع الجلسات على مستوى وحدة التحكم أو عرض واحد.

لدي بعض الخيارات في الاعتبار. أي واحد يبدو الأفضل؟

  • استخدم Interceptors (مثل في الشجاعة) التي يتم تشغيلها قبل وبعد إجراء وحدة التحكم. هذه سوف تفتح وغلق الجلسات / المعاملات. هل هذا ممكن في عالم ASP.NET MVC؟
  • استخدم CurrentSessionContext Singleton المقدمة من قبل Nibernate في سياق ويب. استخدام هذه الصفحة كمثال، أعتقد أن هذا وعد جدا، ولكن لا يزال يتطلب المرشحات على مستوى وحدة التحكم.
  • استخدم httpcontext.current.items لتخزين جلسة الطلب. هذا، إلى جانب قليل من خطوط التعليمات البرمجية في Global.asax.cs، يمكن أن يوفر لي بسهولة جلسة على مستوى الطلب. ومع ذلك، فهذا يعني أن التبعيات سيتم حقنها بين أحمق وآرائي (httpcontext).

شكراً جزيلاً!

هل كانت مفيدة؟

المحلول

حسنا يا شباب، بعد عمل بضعة أيام، قررت أخيرا استخدام httpcontext.current.items لتحميل الجلسة.

انها تعمل كبيرة!

إليك كيف فعلت ذلك

import System.Web
class SessionManager {
    public static ISession GetSession()
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session == null) {
            session = ...; // Create session, like SessionFactory.createSession()...
            HttpContext.Current.Items.Add("NHibernateSession", session);
        }
        return session;
    }

    public static void CloseSession()
    {
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session != null) {
            if (session.IsOpen) {
                session.close();
            }
            HttpContext.Current.Items.Remove("NHibernateSession");
        }
    }
}

باستخدام الطرق الثابتة التي توفرها هذه الفئة، يمكن للمرء الحصول على جلسة (على سبيل المثال، في وحدة تحكم) مرتبطة بال httpcontext الحالي (طلب الويب الحالي). نحتاج إلى مقتطف آخر من التعليمات البرمجية لاستدعاء الطريقة المقروءة () عند اكتمال الطلب.

في global.asax.cs:

protected void Application_EndRequest(object sender, EventArgs args)
{
    NHibernateSessionManager.CloseSession();
}

يتم استدعاء حدث Application_endRequest تلقائيا عند اكتمال الجلسة، لذلك يمكن إغلاق الجلسة بشكل صحيح التخلص منها. هذا مفيد، لأنه وإلا سيكون علينا القيام بذلك في كل وحدة تحكم!

نصائح أخرى

استخدم DI جنبا إلى جنب مع IOC. تأتي معظم IOC مع سلوك مثيل لكل طلب.

ينطوي "حل" على استخدام وحدة بحقن جلسة لكل طلب في وحدات تحكم:

http://letsfollowtheyellowbrickroad.blogspot.com/0/0/nibernate-sessions-in-aspnet-mvc.html.

إلقاء نظرة على S # ARP العمارة. وبعد إنها بنية رائعة للغاية ل ASP.NET MVC و Lhibernate.

يمكنك إضافة عامل تصفية إجراء يمكنه إدارة الجلسة والمعاملات الاحذية الخاصة بك. (يمكن القيام بذلك على مستوى الإجراء أو وحدة التحكم.) هنا مثال عليه:

http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nibernate.aspx.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top