Entity FrameWork DbContext وDependency Injection و DbContextScope
301, MovedPermanently
http://dotnetexpert.ir/Blog/1393/8/9/entity-framework-dbcontext-and-dependency-injection-and-dbcontextscope icon

یکی از متداول‌ترین الگوهای امروزی برای رفع وابستگی به یک سرویس در یک Object وابسته به ان سرویس الگوی Dependency Injection می‌باشد . در این الگو , وابستگی به سایر کلاس‌ها , به صورت اتوماتیک به داخل سرویس مورد نظر تزریق می‌شود و نیاز به نمونه گیری و ساخت Object از ان وابستگی به صورت Explicit نیست . این الگو در مهندسی نرم افزار فوایدیی (Refactoring , کنترل LifeTime اشیاء , ...) دارد که مرتبط با موضوع این مقاله نیست , اما نحوه صحیح نمونه گیریی از DbContext با الگوی Dependency Injection در انواع برنامه‌ها اعم از وب یا دسکتاپ موضوع اصلی این مقاله می‌باشد. 

Entity FrameWork DbContext وDependency Injection و DbContextScope
  • #
    ‫۹ سال و ۱۱ ماه قبل، یکشنبه ۱۸ آبان ۱۳۹۳، ساعت ۱۴:۴۰
    درسته که فایل‌های ashx در تردهای جدایی اجرا می‌شن. اما این‌ها در requestهای جدایی هم نسبت به درخواست صفحه‌ی اصلی اجرا می‌شن. یعنی به ازای هر کدوم یک درخواست جدید به سرور ارسال میشه. بنابراین مشکل استفاده از یک context در چندترد در اینجا وجود نداره. به ازای هر درخواست جدید ashx یک context جداگانه درست میشه.
    در مورد http moduleها وضع فرق می‌کنه. http module‌ها دقیقا در ترد همان درخواست اصلی اجرا میشن. یعنی چند ترد جداگانه در اینجا درست نخواهد شد.
    • #
      ‫۹ سال و ۱۱ ماه قبل، یکشنبه ۱۸ آبان ۱۳۹۳، ساعت ۱۹:۲۹
      ممنون از نظرتون
      خوب Multi Thread تنها یکی از مشکلاتی است که DbContextScope حل می‌کند .
      ولی من خودم از HttpModule و Async Await استفاده کردم
      با استفاده از SimpleInjector  و PerWebRequest دقیقا به همین مشکل برخوردم.
      • #
        ‫۹ سال و ۱۱ ماه قبل، یکشنبه ۱۸ آبان ۱۳۹۳، ساعت ۲۲:۵۰

        خطایی که عنوان کردید، در انتهای مطلب پردازش‌های Async در Entity framework 6 بحث شده. محدودیت خود EF هست. مثالی هم که زده شده یک برنامه‌ی کنسول ویندوزی است. یعنی لزومی نداره که حتما برنامه‌ی وب باشه تا این خطا رخ بده. این خطا هم زمانی رخ می‌ده که Context در چند ترد استفاده بشه و پرازش موازی شروع بشه. این مساله اگر مثلا از Task.Run در برنامه‌های وب استفاده کنید ممکنه رخ بده. چون http module که در ترد دومی اجرا نمیشه. http module چیزی نیست جز کپسوله کردن رخدادهای begin request و end request قابل تعریف در فایل global.asax.cs. این رخدادها هم دقیقا در همون ترد درخواست وب اجرا می‌شن و نه خارج از اون. حالا اگر بحث متدهای async تقلبی رخ بده، بله. ترد دومی اجرا میشه که ضروری نبوده.

        • #
          ‫۹ سال و ۱۱ ماه قبل، یکشنبه ۱۸ آبان ۱۳۹۳، ساعت ۲۳:۲۵
          ممنون . مقاله ایی که گفتین قبلا مطالعه کردم , اما مشکل دقیقا همون چیزی که گفتم , یعنی چه در متد موجود در Controller و چه در متد HttpModule از Async و Await جداگانه استفاده شده است .

          کد داخل Controller :

          var entries = await this.repository.BlogEntries
                          .Include(b => b.Tags)
                          .AsNoTracking()
                          .Where(b => b.Visible && b.PublishDate <= DateTime.Now)
                          .OrderByDescending(b => b.PublishDate)
                          .ToListAsync();

          کد داخل HttpModule
           var existingFeedStatistic = await this.repository.FeedStatistics
                          .FirstOrDefaultAsync(f => f.Identifier == command.Identifier
                              && f.Application == command.Application
                              && f.Identifier != null
                              && f.Created >= currentDay
                              && f.Created < nextDay);
          
          await this.repository.SaveChangesAsync();