Software Philosophy - Concurrency - 2018-10-02.mkv
203.5 MB
فیلم آموزش انلاین در سایت تویچ
موضوع : Parallel and Asynchronous Programming
ارائه : مهران داودی @mehrandvd
فلسفه نرم افزار https://news.1rj.ru/str/SoftwarePhilosophy
موضوع : Parallel and Asynchronous Programming
ارائه : مهران داودی @mehrandvd
فلسفه نرم افزار https://news.1rj.ru/str/SoftwarePhilosophy
#آیا_میدانستید
✅ آیا میدانستید حلقه for سریع تر از list.ForEach یا اصلاحا ForEach Lambda است؟
✅ آیا میدانستید حلقه list.ForEach سریع تر از foreach است؟ زیرا list.ForEach داخل خود از for استفاده میکند ولی foreach داخل خود از مکانسیم Enumerator Iteration که به مراتب سنگین تر است، استفاده میکند.
✅ آیا میدانستید حلقه for که مقدار count آن توسط یک متغیر خوانده شود سریع تر از حلقه for ایی است که مقدار count خود را از list.Count میخواند؟ زیرا سرعت خواندن متد get یک property زمانبر تر از خواندن مقدار یک متغیر است.
مثال :
در تست انجام شده، سرعت اجرای حلقه ها روی 100 میلیون آیتم به ترتیب زیر است
1- حلقه for که از متغیر count میخواند (زمان : 378 میلی ثانیه)
2- حلقه for که از خاصیت list.Count میخواند (زمان : 415 میلی ثانیه)
3- حلقه list.ForEach یا اصطلاحا ForEach Lambda (زمان : 650 میلی ثانیه)
4- حلقه foreach (زمان : 1136 میلی ثانیه)
همانطور که مشاهده میکنید تفاوت این ها آنقدر محسوس نیست که سرعت پروژه را کاهش دهد.
درنتیجه بهتر از کدی را بنویسید که «تمیز» تر است.
@IranAspMvc
✅ آیا میدانستید حلقه for سریع تر از list.ForEach یا اصلاحا ForEach Lambda است؟
✅ آیا میدانستید حلقه list.ForEach سریع تر از foreach است؟ زیرا list.ForEach داخل خود از for استفاده میکند ولی foreach داخل خود از مکانسیم Enumerator Iteration که به مراتب سنگین تر است، استفاده میکند.
✅ آیا میدانستید حلقه for که مقدار count آن توسط یک متغیر خوانده شود سریع تر از حلقه for ایی است که مقدار count خود را از list.Count میخواند؟ زیرا سرعت خواندن متد get یک property زمانبر تر از خواندن مقدار یک متغیر است.
مثال :
var count = list.Count;از روش زیر سریع تر است
for (int i = 0; i < count ; i++) { }
for (int i = 0; i < list.Count ; i++) { }
نتیجه :در تست انجام شده، سرعت اجرای حلقه ها روی 100 میلیون آیتم به ترتیب زیر است
1- حلقه for که از متغیر count میخواند (زمان : 378 میلی ثانیه)
2- حلقه for که از خاصیت list.Count میخواند (زمان : 415 میلی ثانیه)
3- حلقه list.ForEach یا اصطلاحا ForEach Lambda (زمان : 650 میلی ثانیه)
4- حلقه foreach (زمان : 1136 میلی ثانیه)
همانطور که مشاهده میکنید تفاوت این ها آنقدر محسوس نیست که سرعت پروژه را کاهش دهد.
درنتیجه بهتر از کدی را بنویسید که «تمیز» تر است.
@IranAspMvc
Forwarded from جادی، کیبورد آزاد - Jadi
ظاهرا مایکروسافت بزرگترین شرکت اوپن سورس جهان شده؛ با آزاد کردن ۶۰هزار پتنتش
https://jadi.net/2018/10/microsoft-joined-oin/
لینوس توروالدز خالق لینوکس یکبار گفته بود که اگر روزی مایکروسافت برای لینوکس برنامه بنویسه، اون پیروز شده. حالا نه فقط مایکروسافت ادیتوری مثل vscode رو در دنیای لینوکس هم منتشر کرده و نه فقط اجازه می ده فضای لینوکسی به سیستم عامل خودش راه پیدا کنه، که این هفته اعلام کرد که عضو شبکه اختراع آزاد شده (OIN یا هر ترجمه دقیق دیگه ای که داره). این کنسرسیوم کارش اینه که پتنتهای آزاد هر شرکت رو در اختیار بقیه شرکتها بذاره در مقابل اینکه پتنتهای بقیه شرکتها هم برای این شرکتها آزاد بشه.
شبکه Open Invention Network حدود ۲۶۵۰ عضو که توشن اسمهایی مثل گوگل، آی بی ام، ردهت و سوزه به چشم میخورن. مدیر عامل این شبکه اعلام کرده که «مایکروسافت هر چیزی که داره رو آورده. چه تکنولوژی قدیمیترش مثل اندروید و کرنل لینوکس و اوپن استک و چه تکنولوژیهای جدیدترش مثل LF Energy و هایپرلجر و همه قبلیها و بعدیهاشون».
تعداد پتنتهایی که مایکروسافت آورده حدود ۶۰هزار تا است و خوبه یادمون باشه که درآمد مایکروسافت فقط از پتنتهای اندروید حدود ۳.۴ میلیارد دلار در سال ۲۰۱۴ بوده. معلومه که همه شک شدن. مایکروسافت مدعی است که دچار یک تغییر فلسفی بنیادی شده و از جایی که با جامعه آزاد دوست نبوده در حرکت به سمت اون است و با این کار نشون داده که این حرکت جدی و مصممه. مدیر اجرایی مایکروسافت میگه که دنبال بهتر کردن وضعیت توسعه دهندهها است و کاری نداره که اونها رو لینوکس کار می کنن یا ویندوز و از دات نت استفاده می کنن یا جاوا.
این تغییر مدتی طولانی است که در شرکت مایکروسافت دیده می شه و دلیلش هم به احتمال زیاد درک این مساله است که دنیای آینده دنیای باز است. جایی که واقعا ایده ها رقابت می کنن و کسانی که در دنیای باز باشن، دسترسی بیشتری به ایدههای متنوع و همچنین دسترسی بیشتری به خلاقیت خواهند داشت. اتفاق بسیار بزرگیه و من هم هنوز بهش شک دارم؛ هی فکر میکنم شاید جایی از خبر رو نفهمیدم یا نکته پنهانی داره که من نمی دونم. اما به هرحال به نظر می رسه مایکروسافت بیشتر از ۶۰هزار پتنتش رو از این به بعد برای دنیای آزاد، رایگان کرده.
https://jadi.net/2018/10/microsoft-joined-oin/
لینوس توروالدز خالق لینوکس یکبار گفته بود که اگر روزی مایکروسافت برای لینوکس برنامه بنویسه، اون پیروز شده. حالا نه فقط مایکروسافت ادیتوری مثل vscode رو در دنیای لینوکس هم منتشر کرده و نه فقط اجازه می ده فضای لینوکسی به سیستم عامل خودش راه پیدا کنه، که این هفته اعلام کرد که عضو شبکه اختراع آزاد شده (OIN یا هر ترجمه دقیق دیگه ای که داره). این کنسرسیوم کارش اینه که پتنتهای آزاد هر شرکت رو در اختیار بقیه شرکتها بذاره در مقابل اینکه پتنتهای بقیه شرکتها هم برای این شرکتها آزاد بشه.
شبکه Open Invention Network حدود ۲۶۵۰ عضو که توشن اسمهایی مثل گوگل، آی بی ام، ردهت و سوزه به چشم میخورن. مدیر عامل این شبکه اعلام کرده که «مایکروسافت هر چیزی که داره رو آورده. چه تکنولوژی قدیمیترش مثل اندروید و کرنل لینوکس و اوپن استک و چه تکنولوژیهای جدیدترش مثل LF Energy و هایپرلجر و همه قبلیها و بعدیهاشون».
تعداد پتنتهایی که مایکروسافت آورده حدود ۶۰هزار تا است و خوبه یادمون باشه که درآمد مایکروسافت فقط از پتنتهای اندروید حدود ۳.۴ میلیارد دلار در سال ۲۰۱۴ بوده. معلومه که همه شک شدن. مایکروسافت مدعی است که دچار یک تغییر فلسفی بنیادی شده و از جایی که با جامعه آزاد دوست نبوده در حرکت به سمت اون است و با این کار نشون داده که این حرکت جدی و مصممه. مدیر اجرایی مایکروسافت میگه که دنبال بهتر کردن وضعیت توسعه دهندهها است و کاری نداره که اونها رو لینوکس کار می کنن یا ویندوز و از دات نت استفاده می کنن یا جاوا.
این تغییر مدتی طولانی است که در شرکت مایکروسافت دیده می شه و دلیلش هم به احتمال زیاد درک این مساله است که دنیای آینده دنیای باز است. جایی که واقعا ایده ها رقابت می کنن و کسانی که در دنیای باز باشن، دسترسی بیشتری به ایدههای متنوع و همچنین دسترسی بیشتری به خلاقیت خواهند داشت. اتفاق بسیار بزرگیه و من هم هنوز بهش شک دارم؛ هی فکر میکنم شاید جایی از خبر رو نفهمیدم یا نکته پنهانی داره که من نمی دونم. اما به هرحال به نظر می رسه مایکروسافت بیشتر از ۶۰هزار پتنتش رو از این به بعد برای دنیای آزاد، رایگان کرده.
جادی دات نت | کیبرد آزاد
ظاهرا مایکروسافت بزرگترین شرکت اوپن سورس جهان شده؛ با آزاد کردن ۶۰هزار پتنتش
لینوس توروالدز خالق لینوکس یکبار گفته بود که اگر روزی مایکروسافت برای لینوکس برنامه بنویسه، اون پیروز شده. حالا نه فقط مایکروسافت ادیتوری مثل vscode رو در دنیای لینوکس هم منتشر کرده و نه فقط اجازه می ده فضای لینوکسی به سیستم عامل خودش راه پیدا کنه، که این…
بنا بر درخواست بعضی از دوستان مبنی بر آموزش Asp Core تصمیم دارم یک دوره #تدریس نیمه خصوصی قیمت مناسب با موضوع
✅ «آموزش Asp Core مقدماتی تا پیشرفته»
برگزار کنم
🔹 کلاس در ۹ جلسه ۳ ساعته (مجموعا ۲۷ ساعت) در طول ۳ هفته برگزار خواهد شد (البته طول دوره، روز و ساعت برگزاری با توجه به تایم دانشجویان قابل تغییر خواهد بود)
🔸 پیش لازمه این اموزش، تسلط نسبی بر C#, SQL, HTML, CSS و JavaScript میباشد (جهت یکنواخت بودن سطح دانشجویان، از آنها تست و گزینش انجام خواهد شد)
🔹 در این آموزش وقت دانشجویان صرف موراد عمومی طراحی سایت مثل آموزش Bootstrap, jQuery, Angular و دیزاین نخواهد شد و تمرکز اصلی بر روی موضوعات تخصصی DotNetCore, AspCore, EF Cor است (این دوره یک آموزش همه جانبه نیست که نیمی از وقت دوره صرف موارد غیر تخصصی شود، درنتیجه برای کسانی که میخواهند در AspCore حرفه ای شوند و نه دانش سطحی بر روی موارد بیشتر پیدا کنند، مفید خواهد بود)
🔸 این از ابتدا پروژه محور و عملی خواهد بود و مباحث تئوری در لابلای موارد عملی تدریس خواهند شد
🔹در این دوره Best practice ها، نکات حاصل از تجربه عملی در پروژه های مختلف، کدنویسی اصولی و معماری استاندار پروژه تدریس خواهند شد
🔸 فیلم آموزش این دوره، ضبط و در اختیار دانشجویان قرار خواهد گرفت
🔹در پایان دوره، دانشجویان می توانند به مدت یک ماه از «پرسش و پاسخ کامل به همراه AnyDesk توسط مدرس» استفاده کنند
🔸ظرفیت دوره محدود (۵ نفر) بوده و از اوایل ماه آینده (آبان) شروع خواهند شد. ضمنا دوره حضوری بوده و در تهران برگذار خواهد شد
جهت رزرو و اطلاعات بیشتر میتوانید با بنده در ارتباط باشید
🔰@mj_ebrahimi
محمد جواد ابراهیمی
✅ «آموزش Asp Core مقدماتی تا پیشرفته»
برگزار کنم
🔹 کلاس در ۹ جلسه ۳ ساعته (مجموعا ۲۷ ساعت) در طول ۳ هفته برگزار خواهد شد (البته طول دوره، روز و ساعت برگزاری با توجه به تایم دانشجویان قابل تغییر خواهد بود)
🔸 پیش لازمه این اموزش، تسلط نسبی بر C#, SQL, HTML, CSS و JavaScript میباشد (جهت یکنواخت بودن سطح دانشجویان، از آنها تست و گزینش انجام خواهد شد)
🔹 در این آموزش وقت دانشجویان صرف موراد عمومی طراحی سایت مثل آموزش Bootstrap, jQuery, Angular و دیزاین نخواهد شد و تمرکز اصلی بر روی موضوعات تخصصی DotNetCore, AspCore, EF Cor است (این دوره یک آموزش همه جانبه نیست که نیمی از وقت دوره صرف موارد غیر تخصصی شود، درنتیجه برای کسانی که میخواهند در AspCore حرفه ای شوند و نه دانش سطحی بر روی موارد بیشتر پیدا کنند، مفید خواهد بود)
🔸 این از ابتدا پروژه محور و عملی خواهد بود و مباحث تئوری در لابلای موارد عملی تدریس خواهند شد
🔹در این دوره Best practice ها، نکات حاصل از تجربه عملی در پروژه های مختلف، کدنویسی اصولی و معماری استاندار پروژه تدریس خواهند شد
🔸 فیلم آموزش این دوره، ضبط و در اختیار دانشجویان قرار خواهد گرفت
🔹در پایان دوره، دانشجویان می توانند به مدت یک ماه از «پرسش و پاسخ کامل به همراه AnyDesk توسط مدرس» استفاده کنند
🔸ظرفیت دوره محدود (۵ نفر) بوده و از اوایل ماه آینده (آبان) شروع خواهند شد. ضمنا دوره حضوری بوده و در تهران برگذار خواهد شد
جهت رزرو و اطلاعات بیشتر میتوانید با بنده در ارتباط باشید
🔰@mj_ebrahimi
محمد جواد ابراهیمی
DotNetZoom pinned «بنا بر درخواست بعضی از دوستان مبنی بر آموزش Asp Core تصمیم دارم یک دوره #تدریس نیمه خصوصی قیمت مناسب با موضوع ✅ «آموزش Asp Core مقدماتی تا پیشرفته» برگزار کنم 🔹 کلاس در ۹ جلسه ۳ ساعته (مجموعا ۲۷ ساعت) در طول ۳ هفته برگزار خواهد شد (البته طول دوره، روز و…»
DotNetZoom
بنا بر درخواست بعضی از دوستان مبنی بر آموزش Asp Core تصمیم دارم یک دوره #تدریس نیمه خصوصی قیمت مناسب با موضوع ✅ «آموزش Asp Core مقدماتی تا پیشرفته» برگزار کنم 🔹 کلاس در ۹ جلسه ۳ ساعته (مجموعا ۲۷ ساعت) در طول ۳ هفته برگزار خواهد شد (البته طول دوره، روز و…
لیست سرفصل های دوره.pdf
358.9 KB
لیست سرفصل هایی که در این دوره تدریس خواهند شد
@IranAspMvc
@IranAspMvc
#Announcement #Released
نسخه Preview 3 منتشر شد
شامل :
✅ .NET Core 2.2 Preview 3 (Runtime)
✅ .NET Core SDK 2.2.100 Preview 3 (SDK)
✅ Asp .Net Core 2.2 Preview 3
✅ Entity Framework Core 2.2 Preview 3
🔰 توضیحات بیشتر :
https://github.com/dotnet/core/blob/master/release-notes/2.2/preview/2.2.0-preview3.md
🔰 امکانات جدید و بهبود های 2.2 Preview 3 AspCore
https://blogs.msdn.microsoft.com/webdev/2018/10/17/asp-net-core-2-2-0-preview3-now-available/
🔰 امکانات جدید و بهبود های EF Core 2.2 Preview 3
https://blogs.msdn.microsoft.com/dotnet/2018/10/17/announcing-entity-framework-core-2-2-preview-3/
لینک دانلود NET Core (SDK) 2.2.100 Preview 3 :
64x : https://bit.ly/2yrInB7
86x : https://bit.ly/2yYmIQP
نسخه SDK شامل NET Core , ASP .NET Core runtime می باشد و نیاز به نصب جداگانه آنها نمی باشد.
جهت استفاده از این نسخه باید Visual Studio 15.9 Preview 3 به بالا داشته باشید که می توانید توسط Visual Stuido Installer آن را اپدیت کنید
_______________
@IranAspMvc
نسخه Preview 3 منتشر شد
شامل :
✅ .NET Core 2.2 Preview 3 (Runtime)
✅ .NET Core SDK 2.2.100 Preview 3 (SDK)
✅ Asp .Net Core 2.2 Preview 3
✅ Entity Framework Core 2.2 Preview 3
🔰 توضیحات بیشتر :
https://github.com/dotnet/core/blob/master/release-notes/2.2/preview/2.2.0-preview3.md
🔰 امکانات جدید و بهبود های 2.2 Preview 3 AspCore
https://blogs.msdn.microsoft.com/webdev/2018/10/17/asp-net-core-2-2-0-preview3-now-available/
🔰 امکانات جدید و بهبود های EF Core 2.2 Preview 3
https://blogs.msdn.microsoft.com/dotnet/2018/10/17/announcing-entity-framework-core-2-2-preview-3/
لینک دانلود NET Core (SDK) 2.2.100 Preview 3 :
64x : https://bit.ly/2yrInB7
86x : https://bit.ly/2yYmIQP
نسخه SDK شامل NET Core , ASP .NET Core runtime می باشد و نیاز به نصب جداگانه آنها نمی باشد.
جهت استفاده از این نسخه باید Visual Studio 15.9 Preview 3 به بالا داشته باشید که می توانید توسط Visual Stuido Installer آن را اپدیت کنید
_______________
@IranAspMvc
#Issues
و اما لیست Issue های و مشکلات AspNet Core , EF Core 2.2 Preview 3 در لینک زیر قابل مشاهده است
❌ https://github.com/aspnet/Announcements/issues/323
از مهم ترین Issue های کشف شده تاکنون می توان به مورد زیر اشاره کرد :
⭕️ وقتی یک پروژه MVC یا Razor Pages جدید ایجاد کنید فایل استایل bootstrap.min.css در سمت کلاینت رندر نمی شود، در صورتی که در فایل Layout وجود دارد!
دلیل این مشکل، نقص در integrity check این فایل است و با افزودن خاصیت
⭕️ و یا استثنای NullReferenceException به هنگام کار با IHttpClientFactory که با تنظیم کردن خاصیت زیر قابل حل می باشد.
اگر با آخرین ورژن (که درحال حاضر Previwe 3 نسخه 2.2 است) مشکل پیدا کردید، (مثل همین موارد بالا) می توانید با افزودن فایل global.json به سلوشن خود، ورژن SDK پروژه خود را تغییر دهید مانند زیر
توضیحات بیشتر :
https://docs.microsoft.com/en-us/dotnet/core/tools/global-json
___________
@IranAspMvc
و اما لیست Issue های و مشکلات AspNet Core , EF Core 2.2 Preview 3 در لینک زیر قابل مشاهده است
❌ https://github.com/aspnet/Announcements/issues/323
از مهم ترین Issue های کشف شده تاکنون می توان به مورد زیر اشاره کرد :
⭕️ وقتی یک پروژه MVC یا Razor Pages جدید ایجاد کنید فایل استایل bootstrap.min.css در سمت کلاینت رندر نمی شود، در صورتی که در فایل Layout وجود دارد!
دلیل این مشکل، نقص در integrity check این فایل است و با افزودن خاصیت
crossorigin="anonymous"
به تگ <link> این CSS، برطرف خواهد شد.⭕️ و یا استثنای NullReferenceException به هنگام کار با IHttpClientFactory که با تنظیم کردن خاصیت زیر قابل حل می باشد.
HttpClientFactoryOptions.HandlerLifetime = Timeout.InfiniteTimespan;
🔰 با نصب نسخه SDK جدید، نسخه پیش فرضی که پروژه شما بر روی آن اجرا می شود، آخرین ورژن خواهد بوداگر با آخرین ورژن (که درحال حاضر Previwe 3 نسخه 2.2 است) مشکل پیدا کردید، (مثل همین موارد بالا) می توانید با افزودن فایل global.json به سلوشن خود، ورژن SDK پروژه خود را تغییر دهید مانند زیر
{
"sdk": {
"version": "2.1.300"
}
}
توضیحات بیشتر :
https://docs.microsoft.com/en-us/dotnet/core/tools/global-json
___________
@IranAspMvc
#Api_Documention
معرفی #بهترین ابزار های #مستند_سازی و تست Api
https://bit.ly/api-documention
_______________
@IranAspMvc
معرفی #بهترین ابزار های #مستند_سازی و تست Api
https://bit.ly/api-documention
_______________
@IranAspMvc
به سلامتی #RedHat هم رفت خونه بخت!
شرکت IBM شرکت Red Hat را 34 میلیارد دلار خرید.
https://read.bi/2zdaZh8
___________
@IranAspMvc
شرکت IBM شرکت Red Hat را 34 میلیارد دلار خرید.
https://read.bi/2zdaZh8
___________
@IranAspMvc
#News #NetCore3
ماکروسافت اعلام کرد ASP NET Core 3.0 دیگر از Net Framework Full پشتیبانی نخواهد کرد
http://bit.ly/2zgCiqR
___________
@IranAspMvc
ماکروسافت اعلام کرد ASP NET Core 3.0 دیگر از Net Framework Full پشتیبانی نخواهد کرد
http://bit.ly/2zgCiqR
___________
@IranAspMvc
یکی از امکانات Angular 7، ویژگی Virtual Scrolling میباشد. در صورتیکه شما قصد داشته باشید یک لیست بزرگ از المنتها (مثلا 1000 آیتم) را بارگذاری کنید، اینکار میتواند بر روی کارآیی برنامهی شما تاثیر بگذارد .
می تواند برای بارگذاری تنها بخشهای قابل مشاهده از یک لیست (مثلا 10 آیتم)، بر روی صفحه نمایش استفاده شود و همچنین تنها آیتمهایی Render خواهند شد که میتواند آنها را در صفحه نمایش جا دهد. اگر لیست بارگذاری شده را اسکرول کنیم، در این حالت المنتها در DOM به صورت پویا load و unload میشوند.
آموزش Virtual Scrolling در Angular 7 :
https://www.dotnettips.info/post/2939
لینک Demo :
https://stackblitz.com/edit/angular-jnjms3
___________
@IranAspMvc
می تواند برای بارگذاری تنها بخشهای قابل مشاهده از یک لیست (مثلا 10 آیتم)، بر روی صفحه نمایش استفاده شود و همچنین تنها آیتمهایی Render خواهند شد که میتواند آنها را در صفحه نمایش جا دهد. اگر لیست بارگذاری شده را اسکرول کنیم، در این حالت المنتها در DOM به صورت پویا load و unload میشوند.
آموزش Virtual Scrolling در Angular 7 :
https://www.dotnettips.info/post/2939
لینک Demo :
https://stackblitz.com/edit/angular-jnjms3
___________
@IranAspMvc
http://bit.ly/2PEJSpr
بررسی و Navigate کردن بین کد های داخل Github مثل همیشه یک دردسر بوده و به راحتی امکان پذیر نیست، چرا که مانند یک IDE، رفرنس بین کدها مشخص نیست یا مثلا گزینه ای مانند Go to Definition وجود ندارد که بتوان محل تعریف یک متد را که در جایی درگیر استفاده شده است، یافت؛ به همین منوال برای یافتن کلاس هایی که یک Interface را Implement کرده اند و یا پیدا کردن کد های کلاسی که کلاس جاری از آن ارث بری کرده است
در این موارد تنها راه چاره، سرچ کردن نام متد یا کلاس درریپازیتوری Github است و سپس روبرو شدن با حجم انبوهی از کد ها که متن جستجو شده در آنها به کار رفته به مانند پیدا کردن "سوزن در گاه دون" است
افزونه Sourcegraph ابزاریست که قابلیت intelligence را به کد های Github شما میدهد و توسط آن میتوانید 3 عمل زیر را به راحتی انجام دهید
1- Go to Definition : یافتن کد تعریف کد مربوطه
2- Find References : یافتن تمام صفحاتی که کد مربوطه در آنجا استفاده شده است
3- Find Implementations : یافتن تمام پیاده سازی های کد(مثلا interface) مربوطه
* این افزونه از زبان های مختلفی مانند JavaScript, TypeScript, Python, Java, Go, ... پشتیبانی میکند ولی متاسفانه از زبان C# پشتیبانی نکرده و در مورد ریپازیتوری های C# کمکی به ما نمیکند
لینک دانلود افزونه Chrome:
https://chrome.google.com/webstore/detail/sourcegraph/dgjhfomjieaadpoljlnidmbgkdffpack
_______________
@IranAspMvc
بررسی و Navigate کردن بین کد های داخل Github مثل همیشه یک دردسر بوده و به راحتی امکان پذیر نیست، چرا که مانند یک IDE، رفرنس بین کدها مشخص نیست یا مثلا گزینه ای مانند Go to Definition وجود ندارد که بتوان محل تعریف یک متد را که در جایی درگیر استفاده شده است، یافت؛ به همین منوال برای یافتن کلاس هایی که یک Interface را Implement کرده اند و یا پیدا کردن کد های کلاسی که کلاس جاری از آن ارث بری کرده است
در این موارد تنها راه چاره، سرچ کردن نام متد یا کلاس درریپازیتوری Github است و سپس روبرو شدن با حجم انبوهی از کد ها که متن جستجو شده در آنها به کار رفته به مانند پیدا کردن "سوزن در گاه دون" است
افزونه Sourcegraph ابزاریست که قابلیت intelligence را به کد های Github شما میدهد و توسط آن میتوانید 3 عمل زیر را به راحتی انجام دهید
1- Go to Definition : یافتن کد تعریف کد مربوطه
2- Find References : یافتن تمام صفحاتی که کد مربوطه در آنجا استفاده شده است
3- Find Implementations : یافتن تمام پیاده سازی های کد(مثلا interface) مربوطه
* این افزونه از زبان های مختلفی مانند JavaScript, TypeScript, Python, Java, Go, ... پشتیبانی میکند ولی متاسفانه از زبان C# پشتیبانی نکرده و در مورد ریپازیتوری های C# کمکی به ما نمیکند
لینک دانلود افزونه Chrome:
https://chrome.google.com/webstore/detail/sourcegraph/dgjhfomjieaadpoljlnidmbgkdffpack
_______________
@IranAspMvc
DotNetZoom
http://bit.ly/2PEJSpr بررسی و Navigate کردن بین کد های داخل Github مثل همیشه یک دردسر بوده و به راحتی امکان پذیر نیست، چرا که مانند یک IDE، رفرنس بین کدها مشخص نیست یا مثلا گزینه ای مانند Go to Definition وجود ندارد که بتوان محل تعریف یک متد را که در جایی…
در ادامه پست قبلی به معرفی ابزاری برای Navigate/Browse کردن بین کد های C# می پردازیم
ابزار SourceBrowser ابزارییست برای راحت سازی Navigate کردن بین کد های C# که یک Solution سی شارپی یا VB.Net ایی را میگیرد و فایل های استاتیک Html ایی تولید می کند که حاوی کد های سلوشن شماست و قابل Navigate کردن بین کد هاست
اگر هنوز متوجه طرز کار آن نشده اید بهتر است سایت های زیر را که خروجی و حاصل این ابزار است را مشاهده کنید :
1- https://referencesource.microsoft.com (.NET Framework source online)
2- http://source.roslyn.io (Roslyn source online)
3- https://source.dot.net (.NET Core source online)
4- https://aspnetsource.azurewebsites.net (unofficial ASP.NET Core 1.0 source)
این ابزار بیشتر برای کسانی مفید است که کتابخانه یا فریمورک سی شارپی دارند و قصد دارند سورس کد خود را جهت راحتی بیشتر در Browse کردن در اختیار عموم قرار دهند
لینک ریپازیتوری و توضیحات بیشتر :
https://github.com/KirillOsenkov/SourceBrowser
_______________
@IranAspMvc
ابزار SourceBrowser ابزارییست برای راحت سازی Navigate کردن بین کد های C# که یک Solution سی شارپی یا VB.Net ایی را میگیرد و فایل های استاتیک Html ایی تولید می کند که حاوی کد های سلوشن شماست و قابل Navigate کردن بین کد هاست
اگر هنوز متوجه طرز کار آن نشده اید بهتر است سایت های زیر را که خروجی و حاصل این ابزار است را مشاهده کنید :
1- https://referencesource.microsoft.com (.NET Framework source online)
2- http://source.roslyn.io (Roslyn source online)
3- https://source.dot.net (.NET Core source online)
4- https://aspnetsource.azurewebsites.net (unofficial ASP.NET Core 1.0 source)
این ابزار بیشتر برای کسانی مفید است که کتابخانه یا فریمورک سی شارپی دارند و قصد دارند سورس کد خود را جهت راحتی بیشتر در Browse کردن در اختیار عموم قرار دهند
لینک ریپازیتوری و توضیحات بیشتر :
https://github.com/KirillOsenkov/SourceBrowser
_______________
@IranAspMvc
GitHub
GitHub - KirillOsenkov/SourceBrowser: Source browser website generator that powers http://referencesource.microsoft.com and ht…
Source browser website generator that powers http://referencesource.microsoft.com and http://sourceroslyn.io - KirillOsenkov/SourceBrowser
الگوی Repository و Unit Of Work روی EF؛ خوب یا بد؟!
http://bit.ly/2D9Bk3k
🔰 الگوی Repository پیشنهاد می کنه لایه ی واسطی بین لایه بیزینس/منطق برنامه و لایه دسترسی به دیتابیس ایجاد بشه و کد های لازم برای انجام عملیات روی دیتابیس داخل اون نوشته بشه. این لایه نحوه دسترسی به پایگاه داده را از لایه های بالایی پنهان می کنه و لایه های بالایی برای اجرای دستورات و یا فراخوانی داده ها باید از طریق این لایه درخواست های خودشون رو مطرح کنند.
درنتیجه برای جداسازی و ایزوله کردن نحوه دسترسی به داده، اون ها رو داخل Repository می میگذارند و لایه های بالایی بدون درگیر شدن با جزئیات نحوه دسترسی به داده ها، فقط متد های ریپازیتوری رو فراخوانی می کنند
در این الگو برای هر یک از Domain Model (کلاس های معادل جداولمون) نیاز هست تا یک کلاس Repository جدا ساخته شود و این مخزن مسئولیت ساخت کوئری های مرتبط را به عهده خواهد گرفت.
🔰 الگوی Unit Of Work هم یکی از الگوی های رایج هست و هدفش اینه که، چندین عملیات در قالب یک درخواست و یک Transaction روی دیتابیس اعمال بشه؛ نه اینکه به ازای هر تغییر و هر بار افزودن و حذف داده ها، بلافاصله و تک به تک، داده ها را به سمت پایگاه داده ارسال کنیم. چرا که این امر هم موجب کاهش کارایی و مصرف منابع خواهد شد و هم ممکن است در حین ثبت داده ها ناگهان خطایی رخ دهد و باقی تغییرات در پایگاه داده منعکس نشوند و این یعنی تراکنشهای ناموفق یا پاره ای (partially-executed) که نهایتا به یکپارچگی و صحت دادهها صدمه میزند.
جالبه بدونین Entity Framework یک پیاده سازی کامل از این 2 الگو هست چرا که هم جزئیات و فرایند اجرا کوئری و عملیات دیتابیسی را داخل DbSet های Context متمرکز کرده (مانند Repositoy)
و هم توسط مکانیزم ChangeTracker، تمام عملیات لازم (افزودن، اپدیت اشیای ویرایش شده و یا حذف شده و...) رو توسط متد SaveChanges به صورت یک جا روی دیتابیس اعمال میکنه (مانند UOW)
حتی در داکیومنت خود ماکروسافت نیز، کلاس DbContext رو اینگونه معرفی میکنه:
🔰 ولی چرا استفاده از الگوی Repository و Unit Of Work روی EF روش مناسبی نیست؟
1️⃣ انتزاع روی انتزاع اضافه کاریه!
همون طور که قبلا گفتیم EF پیاده سازی کاملی از این دو الگو هست و افزودن این 2 الگو روی آن، "دوباره کاری" ایی هست و اصلاحا بهش میگن انتزاعی روی انتزاع دیگر (Abstraction of an Abstraction) که تازه باعث میشه یه سری از قابلیت های EF رو از دست بدیم چرا که پیاده سازی ما به کاملی و یکپارچگی خود EF نیست! و عملا قابلیت های "خاص و ویژه" EF رو از دست میدیم.
2️⃣ جایگزین کردن ORM همیشه معقول نیست!
یکی دیگه از دلایلی که برنامه نویسان برای استفاده از Repository میارند اینه که ما میتونیم براحتی ORM پروژه رو تغییر بدیم.
وقتی شما از یک اینترفیس IRepository تو کل پروژتون استفاده میکنین باعث میشه بتونین کلاس پیاده سازی کننده این اینترفیس رو با یک کلاس دیگه (که همین اینترفیس IRepository رو پیاده سازی کرده) جایگزین کنین؛ مثلا یک بار میشه اون رو توسط EF پیاده سازی کنین و بار دیگه توسط یک ORM دیگه (مثلNHibernate) و چون هر دو اینها یک اینترفیس مشترک (IRepository) رو پیاده سازی کرده اند می توان بدون تغییر در کد ها، براحتی یکی را جایگزین دیگری کرد. (البته در واقع این مزیت نه به لطف Repository، بلکه به لطف استفاده از Interface به جای یک کلاس مشخص به دست میاد)
نکته مهم اینه که این مزیت زمانی مفیده که احتمال میدین ORM پروژه تغییر کنه، در غیر این صورت الکی خودتون رو به دردسر انداختین.
به شخصه توی ده ها پروژه ای که انجام دادم هیچ موقع ندیدم ORM یه پروژه عوض بشه، ولی همیشه دردسر این روش رو داریم به جون میخریم و نهایتا چیزی به جز پیچیده تر شدن کد ها و کمتر شدن خوانایی اونها و کند شدن سرعت توسعه، چیز خاصی نصیبمون نمیشه.
ادامه در پست بعد 👇
@IranAspMvc
http://bit.ly/2D9Bk3k
🔰 الگوی Repository پیشنهاد می کنه لایه ی واسطی بین لایه بیزینس/منطق برنامه و لایه دسترسی به دیتابیس ایجاد بشه و کد های لازم برای انجام عملیات روی دیتابیس داخل اون نوشته بشه. این لایه نحوه دسترسی به پایگاه داده را از لایه های بالایی پنهان می کنه و لایه های بالایی برای اجرای دستورات و یا فراخوانی داده ها باید از طریق این لایه درخواست های خودشون رو مطرح کنند.
درنتیجه برای جداسازی و ایزوله کردن نحوه دسترسی به داده، اون ها رو داخل Repository می میگذارند و لایه های بالایی بدون درگیر شدن با جزئیات نحوه دسترسی به داده ها، فقط متد های ریپازیتوری رو فراخوانی می کنند
در این الگو برای هر یک از Domain Model (کلاس های معادل جداولمون) نیاز هست تا یک کلاس Repository جدا ساخته شود و این مخزن مسئولیت ساخت کوئری های مرتبط را به عهده خواهد گرفت.
🔰 الگوی Unit Of Work هم یکی از الگوی های رایج هست و هدفش اینه که، چندین عملیات در قالب یک درخواست و یک Transaction روی دیتابیس اعمال بشه؛ نه اینکه به ازای هر تغییر و هر بار افزودن و حذف داده ها، بلافاصله و تک به تک، داده ها را به سمت پایگاه داده ارسال کنیم. چرا که این امر هم موجب کاهش کارایی و مصرف منابع خواهد شد و هم ممکن است در حین ثبت داده ها ناگهان خطایی رخ دهد و باقی تغییرات در پایگاه داده منعکس نشوند و این یعنی تراکنشهای ناموفق یا پاره ای (partially-executed) که نهایتا به یکپارچگی و صحت دادهها صدمه میزند.
جالبه بدونین Entity Framework یک پیاده سازی کامل از این 2 الگو هست چرا که هم جزئیات و فرایند اجرا کوئری و عملیات دیتابیسی را داخل DbSet های Context متمرکز کرده (مانند Repositoy)
و هم توسط مکانیزم ChangeTracker، تمام عملیات لازم (افزودن، اپدیت اشیای ویرایش شده و یا حذف شده و...) رو توسط متد SaveChanges به صورت یک جا روی دیتابیس اعمال میکنه (مانند UOW)
حتی در داکیومنت خود ماکروسافت نیز، کلاس DbContext رو اینگونه معرفی میکنه:
A DbContext instance represents a combination of the Unit Of Work and Repository patterns ...حال اینکه بعضی ها اصرار دارند روی EF (که خود پیاده سازی کاملی از Repository و UnitOfWork هست) یک بار دیگه این 2 الگو رو پیاده سازی کنند، یک باور اشتباه هست، چرا که درک صحیح و کاملی از این الگو ها و EF ندارند.
🔰 ولی چرا استفاده از الگوی Repository و Unit Of Work روی EF روش مناسبی نیست؟
1️⃣ انتزاع روی انتزاع اضافه کاریه!
همون طور که قبلا گفتیم EF پیاده سازی کاملی از این دو الگو هست و افزودن این 2 الگو روی آن، "دوباره کاری" ایی هست و اصلاحا بهش میگن انتزاعی روی انتزاع دیگر (Abstraction of an Abstraction) که تازه باعث میشه یه سری از قابلیت های EF رو از دست بدیم چرا که پیاده سازی ما به کاملی و یکپارچگی خود EF نیست! و عملا قابلیت های "خاص و ویژه" EF رو از دست میدیم.
2️⃣ جایگزین کردن ORM همیشه معقول نیست!
یکی دیگه از دلایلی که برنامه نویسان برای استفاده از Repository میارند اینه که ما میتونیم براحتی ORM پروژه رو تغییر بدیم.
وقتی شما از یک اینترفیس IRepository تو کل پروژتون استفاده میکنین باعث میشه بتونین کلاس پیاده سازی کننده این اینترفیس رو با یک کلاس دیگه (که همین اینترفیس IRepository رو پیاده سازی کرده) جایگزین کنین؛ مثلا یک بار میشه اون رو توسط EF پیاده سازی کنین و بار دیگه توسط یک ORM دیگه (مثلNHibernate) و چون هر دو اینها یک اینترفیس مشترک (IRepository) رو پیاده سازی کرده اند می توان بدون تغییر در کد ها، براحتی یکی را جایگزین دیگری کرد. (البته در واقع این مزیت نه به لطف Repository، بلکه به لطف استفاده از Interface به جای یک کلاس مشخص به دست میاد)
نکته مهم اینه که این مزیت زمانی مفیده که احتمال میدین ORM پروژه تغییر کنه، در غیر این صورت الکی خودتون رو به دردسر انداختین.
به شخصه توی ده ها پروژه ای که انجام دادم هیچ موقع ندیدم ORM یه پروژه عوض بشه، ولی همیشه دردسر این روش رو داریم به جون میخریم و نهایتا چیزی به جز پیچیده تر شدن کد ها و کمتر شدن خوانایی اونها و کند شدن سرعت توسعه، چیز خاصی نصیبمون نمیشه.
ادامه در پست بعد 👇
@IranAspMvc
http://bit.ly/2D9Bk3k
3️⃣ محرومیت از قابلیت های ویژه EF
متاسفانه همین مزیت بالا یک عیب هم محسوب میشه؛ چرا که پنهان سازی EF پشت یک اینترفیس با خواص و متد های محدود، شما رو از دستیابی به تمامی قابلیت های یک ORM مثل EF محروم میکنه و فقط میتونین از متد های اون اینترفیس (IRepository) استفاده کنین. (مثلا SelectAll و SelectById و...) ولی دیگه نمیتونین از متد ها و قابلیت های خاص EF مثل Entry یا ChangeTracker یا استفاده کنین.
در واقع واسه این که بتونیم یه ORM رو با یه ORM دیگه جایگزین کنیم، حتما باید توی اینترفیس IRepository مون از ویژگی های مشتریک این دو استفاده کنیم، تا قابل جایگزین کردن باشن و گرنه اگر از ویژگی های خاص یه ORM داخلش استفاده کنیم، چون ORM دوم، این ویژگی های خاص رو نداره، پس عملا نیمتونه این اینترفیس رو پیاده سازی کنه و این یعنی از دست دادن یک سری ویژگی خاص و مهم یک ORM!
نکته دیگری که هست اینه که تعویض ORM پروژه (حتی با رعایت الگو های Repository و UnitOfWork) عملا امکان پذیر نیست و انجامش بیش از اون چیزی که فکر میکنین مشکل ساز میشه چرا که هر ORM پیازه سازی خاص خودش رو برای دستورات Linq داره، یعنی ممکنه یه کوئری Linq ثابت، توی 2تا ORM، دو جواب متفاوت برگردونه!
حتی بعضی متد های خاصی توی یه ORM هست که اصلا توی دیگری وجود نداره، حتی معادلی هم نداره.
نکته: البته که خود EF طوری پیاده سازی شده که با تغییر Provider مربوطه میشه دیتابیس پروژه رو عوض کرد ولی مشابه مشکلات بالا، درعمل، تعویض Database پروژه هم با چالش هایی همراهه و براحتی امکان پذیر نیست.
4️⃣ دقیقا چه فایده ای داره؟!
در گذشته که ORM های قدرتمند امروزی وجود نداشت، برای انجام عملیات روی دیتابیس باید کدهای زیادی نوشته می شد (از جمله : باز کردن کانکشن – نوشتن کوئری مورد نیاز – اجر روی دیتابیس – گرفتن خروجی کوئری - بستن کانکشن - و...)
پس به جای اینکه توی کد لایه های بالا، تمامی کد های ارتباط با دیتابیس رو بنویسیم میومدیم و از Repository استفاده میکردیم (همون DAL قدیم)
ولی الان توی EF همه این ها داخل متد Add یک DbSet محصور شدن و عملا صدا زدن متد Add برابری میکنه با اون 10 خط کدی قبلا که برای ارتباط با دیتابیس و انجام عملیات باید مینوشتیم
شاید این سوال هم براتون پیش اومده باشه که چرا باید داخل Repository متد Add ایی بنویسم که کار خاصی نمیکنه و فقط داره متد Add خود DbSet های EF رو صدا میزنه؟! پس دقیقا چه فایده ای داره؟! چرا اصلا از Add خود EF DbSet استفاده نکنیم؟!
5️⃣ محدودیت بی فایده!
فرض کنید میخواهید ریپازیتوری ایی بنویسید که برنامه نویس لایه های بالاتر رو محدود به استفاده از متد های مشخصی بکنید (که خودتون در ریپازیتوری تعریف کردین)
بنابراین مجبورید به ازای هر حالت خاص یک متد مشخص بنویسید مثل FindStudentByEmail، FindStudentById، FindStudentByName و...
بدین صورت برنامه نویس لایه های بالاتر محدود به استفاده از (فقط) همین متد ها میشه و دیگه نمیتونه Student رو بر اساس فیلتر دیگری (مثلاPhone) واکشی کنه
این محدودید خودش ممکنه به یک معضل تبدیل بشه، چرا که یا برنامه نویس نمیتونه اون واکشی خاصی که میخواد رو انجام بده یا شما مجبورید به ازای تمام حالات متد های مختلفی برای اون بنویسید که این یعنی افزاین حجم کدها به مرور، کاهش خوانایی و سادگی پروژه و همچنین کاهش سرعت توسعه
حال اگر ریپازیتوری نبود، برنامه نویس میتونست خودش از dbContext.Students استفاده کنه هر طور که مایل هست اطلاعات رو واکشی کنه یا عملیاتی رو انجام بده.
❇️ خب پس دیدیم که Repository و UnitOfWork روی EF، آنچنان چنگی هم به دل نمیزنه
ولی... شخصا پیشنهاد میکنم ازش استفاده بکنین حتما! (به شرط اینکه درست پیاده سازی بشه)
حالا اینکه" چرا و چگونه"، در پست بعدی وقتی مزیت هاشو دیدم می فهمید
@IranAspMvc
3️⃣ محرومیت از قابلیت های ویژه EF
متاسفانه همین مزیت بالا یک عیب هم محسوب میشه؛ چرا که پنهان سازی EF پشت یک اینترفیس با خواص و متد های محدود، شما رو از دستیابی به تمامی قابلیت های یک ORM مثل EF محروم میکنه و فقط میتونین از متد های اون اینترفیس (IRepository) استفاده کنین. (مثلا SelectAll و SelectById و...) ولی دیگه نمیتونین از متد ها و قابلیت های خاص EF مثل Entry یا ChangeTracker یا استفاده کنین.
در واقع واسه این که بتونیم یه ORM رو با یه ORM دیگه جایگزین کنیم، حتما باید توی اینترفیس IRepository مون از ویژگی های مشتریک این دو استفاده کنیم، تا قابل جایگزین کردن باشن و گرنه اگر از ویژگی های خاص یه ORM داخلش استفاده کنیم، چون ORM دوم، این ویژگی های خاص رو نداره، پس عملا نیمتونه این اینترفیس رو پیاده سازی کنه و این یعنی از دست دادن یک سری ویژگی خاص و مهم یک ORM!
نکته دیگری که هست اینه که تعویض ORM پروژه (حتی با رعایت الگو های Repository و UnitOfWork) عملا امکان پذیر نیست و انجامش بیش از اون چیزی که فکر میکنین مشکل ساز میشه چرا که هر ORM پیازه سازی خاص خودش رو برای دستورات Linq داره، یعنی ممکنه یه کوئری Linq ثابت، توی 2تا ORM، دو جواب متفاوت برگردونه!
حتی بعضی متد های خاصی توی یه ORM هست که اصلا توی دیگری وجود نداره، حتی معادلی هم نداره.
نکته: البته که خود EF طوری پیاده سازی شده که با تغییر Provider مربوطه میشه دیتابیس پروژه رو عوض کرد ولی مشابه مشکلات بالا، درعمل، تعویض Database پروژه هم با چالش هایی همراهه و براحتی امکان پذیر نیست.
4️⃣ دقیقا چه فایده ای داره؟!
در گذشته که ORM های قدرتمند امروزی وجود نداشت، برای انجام عملیات روی دیتابیس باید کدهای زیادی نوشته می شد (از جمله : باز کردن کانکشن – نوشتن کوئری مورد نیاز – اجر روی دیتابیس – گرفتن خروجی کوئری - بستن کانکشن - و...)
پس به جای اینکه توی کد لایه های بالا، تمامی کد های ارتباط با دیتابیس رو بنویسیم میومدیم و از Repository استفاده میکردیم (همون DAL قدیم)
ولی الان توی EF همه این ها داخل متد Add یک DbSet محصور شدن و عملا صدا زدن متد Add برابری میکنه با اون 10 خط کدی قبلا که برای ارتباط با دیتابیس و انجام عملیات باید مینوشتیم
شاید این سوال هم براتون پیش اومده باشه که چرا باید داخل Repository متد Add ایی بنویسم که کار خاصی نمیکنه و فقط داره متد Add خود DbSet های EF رو صدا میزنه؟! پس دقیقا چه فایده ای داره؟! چرا اصلا از Add خود EF DbSet استفاده نکنیم؟!
5️⃣ محدودیت بی فایده!
فرض کنید میخواهید ریپازیتوری ایی بنویسید که برنامه نویس لایه های بالاتر رو محدود به استفاده از متد های مشخصی بکنید (که خودتون در ریپازیتوری تعریف کردین)
بنابراین مجبورید به ازای هر حالت خاص یک متد مشخص بنویسید مثل FindStudentByEmail، FindStudentById، FindStudentByName و...
بدین صورت برنامه نویس لایه های بالاتر محدود به استفاده از (فقط) همین متد ها میشه و دیگه نمیتونه Student رو بر اساس فیلتر دیگری (مثلاPhone) واکشی کنه
این محدودید خودش ممکنه به یک معضل تبدیل بشه، چرا که یا برنامه نویس نمیتونه اون واکشی خاصی که میخواد رو انجام بده یا شما مجبورید به ازای تمام حالات متد های مختلفی برای اون بنویسید که این یعنی افزاین حجم کدها به مرور، کاهش خوانایی و سادگی پروژه و همچنین کاهش سرعت توسعه
حال اگر ریپازیتوری نبود، برنامه نویس میتونست خودش از dbContext.Students استفاده کنه هر طور که مایل هست اطلاعات رو واکشی کنه یا عملیاتی رو انجام بده.
❇️ خب پس دیدیم که Repository و UnitOfWork روی EF، آنچنان چنگی هم به دل نمیزنه
ولی... شخصا پیشنهاد میکنم ازش استفاده بکنین حتما! (به شرط اینکه درست پیاده سازی بشه)
حالا اینکه" چرا و چگونه"، در پست بعدی وقتی مزیت هاشو دیدم می فهمید
@IranAspMvc
❇️ توی پست های قبلی دیدیم که منطقا استفاده از Repository و Unit Of Work روی Entity Framework اشتباهه ولی عملا میتونه مفید باشه به شرطی که :
1️⃣ صرفا به دید یک Abstraction بهش نگاه کنیم
مثلا فرض کنید تا الان استراتژی حذف شما به صورت Physical (حذف واقعی از دیتابیس) بوده و اکنون میخواین اون رو به حذف Logical (حذف منطقی توسط IsDelete) تغییر بدین. در این صورت باید تمام جا هایی که مستقیما از متد Remove خود DbSet استفاده میکردین رو تغییر بدین و این تغییر در یک پروژه بزرگ دردسر زیادی رو به همراه داره، در صورتی که استفاده از یک Abstraction کار رو بسیار ساده میکرد
درواقع به جای اینکه مستقیما با DbContext و DbSet ها سرو کار داشته باشیم بهتره یک لایه انتزاعی (Abstraction) روی اون ایجاد کنیم و همه جا از اون Abstraction استفاده کنیم، یعنی به جای اینکه در همه جای پروژه متد Remove خود EF رو صدا بزنیم، اون رو داخل کلاس Repository نامی بنویسیم و همه جا متد Delete ریپازیتوری رو فراخوانی کنیم. این باعث میشه اگه یه روزی لازم شد متد Delete ریپازیتوری رو سفارشی کنیم و تغییر بدیم، اون تغییر تو کل پروژه اعمال بشه، چرا که تو کل پروژه از متد Delete ریپازیتوری استفاده کردیم.
به همین ترتیب اگر نیاز به سفارشی سازی متد های دیگر (مثلا Add یا Update) دارید (مثلا اعمال اعتبارسنجی خاص به هنگام افزودن و ویرایش یا لاگ گرفتن تغییرات به هنگام ویرایش و... ) فقط کافیه متد های اون رو داخل Repository تغییر بدین و نه اینکه مجبور باشین تو کل پروژه کد هاتون رو تغییر بدین.
2️⃣ قابلیت های ویژه EF رو از بین نبریم
اگر به صورت معمول از Repository و Unit Of Work استفاده کنیم (یعنی اکثر همین مثال هایی که در وب موجود هست) باعت میشه قابلیت های ویژه EF رو از دست بدیم و نتونیم از اون ها استفاده کنیم
درواقع وقتی EF DbContext رو پشت Unit Of Work و DbSet های اون رو پشت Repository مخفی میکنیم، عملا میتونیم "صرفا" از متد هایی که داخل اون Repository تعریف کردیم استفاده کنیم (یعنی فقط از متد های Add/Delete/Update/Select)
چرا که داخل ریپازیتوری مون، متد یا خاصیتی برای استفاده از قابلیت های ویژه EF مثل ChangeTracker , Entry و ... تعریف نکردیم
پس باید طوری از Repository استفاده کنیم که اکثر قابلیت های EF رو قابل استفاده بگذاریم و بلااستفاده کردن ویژگی خاص اش رو به حداقل برسونیم
مثلا داخل Repository، دسترسی به خود DbSet رو فراهم کنیم
یا مثلا داخل Unit Of Work، دسترسی به شی Database، ChangeTracker و Property های مهم DbContext و نیز متد های مهم اون از جمله Entry و ... رو فراهم کنیم
بدین ترتیب هم از Abstraction استفاده کردیم و هم قابلیت های ویژه EF رو مخفی و بلااستفاده نکردیم.
3️⃣ از Repository جنریک استفاده کنیم
اصل DRY یا همون Dont Repeat Yourself تاکید میکنه به جای اینکه کد های مشابهی رو چندین بار در جا های مختلف پروژه تکرار کنین، یک بار یه جا تعریفش کنین و بقیه جا ها صرفا اون رو فراخونیش کنین
اگر از Generic Repository استفاده نکنین مجبورین به ازای هر کلاسی که به مدل پروژ اضافه میکنید یک ریپازیتوری مختص آن نیز بسازید که دقیقا همان کد های CRUD در آن تکرار شده و این علاوه بر تکرار کد ها (نقض DRY) یعنی کند تر شدن سرعت توسعه.
در صورتی که میتونین به جای اون از Generic Repository استفاده کنید تا الکی کد های تکراری تولید نکنین منتها متد های اون رو virtual تعریف کنین که هرموقع به سفارشی سازی نیاز داشتین با override کردن متد های کلاس Generic Repository در کلاس های مشتق شده از اون، کار سفارشی سازی رو انجام بدین.
بدین ترتیب هم از تکرار کد ها جلوگیری کردیم و هم امکان سفارشی سازی متد ها رو داریم
البته بعضیا میگن جنریک پروژه رو کند میکنه، باید خدمتتون بگم این حرفا رو کلا از ذهنتون بریزید دور؛ تاثیرش خیلی خیلی ناچیزه و در برابر مزیت اش اصلا منطقی نیست ازش استفاده نکنیم.
http://bit.ly/2PKUF1w
پس دیدیم که چرا استفاده از Repository و Unit Of Work روی EF به صورت "معمول (مثال های رایج)" اشتباهه و فهمیدیم بهترین حالت پیاده سازی Repository چیه، انشالا در پست های آینده، یه نمونه پروژه همراه با پیاده سازی اصولی این 2 الگو، آماده و در دسترس تون قرار میدم
@IranAspMvc
1️⃣ صرفا به دید یک Abstraction بهش نگاه کنیم
مثلا فرض کنید تا الان استراتژی حذف شما به صورت Physical (حذف واقعی از دیتابیس) بوده و اکنون میخواین اون رو به حذف Logical (حذف منطقی توسط IsDelete) تغییر بدین. در این صورت باید تمام جا هایی که مستقیما از متد Remove خود DbSet استفاده میکردین رو تغییر بدین و این تغییر در یک پروژه بزرگ دردسر زیادی رو به همراه داره، در صورتی که استفاده از یک Abstraction کار رو بسیار ساده میکرد
درواقع به جای اینکه مستقیما با DbContext و DbSet ها سرو کار داشته باشیم بهتره یک لایه انتزاعی (Abstraction) روی اون ایجاد کنیم و همه جا از اون Abstraction استفاده کنیم، یعنی به جای اینکه در همه جای پروژه متد Remove خود EF رو صدا بزنیم، اون رو داخل کلاس Repository نامی بنویسیم و همه جا متد Delete ریپازیتوری رو فراخوانی کنیم. این باعث میشه اگه یه روزی لازم شد متد Delete ریپازیتوری رو سفارشی کنیم و تغییر بدیم، اون تغییر تو کل پروژه اعمال بشه، چرا که تو کل پروژه از متد Delete ریپازیتوری استفاده کردیم.
به همین ترتیب اگر نیاز به سفارشی سازی متد های دیگر (مثلا Add یا Update) دارید (مثلا اعمال اعتبارسنجی خاص به هنگام افزودن و ویرایش یا لاگ گرفتن تغییرات به هنگام ویرایش و... ) فقط کافیه متد های اون رو داخل Repository تغییر بدین و نه اینکه مجبور باشین تو کل پروژه کد هاتون رو تغییر بدین.
2️⃣ قابلیت های ویژه EF رو از بین نبریم
اگر به صورت معمول از Repository و Unit Of Work استفاده کنیم (یعنی اکثر همین مثال هایی که در وب موجود هست) باعت میشه قابلیت های ویژه EF رو از دست بدیم و نتونیم از اون ها استفاده کنیم
درواقع وقتی EF DbContext رو پشت Unit Of Work و DbSet های اون رو پشت Repository مخفی میکنیم، عملا میتونیم "صرفا" از متد هایی که داخل اون Repository تعریف کردیم استفاده کنیم (یعنی فقط از متد های Add/Delete/Update/Select)
چرا که داخل ریپازیتوری مون، متد یا خاصیتی برای استفاده از قابلیت های ویژه EF مثل ChangeTracker , Entry و ... تعریف نکردیم
پس باید طوری از Repository استفاده کنیم که اکثر قابلیت های EF رو قابل استفاده بگذاریم و بلااستفاده کردن ویژگی خاص اش رو به حداقل برسونیم
مثلا داخل Repository، دسترسی به خود DbSet رو فراهم کنیم
یا مثلا داخل Unit Of Work، دسترسی به شی Database، ChangeTracker و Property های مهم DbContext و نیز متد های مهم اون از جمله Entry و ... رو فراهم کنیم
بدین ترتیب هم از Abstraction استفاده کردیم و هم قابلیت های ویژه EF رو مخفی و بلااستفاده نکردیم.
3️⃣ از Repository جنریک استفاده کنیم
اصل DRY یا همون Dont Repeat Yourself تاکید میکنه به جای اینکه کد های مشابهی رو چندین بار در جا های مختلف پروژه تکرار کنین، یک بار یه جا تعریفش کنین و بقیه جا ها صرفا اون رو فراخونیش کنین
اگر از Generic Repository استفاده نکنین مجبورین به ازای هر کلاسی که به مدل پروژ اضافه میکنید یک ریپازیتوری مختص آن نیز بسازید که دقیقا همان کد های CRUD در آن تکرار شده و این علاوه بر تکرار کد ها (نقض DRY) یعنی کند تر شدن سرعت توسعه.
در صورتی که میتونین به جای اون از Generic Repository استفاده کنید تا الکی کد های تکراری تولید نکنین منتها متد های اون رو virtual تعریف کنین که هرموقع به سفارشی سازی نیاز داشتین با override کردن متد های کلاس Generic Repository در کلاس های مشتق شده از اون، کار سفارشی سازی رو انجام بدین.
بدین ترتیب هم از تکرار کد ها جلوگیری کردیم و هم امکان سفارشی سازی متد ها رو داریم
البته بعضیا میگن جنریک پروژه رو کند میکنه، باید خدمتتون بگم این حرفا رو کلا از ذهنتون بریزید دور؛ تاثیرش خیلی خیلی ناچیزه و در برابر مزیت اش اصلا منطقی نیست ازش استفاده نکنیم.
http://bit.ly/2PKUF1w
پس دیدیم که چرا استفاده از Repository و Unit Of Work روی EF به صورت "معمول (مثال های رایج)" اشتباهه و فهمیدیم بهترین حالت پیاده سازی Repository چیه، انشالا در پست های آینده، یه نمونه پروژه همراه با پیاده سازی اصولی این 2 الگو، آماده و در دسترس تون قرار میدم
@IranAspMvc
به عنوان نکته نهایی هم بهتره به سوال زیر جواب بدیم
لایه Service چیه و چه تفاوتی با Repository داره؟
اصولا Repository برای این نیست که منطق برنامه (Business Logic) رو پیاده سازی کنه. در واقع Repository صرفا لایه "سترسی به دیتابیس" هست که و نه بیشتر؛ و این لایه سرویس هست که باید منطق برنامه (Business Logic) رو پیاده سازی کنه، درنتیجه میدونه چه موقع به چه Repository هایی فرمان های CRUD رو بده تا منطق برنامه پیاده سازی بشه.
اصولش اینه که به جای اینکه منطق برنامه اتون رو داخل کنترولر و اکشن تون بنویسین؛ اون ها رو داخل لایه سرویس پیاده سازی کنین و داخل اکشن فقط متد های لازم رو از سرویس فراخوانی کنین، بدین ترتیب هم باعث میشه منطق شما از لایه Presentation جداسازی و ایزوله بشه و هم کد های اکشن هاتون به شدت کاهش پیدا میکنه و ساده میشه
@IranAspMvc
لایه Service چیه و چه تفاوتی با Repository داره؟
اصولا Repository برای این نیست که منطق برنامه (Business Logic) رو پیاده سازی کنه. در واقع Repository صرفا لایه "سترسی به دیتابیس" هست که و نه بیشتر؛ و این لایه سرویس هست که باید منطق برنامه (Business Logic) رو پیاده سازی کنه، درنتیجه میدونه چه موقع به چه Repository هایی فرمان های CRUD رو بده تا منطق برنامه پیاده سازی بشه.
اصولش اینه که به جای اینکه منطق برنامه اتون رو داخل کنترولر و اکشن تون بنویسین؛ اون ها رو داخل لایه سرویس پیاده سازی کنین و داخل اکشن فقط متد های لازم رو از سرویس فراخوانی کنین، بدین ترتیب هم باعث میشه منطق شما از لایه Presentation جداسازی و ایزوله بشه و هم کد های اکشن هاتون به شدت کاهش پیدا میکنه و ساده میشه
@IranAspMvc
❇️ باور های غلط و رایجی در مورد Unit Of Work وجود داره که بعضا افراد رو به اشتباه میندازه
پس بهتره ببینیم اصولا کارش چیه و دقیقتر بررسیش کنیم
در واقع کار اصلی Unit of Work اینه که لیست تمامی object (رکورد) هایی که :
1-اضافه شده اند (Insert)
2-تغییر کرده اند(Update)
3-حذف شده اند(Delete)
رو در خودش نگه داره و اصطلاحا اونها رو "Track" (ردیابی) کنه
و سپس در یک تراکنش به دیتابیس (یک درخواست به دیتابیس در قالب یک Transaction) همه موارد بالا رو روی دیتابیس اعمال کنه.
و این دقیقا همون کاریه که در Entity Framework (به اختصار EF) در DbContext توسط مکانیسم ChangeTracker اتفاق میافته
اصل Unit Of Work اینه و خود EF به صورت کامل اون رو پیاده کرده و پیاده سازی یک Unit Of Work دیگه روی اون "یک کار اضافی" هست
ولی کاری که به صورت معمول انجام میشه و البته مفید هم هست اینه که یک Abstraction (یک لایه انتزاعی) روی DbContext ایجاد میکنیم و به جای اینکه مستقیما با DbContext سر وکار داشته باشیم، با اون Abstraction سرو کار داریم.
این باعث میشه اگه یه روزی لازم بود تغییری رو روی DbContext اعمال کنیم، چون در همه جای پروژه از اون Abstraction (که معادل DbContext هست) استفاده میکنیم، تغییراتمون تو کل پروژه اعمال بشه. *در واقع فقط فایده اش همینه.
به همین صورت استفاده از Repository هم روی EF اشتباه هست (چرا که EF خودش پیاده سازی کاملی از Repository و Unit Of Work) هست. ولی در اینجا هم استفاده از یک Abstraction روی DbSet ها (همون ریپازیتوری های داخل EF DbContext) یک کار مفید هست و باعث میشه اگه یه روزی خواستیم تغییری روی مثلا متد Add یک ریپازیتوری اعمال کنیم، چون در همه جا از اون Abstraction استفاده شده، تغییرمون توی کل پروژه اعمال بشه.
در کل اگه به "معنای اصلی" Repository و Unit Of Work بخوایم اون رو برای EF پیاده کنیم کار اشتباهی هست چرا که EF پیاده سازی کاملی از این دو هست
ولی کاری که مفید هست و پیشنهاد میشه استفاده از Repository و Unit Of Work به صورت یک Abstraction روی DbContext و DbSet ها در EF هست
اون چیزی که پیشنهاد میشه توی هر درخواست وب (Scope)، یک DbContext داشته باشیم (و نه چندین dbContext) اصطلاحا بهش میگن
الگوی "Context Per Request" یا "Session Per Request"
که اینکار نه توسط Unit Of Work و یا حتی خود EF بلکه توسط سیستم تزریق وابستگی و در اصل توسط IOC Container ها اتفاق میافته
درواقع IOC Container هست که میدونه باید برای هر درخواست (یا اصولا Scope)، فقط و فقط یک DbContext ساخته بشه (به جای اینکه چندین DbContext ایجاد بشه!)
اگه بخوایم دقیق تر بحث درخواست و Scope رو باز کنیم باید بگیم که Scope یک "محدوده" هست که وقتی ایجاد میشه، اشیایی که درون اون ایجاد میشوند داخل همون Scope (محدوده) قابل استفاده هستند و در واقع "زنده" هستند و پس از پایان اون محدوده (Scope)، تمام اشیایی که در اون Scope ایجاد شده اند نیز "میمیرند" (در واقع Dispose میشوند و از بین میروند)
البته تمامی این حرف ها "فقط" برای اشیایی صادق است که Lifetime (بازه عمر) آنها به صورت Scope تنظیم شده باشند.
حال جالبه بدونین که IOC Container میاد و در ابتدای یک درخواست وب (Request)، یک Scope ایجاد میکنه و در پایان اون درخواست وب، اون Scope رو از بین میبره (در نتیجه تمام اشیایی آن Scope هم از بین میروند)
در این حالت وقتی ما DbContext رو به صورت Scope (درواقع با Lifetime یا همون بازه عمر برابر با Scope) تعریف میکنیم، اتفاقی که میافته اینه که IOC Container در ابتدای هر درخواست، یک Scope ایجاد میکنه و درنتیجه DbContext ما هم (که قبلا به صورت Scope تنظیم شده است)، فقط و فقط یک نسخه از آن داخل Scope مربوطه (که اول درخواست ساخته شده) ایجاد میشه؛ در نتیجه طی اون Scope ما هر چندبار هم که DbContext رو فراخوانی کنیم، توسط سیستم تزریق وابستگی، "فقط و فقط" همون یک نسخه اولیه به ما ارجاع(پاس) داده میشه و در این حالت الگوی Context Per Request تحقق میابد
در پایان درخواست وب هم، چون Scope مربوطه ازبین میره، تمامی اشیای داخل آن(ایجاد شده توسط آن Scope) نیز از بین میروند از جمله همین DbContext ما و درواقع در پایان درخواست، DbContext ما هم Dispose میشه
اگه میخواین بیشتر با الگوی Unit Of Work اشنا بشین مقاله زیر رو مسعود بهرامی عزیز بخونین
http://refactor.ir/2017/05/11/unit-of-work/
اگه دوست داشین میتونین تعریف خود مارتین فاولر رو هم در مورد Unit Of Work بخونین
https://martinfowler.com/eaaCatalog/unitOfWork.html
@IranAspMvc
پس بهتره ببینیم اصولا کارش چیه و دقیقتر بررسیش کنیم
در واقع کار اصلی Unit of Work اینه که لیست تمامی object (رکورد) هایی که :
1-اضافه شده اند (Insert)
2-تغییر کرده اند(Update)
3-حذف شده اند(Delete)
رو در خودش نگه داره و اصطلاحا اونها رو "Track" (ردیابی) کنه
و سپس در یک تراکنش به دیتابیس (یک درخواست به دیتابیس در قالب یک Transaction) همه موارد بالا رو روی دیتابیس اعمال کنه.
و این دقیقا همون کاریه که در Entity Framework (به اختصار EF) در DbContext توسط مکانیسم ChangeTracker اتفاق میافته
اصل Unit Of Work اینه و خود EF به صورت کامل اون رو پیاده کرده و پیاده سازی یک Unit Of Work دیگه روی اون "یک کار اضافی" هست
ولی کاری که به صورت معمول انجام میشه و البته مفید هم هست اینه که یک Abstraction (یک لایه انتزاعی) روی DbContext ایجاد میکنیم و به جای اینکه مستقیما با DbContext سر وکار داشته باشیم، با اون Abstraction سرو کار داریم.
این باعث میشه اگه یه روزی لازم بود تغییری رو روی DbContext اعمال کنیم، چون در همه جای پروژه از اون Abstraction (که معادل DbContext هست) استفاده میکنیم، تغییراتمون تو کل پروژه اعمال بشه. *در واقع فقط فایده اش همینه.
به همین صورت استفاده از Repository هم روی EF اشتباه هست (چرا که EF خودش پیاده سازی کاملی از Repository و Unit Of Work) هست. ولی در اینجا هم استفاده از یک Abstraction روی DbSet ها (همون ریپازیتوری های داخل EF DbContext) یک کار مفید هست و باعث میشه اگه یه روزی خواستیم تغییری روی مثلا متد Add یک ریپازیتوری اعمال کنیم، چون در همه جا از اون Abstraction استفاده شده، تغییرمون توی کل پروژه اعمال بشه.
در کل اگه به "معنای اصلی" Repository و Unit Of Work بخوایم اون رو برای EF پیاده کنیم کار اشتباهی هست چرا که EF پیاده سازی کاملی از این دو هست
ولی کاری که مفید هست و پیشنهاد میشه استفاده از Repository و Unit Of Work به صورت یک Abstraction روی DbContext و DbSet ها در EF هست
اون چیزی که پیشنهاد میشه توی هر درخواست وب (Scope)، یک DbContext داشته باشیم (و نه چندین dbContext) اصطلاحا بهش میگن
الگوی "Context Per Request" یا "Session Per Request"
که اینکار نه توسط Unit Of Work و یا حتی خود EF بلکه توسط سیستم تزریق وابستگی و در اصل توسط IOC Container ها اتفاق میافته
درواقع IOC Container هست که میدونه باید برای هر درخواست (یا اصولا Scope)، فقط و فقط یک DbContext ساخته بشه (به جای اینکه چندین DbContext ایجاد بشه!)
اگه بخوایم دقیق تر بحث درخواست و Scope رو باز کنیم باید بگیم که Scope یک "محدوده" هست که وقتی ایجاد میشه، اشیایی که درون اون ایجاد میشوند داخل همون Scope (محدوده) قابل استفاده هستند و در واقع "زنده" هستند و پس از پایان اون محدوده (Scope)، تمام اشیایی که در اون Scope ایجاد شده اند نیز "میمیرند" (در واقع Dispose میشوند و از بین میروند)
البته تمامی این حرف ها "فقط" برای اشیایی صادق است که Lifetime (بازه عمر) آنها به صورت Scope تنظیم شده باشند.
حال جالبه بدونین که IOC Container میاد و در ابتدای یک درخواست وب (Request)، یک Scope ایجاد میکنه و در پایان اون درخواست وب، اون Scope رو از بین میبره (در نتیجه تمام اشیایی آن Scope هم از بین میروند)
در این حالت وقتی ما DbContext رو به صورت Scope (درواقع با Lifetime یا همون بازه عمر برابر با Scope) تعریف میکنیم، اتفاقی که میافته اینه که IOC Container در ابتدای هر درخواست، یک Scope ایجاد میکنه و درنتیجه DbContext ما هم (که قبلا به صورت Scope تنظیم شده است)، فقط و فقط یک نسخه از آن داخل Scope مربوطه (که اول درخواست ساخته شده) ایجاد میشه؛ در نتیجه طی اون Scope ما هر چندبار هم که DbContext رو فراخوانی کنیم، توسط سیستم تزریق وابستگی، "فقط و فقط" همون یک نسخه اولیه به ما ارجاع(پاس) داده میشه و در این حالت الگوی Context Per Request تحقق میابد
در پایان درخواست وب هم، چون Scope مربوطه ازبین میره، تمامی اشیای داخل آن(ایجاد شده توسط آن Scope) نیز از بین میروند از جمله همین DbContext ما و درواقع در پایان درخواست، DbContext ما هم Dispose میشه
اگه میخواین بیشتر با الگوی Unit Of Work اشنا بشین مقاله زیر رو مسعود بهرامی عزیز بخونین
http://refactor.ir/2017/05/11/unit-of-work/
اگه دوست داشین میتونین تعریف خود مارتین فاولر رو هم در مورد Unit Of Work بخونین
https://martinfowler.com/eaaCatalog/unitOfWork.html
@IranAspMvc
توضیحات کامل در مورد الگو های Repository و Unit Of Work و استفاده از اونها به همراه Entity Framework + مزایا و معایب
https://news.1rj.ru/str/IranAspMvc/586
https://news.1rj.ru/str/IranAspMvc/587
https://news.1rj.ru/str/IranAspMvc/588
https://news.1rj.ru/str/IranAspMvc/589
https://news.1rj.ru/str/IranAspMvc/590
*پیشنهاد میکنم همشو بخونین و بعد تصمیم بگیرین
@IranAspMvc
https://news.1rj.ru/str/IranAspMvc/586
https://news.1rj.ru/str/IranAspMvc/587
https://news.1rj.ru/str/IranAspMvc/588
https://news.1rj.ru/str/IranAspMvc/589
https://news.1rj.ru/str/IranAspMvc/590
*پیشنهاد میکنم همشو بخونین و بعد تصمیم بگیرین
@IranAspMvc