معرفی Unit of Work

Unit of Work به معنای واحد کار است و یک نوع الگوی طراحی است. بر اساس این الگو نباید در هر قسمت از برنامه شئ ای از روی DbContext بسازیم و فقط یک بار باید از روی DbContext شی جدید ساخت. به عبارت دیگر برنامه نویس در لایه ی Business Logic نباید با Repository های مختلف کار کند و این وظایف باید به Unit of Work سپرده شود و برنامه نویس فقط از آن استفاده کند. می توان از Unit of Work به عنوان یک Facade از Repository ها یاد کرد.

طبق این الگو، تمام درخواست های کار با دیتابیس در یک صف قرار می گیرند و پشت سر هم انجام می شوند. بعد از آنکه تمام این درخواست ها با موفقیت اجرا شدند، دستور SaveChanges اجرا می شود. چون این الگوی طراحی از مفهوم Transaction استفاده می کند، اگر در این بین مشکلی پیش بیاید یا یکی از درخواست ها با خطا مواجه شود تمام درخواست ها لغو می شوند و هیچ تغییری در دیتابیس رخ نخواهد داد و در اصطلاح Rollback اتفاق می افتد.

این روش مزیت های بسیاری دارد، مثلا Connection های کمتری به دیتابیس وجود خواهند داشت چون در Unit of Work یک تراکنش به ازای چند عمل وجود دارد و نه یک تراکنش به ازای هر عمل.

unit of work

چرا Unit Of Work ؟

  1. عدم دسترسی مستقیم Controller به دیتابیس هنگام عملیات CRUD. چون ارتباط، با استفاده از کلاس و اینترفیس مربوط به Unit Of Work برقرار می شود.
  2. افزایش امنیت دیتابیس
  3. بهینگی سیستم و جلوگیری از خطاهای بالقوه دیتابیسی( اگر درخواستی نیاز به چندین بار ارتباط با دیتابیس داشته باشد، در هر ارتباط یک نمونه از دیتابیس در سرور ساخته می شود که اگر تعداد درخواست ها بالا باشد سرعت دیتابیس و سرور کند می شود.)

مثال:

مثال دو Model به نام های Person و Category داریم و می خواهیم به جای آنکه از Repository هر کدام از آنها استفاده کنیم از یک Context واحد استفاده کنیم. بهتر است قبل از شروع کار نگاهی به این Model ها بیاندازیم.

کلاس Base Entity

کلاس Person Model

کلاس Category Model

ابتدا باید یک پوشه ی مستقل به نام Repository ایجاد نماییم و در آن یک اینترفیس به نام IRepository بسازیم.

IRepository pattern

سپس باید کلاس Repository را بنویسیم که اینترفیس IRepository را پیاده سازی می کند.

Repository implementation

سپس باید اینترفیس IPersonRepository را بنویسیم.

و کلاسی به نام SqlPersonRepository که آن را پیاده سازی کند.

اینترفیس ICategoryRepository

اگر دقت کنید می بینید که چیزی در این اینترفیس نوشته نشده است. دلیلش این است که Repository مربوط به Category تنها از همان متدهای اصلی موجود در اینترفیس IRepository استفاده می کند. کلاسی که این اینترفیس را پیاده سازی می کند نیز به شکل زیر خواهد بود.

سپس باید یک اینترفیس به نام IUnitOfWork بسازیم. این اینترفیس به شکل زیر خواهد بود.

بعد از آن باید کلاس Unit of Work را بنویسیم که اینترفیس IUnitOfWork را پیاده سازی می کند.

و در کنترلر، به جای آن که Repository های مختلف را Inject کنیم، تنها کافی است که اینترفیس IUnitOfWork را Inject نماییم.

و در Startup.cs در متد  ConfigureServices کد زیر را باید بنویسیم.

نوشته شده توسط mrbitmap علیرضا علی رمضانی

مقالات مرتبط

جدیدترین مقالات

فهرست