عنوان:

‫پیاده سازی generic repository یک ضد الگو است


نویسنده: وحید نصیری
تاریخ: ۱۳۹۲/۰۱/۲۵ ۱:۴۴
آدرس: www.dntips.ir


مشاهده مطلب اصلی

نظرات

  • محسن درپرستی در ۱۳۹۲/۰۱/۲۵ ۹:۴۶
    متوجه نشدم چطور Generic Repository باعث وابستگی بین تکنولوژی DataLayer و Application Logic (دلیل اول) میشه ؟
    • وحید نصیری در ۱۳۹۲/۰۱/۲۵ ۱۱:۱
      خلاصه این مطلب خوب به این نحو است:
      الف) اگر از یک Generic Repository داخل کدهای یک مثلا کنترلر مستقیما استفاده می‌کنید، فقط خودتان را گول زده‌اید!  این طراحی نشتی دارد و همچنین حد و مرز مشخصی را نمی‌توان برای آن قائل شد.
      نشتی یا وابستگی که اینجا عنوان شده نمونه‌اش یک چنین متدی است:
      IEnumerable<T> Find(Expression<Func<T, bool>> query);
      در اینجا کار پیاده سازی query به یک لایه بالاتر (مانند یک کنترلر) محول شده که اشتباه است. حد و مرز لایه پیاده سازی کننده منطق تجاری شما باید مشخص باشد و نه باز. یک Expression فقط یک عبارت است که می‌توان با کمک آن انواع و اقسام کوئری‌های وابسته به فناوری دسترسی به داده‌های در حال استفاده را تهیه کرد. به عبارتی اگر تصور می‌کنید که در اینجا کپسوله سازی خوبی را انجام داده‌اید، اینطور نیست. چون دسترسی مستقیم به ORM خود را به لایه‌ای دیگر واگذار کرده‌اید و این دسترسی محصور نشده است.
      نمونه خوبی را که مثال زده به صورت زیر است:
      public IEnumerable<Customer> FindCustomerByName(string input)
          {
              return internalRepository.FindBy(c => c.Name == input);
          }
      در اینجا دقیقا حد و مرز لایه تجاری و امکان دسترسی به آن مشخص است و دارای نشتی (باز بودن برای تغییرات بی حد و حصر در لایه‌های دیگر) نیست.
      ب) الزامی به تعریف یک Generic Repository نیست اما اگر آن‌را تعریف کردید، باید این کلاس خاص داخل کدهایی که منطق تجاری برنامه را با حد و مرز مشخصی کپسوله می‌کنند استفاده کنید. نه اینکه آن‌را در خط مقدم کاری (مانند استفاده مستقیم در یک کنترلر) بکار بگیرید. به آن بیشتر به شکل یک سری متد کمکی نگاه کنید و بس. نامگذاری جالبی را هم در این حالت پیشنهاد داده: internalRepository 
      • حمیدرضا م در ۱۳۹۳/۱۱/۲۵ ۱۴:۳۴
        با سلام

        آیا بدین صورت درست است که Repository رو بصورت جنریک جهت حذف کدهای تکراری لایه سرویس بسازیم (Add/Update/Delete/GetAll/GetById) سپس با کمک Extention Methods (کلاس‌های تکمیل کننده) سایر متدهای مورد نیاز هر entity رو به Reository اش اضافه کنیم (مثلا GetByName/GetByRangeDate).

        بدین صورت هم حد و مرز رعایت میشه و هم از کدنویسی‌های تکراری راحت میشیم