ورود

View Full Version : Repository In ASP.NET MVC



مهدی هادیان2
چهارشنبه 15 آبان 1392, 21:29 عصر
بسم الله الرحمن الرحیم
با سلام
بنده با استفاده از Mvc Scaffolding کنترلرها و ... رو ایجاد کردم تو سوئیچ هاش Repository وجود داشت که وقتی استفاده کردم دیدم کلاس ها رو مطابق با الگوی Repository می سازه.
قبلا که مطالب آقای نصیری رو خونده بودم یادمه که مخالف سرسخت این الگو بودند.
لطفا نظرتون رو بفرمائید.
با سپاس فراوان

hakim22
پنج شنبه 16 آبان 1392, 07:51 صبح
این کار حجم کد نویسی رو بالا میبره اما بدون شک در پروژه های بزرگ ارزش خودشو داره. اگر از Repository استفاده نکنید دستورات برقراری ارتباط با بانک رو کجا باید قرار بدید !؟

در کنترلر یا WebAPI نوشتن دستورات برقراری ارتباط با بانک کار اصلی کنترلر هارو که آماده سازی و انتخاب ویو مناسب هست رو بیشتر میکنه و بهش کار با بانک رو هم اضافه میکنه . مخصوصا اگر قرار باشه جستجو یا فیلترینگ انجام بدید حجم کد درون کنترلر زیاد میشه.
بعد بعضی ها با استفاده از Code Refactor متهدهای Private درون کنترلر میسازند که کار ارتباط با بانک و جستجو و ... رو انجام میده ، بعدا متوجه میشوند بهتره متدهای کار با بانک رو به یک کلاس دیگه منتقل کنند و اسمشو بزارن Repository

در یک پروژه از ابتدا با Repository کار کردیم یعنی کدهای ارتباط با بانک در یک پروژه ی مجزا با بانام Repository ساختیم. بعدا وقتی لازم شد یک بخش از کار رو با Winform هم پشتیبانی کنیم کار ما خیلی ساده بود. فقط کافی بود یک Reference به پروژه ی Repository بزنیم و همه چیز آماده بود. این درست زمانی بود که متوجه شدیم که بهتره از Service هم استفاده کنیم و ارتباط بین کنترلر ها از طریق یک لایه ی دیگر به نام Service با Repository برقرار بشه و نه مستقیما و بعد برای کار بهتر از IoC و Dependency Injection استفاده کردیم و Ninject رو هم پیاده کردیم و این مدلی هست که در تمام پروژه های بعدی استفاده می کنیم.

مسئله اینه که استفاده از Repository بدون Service معنی نمیده ، مثل یک توپ کم باده ، میشه قلش داد اما شوتش کنید معلوم نیست کجا میره و جای دوری هم نمیتونه بره ! و بعد وقتی Service ها رو هم اضافه می کنید (منظورم WCF Service نیست) متوجه میشوید که حالا کلی کلاس دارید که برای استفاده از آنها باید مدام از new استفاده کنید و اینجاست که از Invertion Of control Container به داد شما میرسه و ابزاری مثل Unity و Ninject رو پیاده می کنید که کار ساختن کلاس ها رو انجام میدهند .

اگر بخواهید از این مدل استفاده کنید باید همه ی راه رو بروید و حجم کد زیادی بنویسید در ضمن اینکه دیگر باید همه ی کلاسها را از طریق یک اینترفیس تعریف کنید . چون همه ی IoC Container ها با اینترفیس کار می کنند. ولی اگر یکبار با این روش کار کنید دیگر نمیتوانید از آن دست بکشید

مهدی هادیان2
پنج شنبه 16 آبان 1392, 10:02 صبح
بسم الله الرحمن الرحیم

این کار حجم کد نویسی رو بالا میبره اما بدون شک در پروژه های بزرگ ارزش خودشو داره. اگر از Repository استفاده نکنید دستورات برقراری ارتباط با بانک رو کجا باید قرار بدید !؟

در کنترلر یا WebAPI نوشتن دستورات برقراری ارتباط با بانک کار اصلی کنترلر هارو که آماده سازی و انتخاب ویو مناسب هست رو بیشتر میکنه و بهش کار با بانک رو هم اضافه میکنه . مخصوصا اگر قرار باشه جستجو یا فیلترینگ انجام بدید حجم کد درون کنترلر زیاد میشه.
بعد بعضی ها با استفاده از Code Refactor متهدهای Private درون کنترلر میسازند که کار ارتباط با بانک و جستجو و ... رو انجام میده ، بعدا متوجه میشوند بهتره متدهای کار با بانک رو به یک کلاس دیگه منتقل کنند و اسمشو بزارن Repository

در یک پروژه از ابتدا با Repository کار کردیم یعنی کدهای ارتباط با بانک در یک پروژه ی مجزا با بانام Repository ساختیم. بعدا وقتی لازم شد یک بخش از کار رو با Winform هم پشتیبانی کنیم کار ما خیلی ساده بود. فقط کافی بود یک Reference به پروژه ی Repository بزنیم و همه چیز آماده بود. این درست زمانی بود که متوجه شدیم که بهتره از Service هم استفاده کنیم و ارتباط بین کنترلر ها از طریق یک لایه ی دیگر به نام Service با Repository برقرار بشه و نه مستقیما و بعد برای کار بهتر از IoC و Dependency Injection استفاده کردیم و Ninject رو هم پیاده کردیم و این مدلی هست که در تمام پروژه های بعدی استفاده می کنیم.

مسئله اینه که استفاده از Repository بدون Service معنی نمیده ، مثل یک توپ کم باده ، میشه قلش داد اما شوتش کنید معلوم نیست کجا میره و جای دوری هم نمیتونه بره ! و بعد وقتی Service ها رو هم اضافه می کنید (منظورم WCF Service نیست) متوجه میشوید که حالا کلی کلاس دارید که برای استفاده از آنها باید مدام از new استفاده کنید و اینجاست که از Invertion Of control Container به داد شما میرسه و ابزاری مثل Unity و Ninject رو پیاده می کنید که کار ساختن کلاس ها رو انجام میدهند .

اگر بخواهید از این مدل استفاده کنید باید همه ی راه رو بروید و حجم کد زیادی بنویسید در ضمن اینکه دیگر باید همه ی کلاسها را از طریق یک اینترفیس تعریف کنید . چون همه ی IoC Container ها با اینترفیس کار می کنند. ولی اگر یکبار با این روش کار کنید دیگر نمیتوانید از آن دست بکشید
با سلام
با اجازه شما سوالم رو دوباره مطرح میکنم.
مایکروسافت سوئیچ Ropository رو در MVC Scaffolding جای داده؛ به نوعی استفاده از این الگو رو تائید کرده از طرفی آقای نصیری در سایتشون مخالف جدی این الگو با ذکر ادله بودند و به جاش استفاده از الگوی Unit Of Work رو توصیه کرده بودند. خوب میدونید پیاده سازی ایندو چقدر باهم فرق دارند.
ما حرف مایکروسافت رو بد فهمیدیم یا.....؟
با سپاس

amir-yeketaz
پنج شنبه 16 آبان 1392, 10:30 صبح
بسم الله الرحمن الرحیم

با سلام
با اجازه شما سوالم رو دوباره مطرح میکنم.
مایکروسافت سوئیچ Ropository رو در MVC Scaffolding جای داده؛ به نوعی استفاده از این الگو رو تائید کرده از طرفی آقای نصیری در سایتشون مخالف جدی این الگو با ذکر ادله بودند و به جاش استفاده از الگوی Unit Of Work رو توصیه کرده بودند. خوب میدونید پیاده سازی ایندو چقدر باهم فرق دارند.
ما حرف مایکروسافت رو بد فهمیدیم یا.....؟
با سپاس

دوست عزیز بحث آقای نصیری مخالفت با کلیت کار (که حکیم22 توضیح دادند) نیست و نبوده است! ... چیزی که مهمه نحوه ی پیاده سازی هست و پیاده سازی های بسیار زیادی وجود داره

hakim22
پنج شنبه 16 آبان 1392, 10:45 صبح
استفاده از Repository Pattern یعنی تغییرات در بانک اطلاعاتی مستقیما اعمال نشه و این کار توسط یک واسط انجام بشه . در حقیقت کنترلر در پروژه ی MVC نباید هیچ درکی از اینکه اطلاعات به چه روشی از بانک اطلاعاتی خوانده میشوند داشته باشد. به عبارت دیگر کنترلر هیچ Reference به Entity framework و سایر ابزار ADO نداشته باشد. در عوض به پروژه ی دیگری که وصل باشد که شامل کلاسها و دستوراتی است که اطلاعات را به بانک وصل می کنند و کار تغییر داده های درون SQL Server را به عهده دارند.

منظور از Unit Of Work این است که دفعات برقراری ارتباط با لایه ی Repository تحت کنترل ما باشد . مثلا شما 20 کاربر به سایت اضافه می کنید ولی یکبار عملیات ذخیره سازی را انجام میدهید. در طول این مدت اطلاعات کاربران در حافظه ی موقت نگه داشته شده است و بعدا که SaveChanges را اعمال می کنید همه ی آنها با هم ذخیره میشوند. حتما این مسئله به بازدهی بیشتر کمک میکند. استفاده از EF این مشکل را برطرف کرده است و شما میتوانید به هر تعداد رکورد به جدولهای اضافه کنید و بعد با استفاده از SaveChanges همه را یکجا ذخیره کنید.

مسئله این است که پیاده سازی Repository دست ما را از EF کوتاه می کند و باید در این میان متدهایی نوشت که با لیست و IQuerable کار کنند در غیر این صورت این قابلیت EF محو میشود.

مهدی هادیان2
پنج شنبه 16 آبان 1392, 10:48 صبح
بسم الله الرحمن الرحیم

دوست عزیز بحث آقای نصیری مخالفت با کلیت کار (که حکیم22 توضیح دادند) نیست و نبوده است! ... چیزی که مهمه نحوه ی پیاده سازی هست و پیاده سازی های بسیار زیادی وجود داره
لطفا http://www.dotnettips.info/post/842/ef-code-first-12 رو مطالعه بفرمائید.
با سپاس

amir-yeketaz
پنج شنبه 16 آبان 1392, 10:56 صبح
شما بهتره پست قبلیشونو بخونین http://www.dotnettips.info/post/841/ef-code-first-11

بنده خودم از پیاده سازی ایشون در حالت generic استفاده میکنم .
ایشون از پیاده سازی های اشتباه گلایه دارن و به همین خاطر اسم پیاده سازیشونو repository نذاشتن و بهش میگن service تا بهتر مفهوم رو برسونه

hakim22
پنج شنبه 16 آبان 1392, 10:58 صبح
به این مقاله مراجعه کنید :

http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

مبینید که در دیاگرام ها الگوی Repository درون مفهوم Unit Of Work قرار گرفته است. برداشت من این است که الگوی Repository باید مفهوم Unit Of Work را هنگام پیاده سازی درنظر بگیرند.
همانطور که در عنوان مقاله میبینید این دو الگو در تناقض با هم نیستند بلکه یکدیگر را کامل میکنند. این دو الگو قابل مقایسه با هم نیستند چون کارها و اهداف متفاوتی را پوشش میدهند.

hakim22
پنج شنبه 16 آبان 1392, 11:10 صبح
در ضمن من منظور از قابل انتقال نبودن لایه ی Repository رو نمیفهمم :



توضیحات:
همانطور که ملاحظه می‌کنید در هیچکدام از کلاس‌های سرویس برنامه، وهله سازی مستقیمی از الگوی واحد کار وجود ندارد. این لایه از برنامه اصلا نمی‌داند که کلاسی به نام Sample07Context وجود خارجی دارد یا خیر.
همچنین لایه اضافی دیگری را به نام Repository جهت مخفی سازی سازوکار EF به برنامه اضافه نکرده‌ایم. این لایه شاید در نگاه اول برنامه را مستقل از ORM جلوه دهد اما در عمل قابل انتقال نیست و سبب تحمیل سربار اضافی بی موردی به برنامه می‌شود؛ ORMها ویژگی‌های یکسانی را ارائه نمی‌دهند. حتی در حالت استفاده از LINQ، پیاده سازی‌های یکسانی را به همراه ندارند.


استفاده از یک پروژه مجزا برای کار با بانک اطلاعاتی و یک پروژهی مجزا که اطلاعات رو پردازش کنه به نام service یکی از بهترین روشهای پیاده سازی پروژه های ASP.MVC هست و به عنوان Best practices شناخته میشود. مخصوصا وقتی چند تیم با تخصص های مختلف رو یک پروژه کار میکنند هرچه برنامه به اجزا کوچکتر تقسیم شود بهتر است.
در ضمن رابطه ی یک به یک بین جداول بانک اطلاعاتی با کلاسهای Repository وجود ندارد. همینطور هم رابطه ی یک به یک بین Repository و Service ها وجود ندارد و به همین ترتیب رابطه ی یک به یک بین Service ها و کنترلها وجود ندارد.

بهترین حالتی که به نظر من وجود داره اینه که یک پروژه به نام Repostory کارهای بانک رو انجام بده و یک پروژه به نام Service اطلاعات رو از Repository ها جمع آوری کنه ViewModel هارو برای کنترلر آماده کنه و بعد یک کنترلر با استفاده از سرویس ها اطلاعات رو به ویو بفرسته. و همین جهت به صورت عکس .

حداقل این مدلی هست که Ninject برای پیاده سازی Invertion Of control توصیه میکنه .و بدون استفاده از ابزارهایی مثل Ninject و Unity جدا سازی اجزا به چند پروژه تبدیل به یک کابوس میشه و همانطور که قبلا توضیح دادم تمام وقت کار شما تبدیل میشه به ساختن نمونه از کلاسهای درون Repository و Service

ali_kolahdoozan
پنج شنبه 16 آبان 1392, 13:09 عصر
من مقاله یا هر چیز دیگری از آقای نصیری نخوانده ام ، اما در کل شما Microsoft رو بگیر و برو جلو ، مگر اینکه مورد شما خیلی خاصی باشه . مثلا از شما خواسته بشه برای Design Pattern یک ERP ، نظر بدید که خوب شاید داستان فرق کنه . برای سایتهای معمول و.... ، نگران نباشید !.

amir-yeketaz
پنج شنبه 16 آبان 1392, 13:54 عصر
من مقاله یا هر چیز دیگری از آقای نصیری نخوانده ام ، اما در کل شما Microsoft رو بگیر و برو جلو ، مگر اینکه مورد شما خیلی خاصی باشه . مثلا از شما خواسته بشه برای Design Pattern یک ERP ، نظر بدید که خوب شاید داستان فرق کنه . برای سایتهای معمول و.... ، نگران نباشید !.

مایکروسافتو بگیر و برو جلو؟!!! ...(این حرف خیلی ساده لوحانه است!)

آقای نصیری حرف تیم EF رو ملاک قرار دادن (تیم EF مهمه چی بگه نه مایکروسافت!!! ) و اگر اون پستی که من لینکشو دادم بخونین متوجه میشین که حرف آقای نصیری چی هست!

ali_kolahdoozan
پنج شنبه 16 آبان 1392, 13:59 عصر
مایکروسافتو بگیر و برو جلو؟!!! ...(این حرف خیلی ساده لوحانه است!)

آقای نصیری حرف تیم EF رو ملاک قرار دادن (تیم EF مهمه چی بگه نه مایکروسافت!!! ) و اگر اون پستی که من لینکشو دادم بخونین متوجه میشین که حرف آقای نصیری چی هست!


دیگه هر طور که راحتید !.

Amir Oveisi
پنج شنبه 16 آبان 1392, 14:20 عصر
به نظر من هم تنها استفاده از لایه Service کافی هست و دلیلی وجود نداره که وقتی خود DbContext به عنوان Repository قابل استفاده هست دوباره بیایم و Repository ایجاد کنیم.
در اکثر مواردی که دیدم کسانی که هم از Repository و هم از Service استفاده کردند در واقع دارن یک کار رو در دو لایه تکرار میکنند! بعضی ها دقیقا دارن مثل هم کار میکنند ولی یکی اسم Repository میزاره روش یکی دیگه اسم Service!
در حالیکه اصلا قواعد Service یا Repository رو رعایت نکردند تو پیاده سازی هاشون.
استفاده از Repository در یک حالت به نظر من قابل توجیه هست که شما plan ای برای سویچ شدن پی در پی میان Data Source های مختلف و تکنیک های ذخیره سازی داده متفاوت داشته باشید. مثلا ممکنه در زمان اجرا نیاز داشته باشید که کلا با یک File System کار کنید و یا تکنیک های دیگر... .
البته حتی در اینصورت هم میشه فقط با استفاده از لایه Service این کار ها رو انجام داد و الزاما نیازی به وجود Repository نخواهد بود.

مهدی هادیان2
پنج شنبه 16 آبان 1392, 14:21 عصر
بسم الله الرحمن الرحیم
با سلام
دوستان به هر حال باید پذیرفت که سوئیچ -Repository پاسخگوی کامل نیاز ما در پروژه ها نیست.
چه جوری میشه قالب این رو تغییر داد تا بر اساس الگوی Unit Of Work تنها یک Contex رو به اشتراک بذاریم؟
با سپاس

hakim22
پنج شنبه 16 آبان 1392, 15:38 عصر
میشه قالبهای T4 رو عوض کرد که باید به مسیر نصب VS بروید و به دنبال فایلهلی با پسوند tt. بگردید.یک فولدری با نام CodeTemplate هست که همه ی قالبها درونش ذخیره هستند.
ابزار T4 با زبان CS یا VB قابل کد نویسی است . ولی خیلی وقتها میشه اونها را در اینترنت هر پیدا کرد.

مهدی هادیان2
پنج شنبه 16 آبان 1392, 17:33 عصر
بسم الله الرحمن الرحیم

میشه قالبهای T4 رو عوض کرد که باید به مسیر نصب VS بروید و به دنبال فایلهلی با پسوند tt. بگردید.یک فولدری با نام CodeTemplate هست که همه ی قالبها درونش ذخیره هستند.
ابزار T4 با زبان CS یا VB قابل کد نویسی است . ولی خیلی وقتها میشه اونها را در اینترنت هر پیدا کرد.
با سلام
متاسفانه لینکی تو اینترنت پیدا نکردم.

Amir Oveisi
پنج شنبه 16 آبان 1392, 21:18 عصر
http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTempla tesInASPNETMVC.aspx

مهدی هادیان2
جمعه 17 آبان 1392, 22:57 عصر
بسم الله الرحمن الرحیم
با سلام
متاسفانه تسلط کافی ندارم بنابراین نتونستم قالب هایی که Scaffolding میسازه رو شخصی سازی کنم.
قصد داشتم مثل حالت واقعی یک dbContext داشته باشه و در لایه های مختلف به اشتراک بذاره و یک کلاس برای کارهای مشترک (حذف و درج و ...) و کلاس های Repository برای هر کدام.
کل قالب Scaffolding تغییر کرد.http://forum.p30world.com/images/New-Smile3/01.gifhttp://forum.p30world.com/images/New-Smile3/01.gif
به نظرتون روی این قالب ها کار کنم یا عطای Scaffolding رو به لقاش ببخشم؟
با سپاس

hakim22
شنبه 18 آبان 1392, 00:40 صبح
تغییر یا طراحی یک T4 برای کسی مناسب است که وقت آن را داشته باشد یا اینکه قرار است بسیار زیاد از آن استفاده کند. نتیجه ی کار به ندرت کامل است و نیاز به کد نویسی دستی همیشه وجود دارد.
منظور من بیشتر این بود که در اینترنت به دنبال Template های آماده بگردید یکی مناسب پیدا کنید ، یک عده ای وقت و انرژی زیادی قبلا در این زمینه صرف کرده اند !!!

http://geekswithblogs.net/danemorgridge/archive/2010/06/28/entity-framework-repository-amp-unit-of-work-t4-template-on.aspx

http://efrepository.codeplex.com/

http://visualstudiogallery.msdn.microsoft.com/43434f79-468c-487b-875f-73a8def607f3

مهدی هادیان2
یک شنبه 19 آبان 1392, 19:36 عصر
بسم الله الرحمن الرحیم
با سلام
متاسفانه قالب مناسبی که به درستی الگوها رو پیاده سازی کرده باشه؛ پیدا نکردم.

مهدی هادیان2
سه شنبه 21 آبان 1392, 13:32 عصر
بسم الله الرحمن الرحیم
با سلام
دوستان کسی هست که به صورت عملی در پروژه ها از قالب های آماده استفاده کند یا برای کنترلرها از صفر کد می زنید؟
فکر می کنم با پاسخ به این سوال این تاپیک ان شاالله به نتیجه برسد.
با سپاس فراوان

fatima_h66
سه شنبه 27 آبان 1393, 13:07 عصر
بسم الله الرحمن الرحیم
با سلام
دوستان کسی هست که به صورت عملی در پروژه ها از قالب های آماده استفاده کند یا برای کنترلرها از صفر کد می زنید؟
فکر می کنم با پاسخ به این سوال این تاپیک ان شاالله به نتیجه برسد.
با سپاس فراوان

برای پروره های کوچک اصلا لازمه از این کار استفاده کنیم؟
یا بذرایم روال مشخص خودش رو بره؟
من نمیدونم استفاده از قالب علی آماده درسته یانه؟
اگه هست یکی رو معرفی کنید که قالب مناسبی رو پیاده سازی کرده و توضیح درستی داده باشه.