<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های پارسا پناهپور</title>
        <link>https://virgool.io/feed/@parsapanahpoor77</link>
        <description>Backend developer | .Net developer</description>
        <language>fa</language>
        <pubDate>2026-04-14 18:37:29</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2898087/avatar/avatar.png?height=120&amp;width=120</url>
            <title>پارسا پناهپور</title>
            <link>https://virgool.io/@parsapanahpoor77</link>
        </image>

                    <item>
                <title>الگوی Unit of Work چیست؟ (بررسی دیدگاه های مختلف)</title>
                <link>https://virgool.io/@parsapanahpoor77/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-unit-of-work-%DA%86%DB%8C%D8%B3%D8%AA-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%AF%DB%8C%D8%AF%DA%AF%D8%A7%D9%87-%D9%87%D8%A7%DB%8C-%D9%85%D8%AE%D8%AA%D9%84%D9%81-jqwo7r1ryzal</link>
                <description>این الگو در کتاب &quot;Patterns of Enterprise Application Architecture&quot; نوشته مارتین فاولر توضیح داده شده است.The unit of work pattern یک وب‌سایت فروشگاه را در نظر بگیرید. در فرآیند حذف دسته‌بندی‌ها، ابتدا دسته‌بندی را حذف می‌کنیم و سپس بعد از اطمینان از حذف صحیح دسته‌بندی، محصولات آن را حذف می‌کنیم. حالا، اگر هنگام حذف محصولات مشکلی پیش بیاید و محصولات به درستی حذف نشوند، دسته‌بندی حذف شده و ما مجموعه‌ای از محصولات بدون دسته‌بندی خواهیم داشت!!!اینجاست که الگوی Unit of Work به ما کمک می‌کند.یک UnitOfWork، همان‌طور که از نامش پیداست، برای انجام کاری وجود دارد. این کار می‌تواند به سادگی دریافت و نمایش اطلاعات باشد، یا به پیچیدگی پردازش یک سفارش جدید. زمانی که از EntityFramework استفاده می‌کنید و یک DbContext ایجاد می‌کنید، در واقع در حال ایجاد یک UnitOfWork هستید.الگوی Unit of Work یک الگوی طراحی است که می‌توانید از آن برای ارائه Repository های مختلف در برنامه نیز استفاده کنید. این الگو ویژگی‌های بسیار مشابهی با DbContext دارد، با این تفاوت که Unit of Work به Entity Framework Core وابسته نیست، برخلاف DbContext.تا اینجا، چندین Repository ساخته‌ایم. می‌توانیم به‌راحتی این Repository ها را به سازنده کلاس‌های سرویس تزریق کرده و به داده‌ها دسترسی پیدا کنیم. این کار زمانی که تنها ۲ یا ۳ Repositoryدرگیر باشد، بسیار آسان است. اما وقتی تعداد Repository ها بیش از ۳ تا شود، افزودن تزریق‌های جدید هر بار عملی نخواهد بود. برای قرار دادن همه Repository ها در یک شیء، از الگوی Unit Of Work استفاده می‌کنیم.مزیت این روش این است که در مثال بالا، زمانی که ابتدا دسته‌بندی‌ها را حذف می‌کنیم و سپس محصولات را، این تغییرات فقط در حافظه اعمال می‌شوند و با فراخوانی متد Commit، یک تراکنش در پایگاه داده ایجاد می‌شود و تمام این تغییرات به‌صورت یکجا در پایگاه داده اعمال می‌شوند. حالا اگر در وسط کار مشکلی پیش بیاید و به‌عنوان مثال یکی از محصولات نتواند حذف شود، تمام تغییرات به حالت اولیه بازگردانده می‌شوند و انگار که هیچ تغییری در پایگاه داده ایجاد نشده است (و این روش یک خطا برمی‌گرداند و به کاربر اطلاع می‌دهد که حذف به درستی انجام نشده است.) و در نتیجه نه دسته‌بندی‌ها و نه محصولات حذف نخواهند شد.الگوی Unit of Work مسئول ارائه Repository های موجود و اعمال تغییرات در منبع داده (DataSource) است تا یک تراکنش کامل انجام شود و از از دست رفتن داده‌ها جلوگیری کند.یکی دیگر از مزایای مهم این الگو این است که در صورت استفاده از چندین شیء Repository، هر یک از آن‌ها می‌توانند نمونه‌های متفاوتی از DbContext داشته باشند. این موضوع در موارد پیچیده ممکن است منجر به نشت داده‌ها شود.توجه: IDisposable یک رابط است که شامل یک متد به نام Dispose() می‌باشد که برای آزادسازی منابع غیرمدیریتی مانند فایل‌ها، جریانات، پایگاه‌های داده، اتصالات و غیره استفاده می‌شود.الگوی طراحی Unit of Work عملیات حفظ داده‌ها را برای چندین شیء در کسب‌وکار ما به‌عنوان یک تراکنش اتمیک (Atomic) اجرا می‌کند که اطمینان حاصل می‌کند که تمام تراکنش یا تأیید (commit) می‌شود یا برگشت (rollback) می‌یابد. الگوی طراحی Unit of Work چندین Repository را در خود جای می‌دهد و یک کانتکست پایگاه داده مشترک را بین آن‌ها به اشتراک می‌گذارد.محصورسازی یا Encapsulation به معنای حفاظت از یکپارچگی داده‌ها است. به این معنا که زمانی که یک کلاس به‌خوبی محصور شده باشد، داده‌های داخلی آن نمی‌توانند در یک وضعیت یا مقدار نامعتبر و ناهماهنگ قرار بگیرند. این به معنای حفاظت از یکپارچگی و دقت داده‌ها است که به آن Encapsulation گفته می‌شود.همان‌طور که ذکر شد، پنهان‌سازی اطلاعات و تجمیع داده‌ها یا عملیات انجام‌شده روی داده‌ها به‌صورت مشترک به Encapsulation کمک می‌کند. پنهان‌سازی اطلاعات داده‌های داخلی را از دید استفاده کنندگان آن کلاس مخفی می‌کند و قرار دادن داده‌ها و عملیات در کنار هم، یک نقطه ورود واحد برای تمام عملیاتی که می‌توان بر روی آن کلاس انجام داد ایجاد می‌کند.به این ترتیب، می‌توانید قبل از تغییر وضعیت یا داده‌های یک کلاس، یک بررسی انجام دهید و یکپارچگی داده‌هایی را که قرار است در کلاس شما قرار بگیرد، بررسی کنید.این موضوع همچنین در بحث محصورسازی invariants (ثابت‌ها) مطرح می‌شود. invariant به معنای یک سری شرایط است که باید در تمام اوقات حفظ شوند. به‌عنوان یک برنامه‌نویس، شما باید اطمینان حاصل کنید که هیچ‌یک از invariant‌ها هرگز معیوب نشوند و وظیفه شماست که تدابیر لازم برای این کار را در نظر بگیرید.این دو مفهوم به‌طور نزدیکی با هم مرتبط هستند، اما تفاوت‌های زیادی نیز دارند. محصورسازی (Encapsulation) به ثبات داده‌ها اشاره دارد، در حالی که انتزاع (Abstraction) به بزرگ‌تر کردن جنبه‌های ضروری و حذف جنبه‌های غیرضروری می‌پردازد.کمکی که انتزاع به ما می‌کند این است که دیگر نگران این نیستیم که آیا عملی که انجام می‌دهیم معتبر است یا خیر و این وظیفه را به Encapsulation واگذار کرده و بر آنچه که کد انجام می‌دهد، تمرکز می‌کنیم، نه بر اینکه چگونه این کار را انجام می‌دهد.این‌جا جایی است که اختلاف‌نظرهایی در مورد ایجاد Repository وجود دارد.همان‌طور که قبلاً اشاره شد، زمانی که یک انتزاع سطح بالا، مجموعه‌ای از پیچیدگی‌های سطح پایین را انتزاع می‌کند، از انتزاع استفاده می‌کنیم. وقتی خود DbContext یک Unit of Work است، دلیلی برای تعریف یک Unit of Work دیگر نداریم. با این پیاده‌سازی، در واقع با انتزاع‌های سطحی مواجه هستیم که به آن‌ها انتزاع‌های سطحی (Shallow abstractions) می‌گوییم. در سناریوهایی که پیچیدگی در DbContext بیش از حد می‌شود، Unit of Work از حالت سطحی خارج شده و پیاده‌سازی آن توجیه‌پذیر می‌شود.زمانی که از EF Core استفاده می‌کنید و یک DbContext ایجاد می‌کنید، در واقع در حال ایجاد یک Unit of Work هستید.کلاس DbContext بر پایه الگوی Unit of Work استوار است و شامل تمام موجودیت‌های DbSet می‌باشد. این کلاس عملیات پایگاه داده را بر روی این موجودیت‌ها مدیریت کرده و سپس تمام این به‌روزرسانی‌ها را به‌عنوان یک تراکنش در پایگاه داده ذخیره می‌کند.کلاس DbContext ترکیبی از الگوهای Unit of Work و Repository است.برای خواندن مقاله ی Repository کلیک کنید .برای مطالعه ی مقاله ی اصلی این پست کلیک کنید . </description>
                <category>پارسا پناهپور</category>
                <author>پارسا پناهپور</author>
                <pubDate>Tue, 08 Oct 2024 14:33:09 +0330</pubDate>
            </item>
                    <item>
                <title>الگوی Repository چیست ؟</title>
                <link>https://virgool.io/@parsapanahpoor77/httpsvirgoolioparsapanahpoor77repository-wcu8da7tkkoe</link>
                <description>ابتدا، ما تعریف الگوی Repository را از این کتاب با هم مرور خواهیم کرد:Mediates between the domain and data mapping layers, acting like an in-memory collection of domain objects.الگوی ریپوزیتوری چیست ؟ این تعریف بیان می‌کند که Repositor در واقع collection ازEntities است که به عنوان واسطی بین Data Mappers عمل می‌کند.گفتیم که Repository مجموعه‌ای از Entities است، بنابراین باید متدهایی که یک مجموعه دارد را نیز شامل شود، متدهایی مانند:addremovegetfindاولین نکته‌ای که باید به آن توجه کنیم این است که ما در حال صحبت درباره یک collection هستیم، بنابراین متدهایی مانند save (ذخیره) یا update (به‌روزرسانی) نداریم.خب! اگر متدهای ذخیره و به‌روزرسانی نداریم، چطور می‌توانیم یک record جدید ایجاد کنیم یا آن را به‌روزرسانی کنیم؟ پاسخ این سوال را زمانی که به الگوی واحد کار (Unit of Work) اشاره کنیم، خواهیم داد.گفتیم که هر Repository نمایانگر یک Entity است و مانند یک collection از آن Entity در حافظه عمل می‌کند. همچنین گفتیم که هر Repository به دلیل ویژگی collection بودن، دارای متدهایی مانند add ، remove ، get و find است. حالا، از آنجا که همه Repository ها باید این متدها را داشته باشند، برای جلوگیری از تکرار کد، یک کلاس پایه ایجاد می‌کنیم که این متدهای اساسی را دارد و سایر کلاس‌ها از آن ارث‌بری می‌کنند.حالا اجازه دهید به یکی از مزایای Repository Pattern اشاره کنیم:جلوگیری از تکرار کد.کمک به تست‌پذیر بودن کد.استقلال برنامه از پایگاه داده‌ها و ORMها.در برنامه‌هایی که منطق کسب‌وکار به طور مستقیم به داده‌ها دسترسی دارد، ممکن است با مشکلات زیر مواجه شوید:تکرار کدافزایش پتانسیل خطاهای برنامه‌نویسیدشواری در متمرکز کردن سیاست‌های مرتبط با داده‌ها، مانند کشینگ (Caching)عدم توانایی در تست منطق کسب‌وکار به صورت جداگانه از وابستگی‌های خارجیمخازن یا Repository ها کلاس‌هایی هستند که منطق لازم برای ذخیره یا بازیابی داده‌ها را پنهان می‌کنند. بنابراین، برنامه ما اهمیتی نمی‌دهد که از چه نوع ORM استفاده می‌کنیم، زیرا همه چیز مرتبط با ORM در لایه مخزن مدیریت می‌شود. Repository ها کلاس‌ها یا اجزایی هستند که منطق مورد نیاز برای دسترسی به منابع داده را در خود دارند. آن‌ها عملکردهای عمومی دسترسی به داده‌ها را متمرکز کرده و باعث بهبود قابلیت نگهداری می‌شوند و همچنین زیرساخت یا فناوری مورد استفاده برای دسترسی به پایگاه داده‌ها را از لایه Domain Model جدا می‌کنند.از آنجایی که Domain نباید به فناوری وابسته باشد!درنتیجه نباید به لایه دسترسی به داده‌ها یا EF Core یا... ارجاع داشته باشد. دامنه فقط مجموعه‌ای از اینترفیس‌ها را تعریف می‌کند که بعداً به عنوان لایه Data Access شناخته می‌شوند و این اینترفیس‌ها باید پیاده‌سازی شوند!معماری باید از فریمورک‌ها مستقل باشد. (رابرت سیسیل مارتین)ممکن است مواردی پیش بیاید که نیاز به استفاده از چندین ORM در یک راه‌حل داشته باشید. احتمالاً از Dapper برای خواندن داده و از EFCore برای نوشتن داده استفاده کنید. این کار صرفاً برای بهینه‌سازی عملکرد است.الگوی Repository به ما کمک می‌کند با ایجاد یک لایه انتزاعی در بالای لایه دسترسی به داده‌ها به این هدف برسیم. اکنون دیگر نیازی نیست که برنامه شما به EFCore یا هر ORM دیگری وابسته باشد. به جای اینکه EFCore تنها گزینه شما برای دسترسی به داده‌ها باشد، تبدیل به یکی از گزینه‌هایتان می‌شود.حال که لایه EFCore خود را پیکربندی کرده‌ایم، بیایید کمی درباره روش سنتی دریافت داده‌ها از این لایه صحبت کنیم. به‌طور سنتی، شما مستقیماً از شیء dbContext برای خواندن و نوشتن داده‌ها استفاده می‌کنید. این روش خوب است، اما آیا برای بلندمدت واقعاً ایده‌آل است؟ وقتی مستقیماً از dbContext استفاده می‌کنید، در واقع Entity Framework Core را به شدت با برنامه خود وابسته می‌کنید. بنابراین، در آینده زمانی که فناوری جدیدتر و بهتری از EFCore منتشر شود یا نیاز باشد، تغییرات لازم برای پیاده‌سازی این فناوری جدید بسیار آزاردهنده خواهد بود، درست است؟از یک طرف، حامیان الگوی Repository معتقدند که تمام کدهای دسترسی به پایگاه داده باید در Repository قرار گیرد، و از طرف دیگر، کسانی که با DbSet و EF کار می‌کنند، اعتراف می‌کنند که DbSet خود یک Repository است، بنابراین نیازی به ایجاد یک Repository دیگر نیست.هر دو نوع تفکر تا حدی صحیح هستند. الگوی Repository و ایده پشت آن برای کار با پایگاه داده‌ها مفید است، اما این الگو مدت‌ها قبل از معرفی ORM‌هایی مانند EF شکل گرفته است و امروزه، با وجود ORM‌های قدرتمندی مثل EF، ممکن است استفاده از این الگو چندان مفید نباشد.مهم‌ترین دلایلی که ممکن است بخواهید این کار را انجام دهید (اضافه کردن یک لایه انتزاعی در بالای DbContext):شاید نمی‌خواهید پروژه‌تان کاملاً به Entity Framework و معماری آن وابسته باشد. بنابراین، Entity Framework را پشت این انتزاعات پنهان می‌کنید تا بتوانید آن را با هر ORM دیگری بدون هیچ تغییری در اینترفیس لایه دسترسی به داده‌ها جایگزین کنید.پیاده‌سازی Repository سفارشی در هنگام پیاده‌سازی میکروسرویس‌ها یا برنامه‌های پیچیده‌تر چندین مزیت ارائه می‌دهد. الگوهای Unit of Work و Repository برای محصور کردن لایه persistence در نظر گرفته می‌شوند، به‌طوری‌که از لایه‌های برنامه و مدل دامنه جدا می‌شوند.شما از Repository برای تعیین عملیات مجاز روی موجودیت‌های خاص استفاده می‌کنید.خود مایکروسافت توصیه می‌کند که در سناریوهای پیچیده از الگوهای Repository استفاده کنید تا وابستگی را کاهش داده و قابلیت تست‌پذیری را بهبود ببخشید. در مواردی که می‌خواهید ساده‌ترین کد ممکن را داشته باشید، بهتر است از الگوی Repository اجتناب کنید.اگر به الگوی unit of work علاقه دارید میتونید دیدگاه های مختلف و نظرات پیرامون این الگو رو در مقاله ی من مطالعه کنید . برای خواندن کلیک کنید .</description>
                <category>پارسا پناهپور</category>
                <author>پارسا پناهپور</author>
                <pubDate>Wed, 25 Sep 2024 11:11:41 +0330</pubDate>
            </item>
            </channel>
</rss>