✅ آموزش Unit Testing با استفاده از NUnit و Moq بخش دوم: Mocking
در زمینه Unit Testing گاهی اوقات یک Unit یا کلاس وابستگی هایی دارد که مورد بررسی برای تست نیستند. همچنین Unit مورد نظر بدون داشتن این وابستگی ها نمیتواند کار کند. یکی از راه های حل این مشکل، شبیه سازی وابستگی های Unit یا کلاس است که به Mocking معروف می باشد. یکی از کتابخانه های بسیار کاربردی و معروف در زمینه Mocking ، کتابخانه Moq می باشد که در این مقاله قصد داریم به بررسی آن بپردازیم
#بابک_طارمی
https://vrgl.ir/BnMoW
_____________
@DotNetZoom
در زمینه Unit Testing گاهی اوقات یک Unit یا کلاس وابستگی هایی دارد که مورد بررسی برای تست نیستند. همچنین Unit مورد نظر بدون داشتن این وابستگی ها نمیتواند کار کند. یکی از راه های حل این مشکل، شبیه سازی وابستگی های Unit یا کلاس است که به Mocking معروف می باشد. یکی از کتابخانه های بسیار کاربردی و معروف در زمینه Mocking ، کتابخانه Moq می باشد که در این مقاله قصد داریم به بررسی آن بپردازیم
#بابک_طارمی
https://vrgl.ir/BnMoW
_____________
@DotNetZoom
ویرگول
آموزش Unit Testing با استفاده از NUnit و Moq بخش دوم: Mocking
در این مقاله قصد داریم که به Mocking و کتابخانه محبوب Moq بپردازیم
🔰 الان داشتم اینو سرچ میکردم میزارم اینجا هم آرشیو بشه هم شاید به دردتون بخوره
واسه Encode کردن URL راه های مختلفی تو دات نت وجود داره
HttpUtility.UrlPathEncode
HttpUtility.UrlEncode
WebUtility.UrlEncode
Uri.EscapeUriString
Uri.EscapeDataString
🔸داغون ترینشون اینه HttpUtility.UrlPathEncode
اصلا درست کار نمیکنه و خروجی رو خراب میکنه تو بعضی موارد. مثلا % و # رو encode نمیکنه
اینجا یه سری مواردش رو گفته
https://stackoverflow.com/a/1148326
🔹اینم یه سری مشکلات داره Uri.EscapeUriString و جدیدا deprecate شده
تو یه سری موارد خروجی رو خراب میکنه مثلا # رو encode نمیکنه
توضیحات بیشتر
https://stackoverflow.com/a/34189188
🔸این 2تا مثل هم رفتار میکنن و روششون اینطوریه که space رو به "+" تبدیل میکنن. فقط یه تفاوت کوچیک دارن
WebUtility.UrlEncode (حروف UpperCase تولید میکنه)
HttpUtility.UrlEncode (حروف LowerCase تولید میکنه)
🔹این 2تا مشکلی که دارن اینه که یه سری کاراکتر های «رزرو نشده» مثل "~" رو هم encode میکنن
توضیحات بیشتر
https://stackoverflow.com/a/47877559
✅ بهترینشون هم که خروجی کاملا استاندارد تولید میکنه و هیچ کدوم از این مشکلات رو نداره اینه
Uri.EscapeDataString
توضیحات بیشتر
https://stackoverflow.com/questions/602642/server-urlencode-vs-httputility-urlencode/
____________________
@DotNetZoom
واسه Encode کردن URL راه های مختلفی تو دات نت وجود داره
HttpUtility.UrlPathEncode
HttpUtility.UrlEncode
WebUtility.UrlEncode
Uri.EscapeUriString
Uri.EscapeDataString
🔸داغون ترینشون اینه HttpUtility.UrlPathEncode
اصلا درست کار نمیکنه و خروجی رو خراب میکنه تو بعضی موارد. مثلا % و # رو encode نمیکنه
اینجا یه سری مواردش رو گفته
https://stackoverflow.com/a/1148326
🔹اینم یه سری مشکلات داره Uri.EscapeUriString و جدیدا deprecate شده
تو یه سری موارد خروجی رو خراب میکنه مثلا # رو encode نمیکنه
توضیحات بیشتر
https://stackoverflow.com/a/34189188
🔸این 2تا مثل هم رفتار میکنن و روششون اینطوریه که space رو به "+" تبدیل میکنن. فقط یه تفاوت کوچیک دارن
WebUtility.UrlEncode (حروف UpperCase تولید میکنه)
HttpUtility.UrlEncode (حروف LowerCase تولید میکنه)
🔹این 2تا مشکلی که دارن اینه که یه سری کاراکتر های «رزرو نشده» مثل "~" رو هم encode میکنن
توضیحات بیشتر
https://stackoverflow.com/a/47877559
✅ بهترینشون هم که خروجی کاملا استاندارد تولید میکنه و هیچ کدوم از این مشکلات رو نداره اینه
Uri.EscapeDataString
توضیحات بیشتر
https://stackoverflow.com/questions/602642/server-urlencode-vs-httputility-urlencode/
____________________
@DotNetZoom
Stack Overflow
Server.UrlEncode vs. HttpUtility.UrlEncode
Is there a difference between Server.UrlEncode and HttpUtility.UrlEncode?
Forwarded from کدهک
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ نمایش تعداد کاربران آنلاین در AspNet Core
برای محاسبه تعداد کاربران آنلاین اساسا دو روش وجود داره
1️⃣ روش اول - با استفاده از Cookie
در ASP.NET قدیم داخل کلاس global.asax متد هایی وجود داشت به نام Session_Start و Session_End که به هنگام شروع و پایان "سشن" کاربری، فراخوانی میشدن (با شی Session اشتباه گرفته نشود)
رخداد Session_Start زمانی raise یا اجرا میشد که یک سشن جدید برای یک کاربر ساخته بشه
و رخداد Session_End نیز زمانی raise میشد که یک سشن expire (منقضی) بشه
🔰مکانیزمی که سشن کاربری رو ایجاد ومنقضی میکرد، مراحلش به این صورت بود که:
▪️اولین بار که شخصی سایت رو باز میکرد، خود ASP.NET یک کوکی به نام "ASP.NET_SessionD" با مقدار یک "کلید تصادفی" به همراه Response برای کاربر میفرستاد و اون در مرورگر کاربر ذخیره میشد و از اون طرف همین "کلید تصادفی" در حافظه مموری سرور (به کمک شی Session) به عنوان شناسه یک کاربر (که شاید هنوز نمیدونیم کیه ولی میدونیم یه کاربره) ذخیره میشد (تا اینجای کار یک سشن برای کاربر جدید ساخته شده، در نتیجه رخداد Session_Start فراخوانی میشد)
▪️از درخواست های بعدی، این کوکی به همراه مقدارش (همون کلید تصادفی)، به Server ارسال میشد سپس ASP.NET این کلید رو میخوند و با مقادیر ذخیره شده در شی Session (در حافظه رم) مطابقت میداد و متوجه میشد که این همون کاربری هست که قبلا درخواست زده بود.
تایم منقضی شدن این سشن ها (session expire) به صورت پیشفرض 20 دقیقه بود و مادامی که درخواست یا بازدید از سمت همون کاربر میومد، این مدت زمان تمدید میشد.
در نتیجه مادامی که آخرین درخواست کاربر کمتر از 20 دقیقه قبل بود، سشن برقرار بود و زمانی که این مدت از 20 بیشتر میشد. اون سشن به صورت خودکار expire/منقضی میشد (در این مرحله رخداد Session_End فراخوانی میشد)
🔸بنابراین مادامی که کاربر ما، فاصله بین هر درخواستش کمتر از 20 دقیقه بود، سشن اون کاربر برقرار بود و یک کاربر "آنلاین" به حساب میومد
و زمانی که از آخرین درخواست کاربر، بیش از 20 دقیقه میگذشت، سشن کاربر منقضی شده و یک کاربر "آفلاین" به حساب میومد
در این حالت با کمی کد نویسی میشد تعداد کاربران آنلاین رو محاسبه کرد، به این صورت که یک متغیر global برای تعداد کاربران آنلاین در نظر میگرفتیم و به هنگام Session_Start اون رو ++ (یکی اضافه) و به هنگام Session_End اون رو -- (یکی کم) میکردیم
نکته: این توضیحات حالت پیشفرض هست، در صورت تنظیم sessionState میتونه محل ذخیره سازی سشن و کوکی در سمت سرور و کلاینت متفاوت باشه (مثلا ذخیره شدن سشن ها درون یک دیتابیس SqlServer به جای Memory یا تنظیم شدن کلید تصادفی درون URL به جای کوکی) - توضیحات بیشتر
🔹در ASP.NET Core اما این مکانیزم و این دو متد دیگه وجود نداره. پس مجبوریم مشابه همین مکانیزم رو خودمون کدنویسی و طراحی کنیم. کد نویسیش کار خاصی نداره، همین مراحل ساخت کوکی با یک "کلید تصادفی" (مثلا guid) و ذخیره اون علاوه بر Response، درون یک InMemory Cache داخل یک Middleware به سادگی انجام میشه
🔸در این روش چون فاصله زمانی 20 دقیقه رو برای session expire هست در نتیجه همیشه ما یک تلورانس و اختلاف 20 دقیقه ای ممکنه داشته باشیم. اگر کاربر جاری همین الان مرورگرش رو میبنده یا برق میره چون session اش تا 20 دقیقه از آخرین بازدیدش معتبر هست، همچنان تا 20 دقیقه آینده "آنلاین" محسوب میشه
2️⃣ روش دوم - با استفاده از ارتباطات Realtime مانند SignalR
🔹این روش خیلی مشابه روش قبل هست با این تفاوت که به محض برقرار شدن اتصال کاربر (رخداد OnConnectedAsync کلاس Hub) اون رو به عنوان کاربر آنلاین و به محض قطع شدن ارتباطش (رخداد OnDisconnectedAsync کلاس Hub) اون کاربر رو آفلاین در نظر میگیریم.
بقیه موارد ساخت کلید تصادفی و تنظیم کوکی جهت تشخیص کاربر از بقیه کاربر ها تقریبا مشابه قبل هست
🔸مزیت این روش اینه که دیگه ما تلورانس و اختلاف 20 دقیقه رو نخواهیم داشت و به صورت آنی و در لحظه تعداد کاربران آنلاین بروزرسانی خواهد شد
معایبش هم اینه که به دلیل استفاده از ارتباطات realtime پردازش بیشتری نسبت به روش اول روی سرور میوفته و یا اینکه امکان استفاده از ارتباطات realtime در برنامه شما به هر دلیل از جمله زیرساخت network یا محدودیت های سرور و application شما وجود نداشته باشه
🔹نکته آخر اینکه در اینجا سعی کردم مکانیزم خیلی ساده توضیح بدم اما پیاده سازی صحیح چنین مکانیزمی با توجه به امکان وقوع همزمانی مستلزم اینه که نکات پیشگیری از مشکلات همزمانی رعایت بشه
🔰در اینجا یک پروژه نمونه آماده کردم که هر دو این روش ها رو پیاده سازی کرده و میتونین با بررسی سورس کدش بیشتر با نحوه عملکرد اون آشنا بشین
https://github.com/dotnetzoom/OnlineUsers-AspNetCore
_________
@DotNetZoom
برای محاسبه تعداد کاربران آنلاین اساسا دو روش وجود داره
1️⃣ روش اول - با استفاده از Cookie
در ASP.NET قدیم داخل کلاس global.asax متد هایی وجود داشت به نام Session_Start و Session_End که به هنگام شروع و پایان "سشن" کاربری، فراخوانی میشدن (با شی Session اشتباه گرفته نشود)
رخداد Session_Start زمانی raise یا اجرا میشد که یک سشن جدید برای یک کاربر ساخته بشه
و رخداد Session_End نیز زمانی raise میشد که یک سشن expire (منقضی) بشه
🔰مکانیزمی که سشن کاربری رو ایجاد ومنقضی میکرد، مراحلش به این صورت بود که:
▪️اولین بار که شخصی سایت رو باز میکرد، خود ASP.NET یک کوکی به نام "ASP.NET_SessionD" با مقدار یک "کلید تصادفی" به همراه Response برای کاربر میفرستاد و اون در مرورگر کاربر ذخیره میشد و از اون طرف همین "کلید تصادفی" در حافظه مموری سرور (به کمک شی Session) به عنوان شناسه یک کاربر (که شاید هنوز نمیدونیم کیه ولی میدونیم یه کاربره) ذخیره میشد (تا اینجای کار یک سشن برای کاربر جدید ساخته شده، در نتیجه رخداد Session_Start فراخوانی میشد)
▪️از درخواست های بعدی، این کوکی به همراه مقدارش (همون کلید تصادفی)، به Server ارسال میشد سپس ASP.NET این کلید رو میخوند و با مقادیر ذخیره شده در شی Session (در حافظه رم) مطابقت میداد و متوجه میشد که این همون کاربری هست که قبلا درخواست زده بود.
تایم منقضی شدن این سشن ها (session expire) به صورت پیشفرض 20 دقیقه بود و مادامی که درخواست یا بازدید از سمت همون کاربر میومد، این مدت زمان تمدید میشد.
در نتیجه مادامی که آخرین درخواست کاربر کمتر از 20 دقیقه قبل بود، سشن برقرار بود و زمانی که این مدت از 20 بیشتر میشد. اون سشن به صورت خودکار expire/منقضی میشد (در این مرحله رخداد Session_End فراخوانی میشد)
🔸بنابراین مادامی که کاربر ما، فاصله بین هر درخواستش کمتر از 20 دقیقه بود، سشن اون کاربر برقرار بود و یک کاربر "آنلاین" به حساب میومد
و زمانی که از آخرین درخواست کاربر، بیش از 20 دقیقه میگذشت، سشن کاربر منقضی شده و یک کاربر "آفلاین" به حساب میومد
در این حالت با کمی کد نویسی میشد تعداد کاربران آنلاین رو محاسبه کرد، به این صورت که یک متغیر global برای تعداد کاربران آنلاین در نظر میگرفتیم و به هنگام Session_Start اون رو ++ (یکی اضافه) و به هنگام Session_End اون رو -- (یکی کم) میکردیم
نکته: این توضیحات حالت پیشفرض هست، در صورت تنظیم sessionState میتونه محل ذخیره سازی سشن و کوکی در سمت سرور و کلاینت متفاوت باشه (مثلا ذخیره شدن سشن ها درون یک دیتابیس SqlServer به جای Memory یا تنظیم شدن کلید تصادفی درون URL به جای کوکی) - توضیحات بیشتر
🔹در ASP.NET Core اما این مکانیزم و این دو متد دیگه وجود نداره. پس مجبوریم مشابه همین مکانیزم رو خودمون کدنویسی و طراحی کنیم. کد نویسیش کار خاصی نداره، همین مراحل ساخت کوکی با یک "کلید تصادفی" (مثلا guid) و ذخیره اون علاوه بر Response، درون یک InMemory Cache داخل یک Middleware به سادگی انجام میشه
🔸در این روش چون فاصله زمانی 20 دقیقه رو برای session expire هست در نتیجه همیشه ما یک تلورانس و اختلاف 20 دقیقه ای ممکنه داشته باشیم. اگر کاربر جاری همین الان مرورگرش رو میبنده یا برق میره چون session اش تا 20 دقیقه از آخرین بازدیدش معتبر هست، همچنان تا 20 دقیقه آینده "آنلاین" محسوب میشه
2️⃣ روش دوم - با استفاده از ارتباطات Realtime مانند SignalR
🔹این روش خیلی مشابه روش قبل هست با این تفاوت که به محض برقرار شدن اتصال کاربر (رخداد OnConnectedAsync کلاس Hub) اون رو به عنوان کاربر آنلاین و به محض قطع شدن ارتباطش (رخداد OnDisconnectedAsync کلاس Hub) اون کاربر رو آفلاین در نظر میگیریم.
بقیه موارد ساخت کلید تصادفی و تنظیم کوکی جهت تشخیص کاربر از بقیه کاربر ها تقریبا مشابه قبل هست
🔸مزیت این روش اینه که دیگه ما تلورانس و اختلاف 20 دقیقه رو نخواهیم داشت و به صورت آنی و در لحظه تعداد کاربران آنلاین بروزرسانی خواهد شد
معایبش هم اینه که به دلیل استفاده از ارتباطات realtime پردازش بیشتری نسبت به روش اول روی سرور میوفته و یا اینکه امکان استفاده از ارتباطات realtime در برنامه شما به هر دلیل از جمله زیرساخت network یا محدودیت های سرور و application شما وجود نداشته باشه
🔹نکته آخر اینکه در اینجا سعی کردم مکانیزم خیلی ساده توضیح بدم اما پیاده سازی صحیح چنین مکانیزمی با توجه به امکان وقوع همزمانی مستلزم اینه که نکات پیشگیری از مشکلات همزمانی رعایت بشه
🔰در اینجا یک پروژه نمونه آماده کردم که هر دو این روش ها رو پیاده سازی کرده و میتونین با بررسی سورس کدش بیشتر با نحوه عملکرد اون آشنا بشین
https://github.com/dotnetzoom/OnlineUsers-AspNetCore
_________
@DotNetZoom
Telegram
Attach Files
Forwarded from کدهک
✅ تولید تگ های SEO در ASPNET Core با کتابخانه SeoTags
تگ های زیاد و متنوعی برای بهبود SEO سایت وجود دارند. از انواع meta و link گرفته تا تگ های تنظیم Twitter Card و Open Graph تا JSON-LD و Microdata برای Structred Data تا SiteMap و...
هرکدوم هم مسلما مقادیر خاص خودشون رو میپذیرن و بسته به شرایط و نوع محتوا متفاوت هستند.
کتابخانه SeoTags تمامی تگ های مهم و کاربردی رو براحتی برای وبسایت ASPNET Core ایی شما میسازه و حالت ها و تگ های زیادی هم پشتیبانی میکنه.
اینو کتابخونه رو تازگی نوشتم (در جهت راه اندازی سایت DotNetZoom) و به زودی تکمیل ترش هم میکنم.
شما هم اگه دوست داشتین توش مشارکت کنین، issue بزنین و pull request بفرستین
طریقه استفاده و نمونه خروجی تگ ها رو میتونین توی ریپازیتوری مشاهده کنین
https://github.com/mjebrahimi/SeoTags
___________________
@DotNetZoom
تگ های زیاد و متنوعی برای بهبود SEO سایت وجود دارند. از انواع meta و link گرفته تا تگ های تنظیم Twitter Card و Open Graph تا JSON-LD و Microdata برای Structred Data تا SiteMap و...
هرکدوم هم مسلما مقادیر خاص خودشون رو میپذیرن و بسته به شرایط و نوع محتوا متفاوت هستند.
کتابخانه SeoTags تمامی تگ های مهم و کاربردی رو براحتی برای وبسایت ASPNET Core ایی شما میسازه و حالت ها و تگ های زیادی هم پشتیبانی میکنه.
اینو کتابخونه رو تازگی نوشتم (در جهت راه اندازی سایت DotNetZoom) و به زودی تکمیل ترش هم میکنم.
شما هم اگه دوست داشتین توش مشارکت کنین، issue بزنین و pull request بفرستین
طریقه استفاده و نمونه خروجی تگ ها رو میتونین توی ریپازیتوری مشاهده کنین
https://github.com/mjebrahimi/SeoTags
___________________
@DotNetZoom
GitHub
GitHub - mjebrahimi/SeoTags: 🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph…
🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph (for Facebook) (og:), and JSON-LD schema (structured data). - mjebrahimi/SeoTags
✅ تصاویر پس زمینه Windows 11
دسکتاپ تون رو صفا بدین :)
https://www.windowsobserver.com/dwnld/38638/
_____________________
@DotNetZoom
دسکتاپ تون رو صفا بدین :)
https://www.windowsobserver.com/dwnld/38638/
_____________________
@DotNetZoom
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
❇️ فرق Task.Run با Task.Factory.StartNew
در این سری پست های #پرسش_پاسخ قصد دارم بعضی از سوالاتی که دوستان میپرسند رو به همراه جواب هاشون برای شما به اشتراک بگذارم
🔸سوال:
فرق Task.Run با Task.Factory.StartNew چیه؟ از کدومشون باید استفاده کنیم؟
🔹پاسخ:
خود Task.Run پشت پرده از Task.Factory.StartNew استفاده میکنه و در واقع یه Wrapper روی اون هست که استفاده ازش رو ساده تر میکنه.
علتش اینه که Task.Factory.StartNew امضا (overload) های متفاوتی داره که کار با اون رو انعطاف پذیر تر میکنه که همین انعطاف پذیری بیشتر باعث شده کار باهاش پیچیده تر باشه. مثلا وجود آپشن های بیشتری از جمله TaskCreationOptions و TaskScheduler که اجازه میده سفارشی سازی بیشتری انجام بدیم.
همچنین با توجه به اینکه خروجی متد StartNew از نوع <Task<T هست، این نوع جنریک T درواقع خروجی همون delegate ایی که بهش پاس میدین. درنتیجه اگر delegate ورودی شما به متد StartNew، خودش از نوع Task باشه، خروجی نهایی متد StartNew میشه یک <Task<Task که در این حالت بایستی توسط متد Unwarp، اون تسک داخلی (inner task) رو بیرون بکشید و با اون کار بکنید
از این رو تیم دات نت به جهت جلوگیری و مخفی کردن این پیچیدگی ها اومده Task.Run رو برای سناریو های پرکاربرد ایجاد کرده که این پیچیدگی ها رو داخل خودش مخفی میکنه
جمع بندی اینکه همیشه از Task.Run به جای Task.Factory.StartNew استفاده کنید مگر اینکه نیاز به سفارشی سازی یا استفاده از حالت های خاص دارید (اون هم با آگاهی کامل) که توضیحش از حوصله این سوال خارجه
جهت اطلاعات بیشتر مطالعه لینک زیر کمکتون میکنه
▪️Task.Run vs Task.Factory.StartNew
🔸حالا که تا اینجای کار اومدید جا داره یه نکته دیگه هم بگم
علاوه بر روش های بالا 2 روش دیگه برای ساخت یک Task وجود داره.
1- نمونه سازی تسک توسط سازنده کلاس Task
2- استفاده از کلاس TaskCompletionSource
این دو روش کمتر عمومی بوده و معمولا نیاز نمیشه از این ها استفاده کنید. روش اول بسیار کم کاربرد هست و use-case های خاصی داره و باید با احتیاط و آگاهی ازش استفاده کنین.
وقتی شما توسط Task.Run یا Task.Factory.StartNew استفاده میکنید، یک تسک برای شما ساخته میشه و بلافاصله Start میشه. درنتیحه Task ایی که به دست شما میرسه از قبل start شده و فراخوانی مجدد متد Start روی اون، باعث وقوع Exception میشه
ولی وقتی توسط سازنده کلاس Task استفاده میکنید میتونین قبل از Start شدنش به اون نمونه ایجاد شده دسترسی پیدا کنین. و سپس باید به صورت دستی متد Start رو فراخوانی کنین تا Task اجرا بشه. هرچند فراخوانی دستی متد Start بدلیل Synchronization ایی که در پشت صحنه اعمال میشه (به دلیل جلوگیری از Start شدن همزمان توسط چندین Thread) دارای سربار هست
کلاس TaskCompletionSource اما مکانیزمش کلا فرق میکنه. این کلاس وظیفه ساخت "و مدیریت" چرخه حیات یک Task رو به عهده داره.
مثلا توسط متد های SetResult و SetException و SetCanceled (و نیز همین متد ها با پشوند TryXXX به جهت مدیریت همزمانی) این امکان رو به شما میده وضعیت تسک رو به یکی از این حالات تغییر بدید:
"کنسل شده" یا "خطا رخ داده" یا "تکمیل شده با موفقیت (به همراه نتیجه خروجی اون)"
از این روش معمولا برای تبدیل کد های قدیمی APM و EAP به TPL (روش جدید تر و توصیه شده مایکروسافت) استفاده میشه و یه use-case های خاصی که باید با احتیاط و آگاهی از استفاده بشه
اطلاعات بیشتر:
▪️Mechanisms for Creating Tasks
▪️The Nature of TaskCompletionSource
▪️The danger of TaskCompletionSource class
___________________
@DotNetZoom
در این سری پست های #پرسش_پاسخ قصد دارم بعضی از سوالاتی که دوستان میپرسند رو به همراه جواب هاشون برای شما به اشتراک بگذارم
🔸سوال:
فرق Task.Run با Task.Factory.StartNew چیه؟ از کدومشون باید استفاده کنیم؟
🔹پاسخ:
خود Task.Run پشت پرده از Task.Factory.StartNew استفاده میکنه و در واقع یه Wrapper روی اون هست که استفاده ازش رو ساده تر میکنه.
علتش اینه که Task.Factory.StartNew امضا (overload) های متفاوتی داره که کار با اون رو انعطاف پذیر تر میکنه که همین انعطاف پذیری بیشتر باعث شده کار باهاش پیچیده تر باشه. مثلا وجود آپشن های بیشتری از جمله TaskCreationOptions و TaskScheduler که اجازه میده سفارشی سازی بیشتری انجام بدیم.
همچنین با توجه به اینکه خروجی متد StartNew از نوع <Task<T هست، این نوع جنریک T درواقع خروجی همون delegate ایی که بهش پاس میدین. درنتیجه اگر delegate ورودی شما به متد StartNew، خودش از نوع Task باشه، خروجی نهایی متد StartNew میشه یک <Task<Task که در این حالت بایستی توسط متد Unwarp، اون تسک داخلی (inner task) رو بیرون بکشید و با اون کار بکنید
از این رو تیم دات نت به جهت جلوگیری و مخفی کردن این پیچیدگی ها اومده Task.Run رو برای سناریو های پرکاربرد ایجاد کرده که این پیچیدگی ها رو داخل خودش مخفی میکنه
جمع بندی اینکه همیشه از Task.Run به جای Task.Factory.StartNew استفاده کنید مگر اینکه نیاز به سفارشی سازی یا استفاده از حالت های خاص دارید (اون هم با آگاهی کامل) که توضیحش از حوصله این سوال خارجه
جهت اطلاعات بیشتر مطالعه لینک زیر کمکتون میکنه
▪️Task.Run vs Task.Factory.StartNew
🔸حالا که تا اینجای کار اومدید جا داره یه نکته دیگه هم بگم
علاوه بر روش های بالا 2 روش دیگه برای ساخت یک Task وجود داره.
1- نمونه سازی تسک توسط سازنده کلاس Task
2- استفاده از کلاس TaskCompletionSource
این دو روش کمتر عمومی بوده و معمولا نیاز نمیشه از این ها استفاده کنید. روش اول بسیار کم کاربرد هست و use-case های خاصی داره و باید با احتیاط و آگاهی ازش استفاده کنین.
وقتی شما توسط Task.Run یا Task.Factory.StartNew استفاده میکنید، یک تسک برای شما ساخته میشه و بلافاصله Start میشه. درنتیحه Task ایی که به دست شما میرسه از قبل start شده و فراخوانی مجدد متد Start روی اون، باعث وقوع Exception میشه
ولی وقتی توسط سازنده کلاس Task استفاده میکنید میتونین قبل از Start شدنش به اون نمونه ایجاد شده دسترسی پیدا کنین. و سپس باید به صورت دستی متد Start رو فراخوانی کنین تا Task اجرا بشه. هرچند فراخوانی دستی متد Start بدلیل Synchronization ایی که در پشت صحنه اعمال میشه (به دلیل جلوگیری از Start شدن همزمان توسط چندین Thread) دارای سربار هست
کلاس TaskCompletionSource اما مکانیزمش کلا فرق میکنه. این کلاس وظیفه ساخت "و مدیریت" چرخه حیات یک Task رو به عهده داره.
مثلا توسط متد های SetResult و SetException و SetCanceled (و نیز همین متد ها با پشوند TryXXX به جهت مدیریت همزمانی) این امکان رو به شما میده وضعیت تسک رو به یکی از این حالات تغییر بدید:
"کنسل شده" یا "خطا رخ داده" یا "تکمیل شده با موفقیت (به همراه نتیجه خروجی اون)"
از این روش معمولا برای تبدیل کد های قدیمی APM و EAP به TPL (روش جدید تر و توصیه شده مایکروسافت) استفاده میشه و یه use-case های خاصی که باید با احتیاط و آگاهی از استفاده بشه
اطلاعات بیشتر:
▪️Mechanisms for Creating Tasks
▪️The Nature of TaskCompletionSource
▪️The danger of TaskCompletionSource class
___________________
@DotNetZoom
Microsoft News
Task.Run vs Task.Factory.StartNew
In .NET 4, Task.Factory.StartNew was the primary method for scheduling a new task. Many overloads provided for a highly configurable mechanism, enabling setting options, passing in arbitrary state, enabling cancellation, and even controlling scheduling behaviors. …
✅ گفتگو درباره Distributed Tracing در علی بابا تاک
آکادمی علیبابا، در سری برنامههای علیباباتاک، به بیان چالشها و تجربیات علیباباییها و دنیای کار میپردازه.
در این ارائه، معین تاجیک و مسعود دانشپور، درباره این موضوع صحبت خواهند کرد که چطور میتوان با استفاده از مفاهیم Open Tracing و Open Telemetry، در بین مایکروسرویسهای مختلف، درخواستهای کاربران را شناسایی و تمامی اطلاعات مفیدی که باعث بهبود روند Tracing، Debugging و شناسایی Performance Pitfall ها میشود را به وسیله پروتکلهای استاندارد و همچنین با استفاده از ابزارهای موجود در بازار جمع آوری و مانیتور کرد.
🔸زمان: سهشنبه ۲۹ تیر، ساعت ۱۷:۰۰ تا ۱۸:۳۰
🔸ثبت نام رایگان از طریق لینک زیر:
https://evnd.co/FmdPz
_________________
@DotNetZoom
آکادمی علیبابا، در سری برنامههای علیباباتاک، به بیان چالشها و تجربیات علیباباییها و دنیای کار میپردازه.
در این ارائه، معین تاجیک و مسعود دانشپور، درباره این موضوع صحبت خواهند کرد که چطور میتوان با استفاده از مفاهیم Open Tracing و Open Telemetry، در بین مایکروسرویسهای مختلف، درخواستهای کاربران را شناسایی و تمامی اطلاعات مفیدی که باعث بهبود روند Tracing، Debugging و شناسایی Performance Pitfall ها میشود را به وسیله پروتکلهای استاندارد و همچنین با استفاده از ابزارهای موجود در بازار جمع آوری و مانیتور کرد.
🔸زمان: سهشنبه ۲۹ تیر، ساعت ۱۷:۰۰ تا ۱۸:۳۰
🔸ثبت نام رایگان از طریق لینک زیر:
https://evnd.co/FmdPz
_________________
@DotNetZoom
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
❇️ تفاوت Event و Delegate و مشکل نشتی حافظه (Memory Leaks) در کار با Event ها
در این پست ابتدا به تفاوت های event و delegate می پردازیم و سپس علت مشکل نشتی حافظه رو به هنگام استفاده از اون ها بررسی میکنیم (سوالی که ممکنه بعضا توی مصاحبه باهاش برخورد کرده باشین)
🔸در ابتدا باید بگم که این دو خیلی شبیه به هم هستند
1- هر دو میتونن باعث memory leak بشن
2- هر دو این امکان رو دارن که با =+ و =- بشه چندتا متد رو بهشون اضافه یا کم کرد
3- هر دو موقع raise شدن (اجرا شدن)، تمام متد های ثبت شده داخل خودشون رو فراخوانی میکنن
🔹و اما تفاوت های اونها چیه؟
در واقع event یک abstraction بر روی delegate هست که یک سری محدودیت ها (بهتره بگیم محافظت ها) رو روش اعمال میکنه
1- اجازه نمیده event رو ریست کنین (یعنی فقط اجازه میده با += و -= متدی بهش اضافه یا کم کنین ولی اجازه نمیده که با = مقدارش رو ریست کنین)
2- اون event رو فقط از طریق داخل کلاس شامل شوندش قابل فراخوانی میکنه یعنی از بیرون کسی نمیتونه اون event رو فراخوانی کنه
🔸بررسی مشکل نشتی حافظه در Event و Delegate
احتمالا خیلی جا ها دیدید یا شنیدید که میگن event ها میتونن باعث نشتی حافظه بشن. اما این مورد محدود به event نیست؛ برای delegate ها هم میتونه اتفاق بیافته. حتی برای یک شی استاتیک هم میتونه اتفاق بیافته. در واقع علت اصلی این مشکل مربوط به باقی ماندن رفرنس اشیای «بلا استفاده» هست
فرض کنین یه کلاس static داریم که داخلش یه لیست static هست. طبیعتا طول عمر این لیست به دلیل static بودن تا پایان عمر application باقی خواهد ماند، در نتیجه GC (مخفف Garbage Collector)، اون لیست رو Dispose نمیکنه
حالا اگر در طول برنامه اشیایی رو درون اون لیست Add کنیم عملا چون رفرنس اون اشیا داخل لیست باقی میمونن، اون اشیا هم تا پایان عمر برنامه Dispose نمیشن (حتی اگه دیگه با اون اشیا کاری نداشته باشیم) و همین عامل هست که باعث Memory Leak میشه
حالا مشابه همین اتفاق میتونه برای event ها و delegate ها هم بیافته
در واقع وقتی متدی از یک شی رو به یک event یا delegate (مانند Action و Func) توسط = یا =+ نسبت میدین، رفرنس اون شی هم Capture میشه، در نتیجه تا پایان عمر اون event یا delegate مربوطه، اون اشیاء هم باقی میمونن و Dispose نمیشن
🔹برای رفع این مشکل راه حل های مختلفی هست
1️⃣ استفاده از -= برای حذف کردن رفرنس (unsubscribe کردن) اون متد از event یا delegate مربوطه
2️⃣ استفاده از الگوی Weak Reference Pattern که توسط کلاس WeakEventHandler دات نت پیاده سازی میشه
3️⃣ استفاده از الگوی Event Aggregator Pattern که اون هم به نوعی از Weak Reference استفاده میکنه و داخل کتابخونه Prism زیاد ازش استفاده شده
و روش های دیگه که خارج از توضیح این پست هست
🔰جهت اطلاعات بیشتر و روش های جلوگیری از نشتی حافظه پیشنهاد میکنم مقالات زیر رو مطالعه کنین
✔️5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
✔️Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators
✔️Memory Leak in C#
✔️Are you afraid of event handlers because of C# memory leak?
✔️Events: Demystifying Common Memory Leaks
✔️Weak Event Patterns
_________________
@DotNetZoom
در این پست ابتدا به تفاوت های event و delegate می پردازیم و سپس علت مشکل نشتی حافظه رو به هنگام استفاده از اون ها بررسی میکنیم (سوالی که ممکنه بعضا توی مصاحبه باهاش برخورد کرده باشین)
🔸در ابتدا باید بگم که این دو خیلی شبیه به هم هستند
1- هر دو میتونن باعث memory leak بشن
2- هر دو این امکان رو دارن که با =+ و =- بشه چندتا متد رو بهشون اضافه یا کم کرد
3- هر دو موقع raise شدن (اجرا شدن)، تمام متد های ثبت شده داخل خودشون رو فراخوانی میکنن
🔹و اما تفاوت های اونها چیه؟
در واقع event یک abstraction بر روی delegate هست که یک سری محدودیت ها (بهتره بگیم محافظت ها) رو روش اعمال میکنه
1- اجازه نمیده event رو ریست کنین (یعنی فقط اجازه میده با += و -= متدی بهش اضافه یا کم کنین ولی اجازه نمیده که با = مقدارش رو ریست کنین)
2- اون event رو فقط از طریق داخل کلاس شامل شوندش قابل فراخوانی میکنه یعنی از بیرون کسی نمیتونه اون event رو فراخوانی کنه
🔸بررسی مشکل نشتی حافظه در Event و Delegate
احتمالا خیلی جا ها دیدید یا شنیدید که میگن event ها میتونن باعث نشتی حافظه بشن. اما این مورد محدود به event نیست؛ برای delegate ها هم میتونه اتفاق بیافته. حتی برای یک شی استاتیک هم میتونه اتفاق بیافته. در واقع علت اصلی این مشکل مربوط به باقی ماندن رفرنس اشیای «بلا استفاده» هست
فرض کنین یه کلاس static داریم که داخلش یه لیست static هست. طبیعتا طول عمر این لیست به دلیل static بودن تا پایان عمر application باقی خواهد ماند، در نتیجه GC (مخفف Garbage Collector)، اون لیست رو Dispose نمیکنه
حالا اگر در طول برنامه اشیایی رو درون اون لیست Add کنیم عملا چون رفرنس اون اشیا داخل لیست باقی میمونن، اون اشیا هم تا پایان عمر برنامه Dispose نمیشن (حتی اگه دیگه با اون اشیا کاری نداشته باشیم) و همین عامل هست که باعث Memory Leak میشه
حالا مشابه همین اتفاق میتونه برای event ها و delegate ها هم بیافته
در واقع وقتی متدی از یک شی رو به یک event یا delegate (مانند Action و Func) توسط = یا =+ نسبت میدین، رفرنس اون شی هم Capture میشه، در نتیجه تا پایان عمر اون event یا delegate مربوطه، اون اشیاء هم باقی میمونن و Dispose نمیشن
🔹برای رفع این مشکل راه حل های مختلفی هست
1️⃣ استفاده از -= برای حذف کردن رفرنس (unsubscribe کردن) اون متد از event یا delegate مربوطه
2️⃣ استفاده از الگوی Weak Reference Pattern که توسط کلاس WeakEventHandler دات نت پیاده سازی میشه
3️⃣ استفاده از الگوی Event Aggregator Pattern که اون هم به نوعی از Weak Reference استفاده میکنه و داخل کتابخونه Prism زیاد ازش استفاده شده
و روش های دیگه که خارج از توضیح این پست هست
🔰جهت اطلاعات بیشتر و روش های جلوگیری از نشتی حافظه پیشنهاد میکنم مقالات زیر رو مطالعه کنین
✔️5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
✔️Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators
✔️Memory Leak in C#
✔️Are you afraid of event handlers because of C# memory leak?
✔️Events: Demystifying Common Memory Leaks
✔️Weak Event Patterns
_________________
@DotNetZoom
Michael's Coding Spot
5 Techniques to avoid Memory Leaks by Events in C# .NET you should know
Event registrations in C# (and .NET in general) are the most common cause of memory leaks. At least from my experience. In fact, I saw so much memory leaks from events that seeing += in code immediately makes me suspicious.
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ رایگان کردن مقالات سایت Medium با افزونه Medium Unlimited
مقالات خوبی تو سایت مدیوم وجود داره ولی بعضا این رایگان نبودن و قفل شدن مقالاتش رو مخه
هرچند که میشه با یه پنجره Incognito تو کروم (یا InPrivate تو مرورگر Edge) اون رو باز کرد و به رایگان استفاده کرد ولی بازم رو مخه
خلاصه اینکه اگه این قضیه رو مخ شما هم هست، راه حلش خیلی سادس؛ استفاده از فزونه Medium Unlimited
این افزونه به مدت نامحدود، مقالات سایت مدیوم رو واستون رایگان میکنه.
🔹برای مروگر FireFox میتونین توسط این لینک نصبش کنین
🔸ولی برای مروگر های Chrome و Edge جدید (که بر پایه موتور کروم هست) از طریق Web Store کروم قابل نصب نیست و باید دستی نصبش کنین.
برای این کار ابتدا:
1-فایل افزونه رو از مخزن گیتهاب پروژه دانلود کنید و فایل zip اش رو تو یه مسیری extract کنین
2- از قسمت منو گزینه Extensions رو انتخاب کنین و سپس توی صفحه ای که میاد، تیک گزینه Developer Mode رو فعال کنین
3- روی دکمه Load Unpacked کلیک کنین و مسیر پوشه افزونه که قبلا extract کردین رو بهش بدین
4- تمام، لذتشو ببرین
🔰ریپازیتوری پروژه:
https://github.com/manojVivek/medium-unlimited
____________________
@DotNetZoom
مقالات خوبی تو سایت مدیوم وجود داره ولی بعضا این رایگان نبودن و قفل شدن مقالاتش رو مخه
هرچند که میشه با یه پنجره Incognito تو کروم (یا InPrivate تو مرورگر Edge) اون رو باز کرد و به رایگان استفاده کرد ولی بازم رو مخه
خلاصه اینکه اگه این قضیه رو مخ شما هم هست، راه حلش خیلی سادس؛ استفاده از فزونه Medium Unlimited
این افزونه به مدت نامحدود، مقالات سایت مدیوم رو واستون رایگان میکنه.
🔹برای مروگر FireFox میتونین توسط این لینک نصبش کنین
🔸ولی برای مروگر های Chrome و Edge جدید (که بر پایه موتور کروم هست) از طریق Web Store کروم قابل نصب نیست و باید دستی نصبش کنین.
برای این کار ابتدا:
1-فایل افزونه رو از مخزن گیتهاب پروژه دانلود کنید و فایل zip اش رو تو یه مسیری extract کنین
2- از قسمت منو گزینه Extensions رو انتخاب کنین و سپس توی صفحه ای که میاد، تیک گزینه Developer Mode رو فعال کنین
3- روی دکمه Load Unpacked کلیک کنین و مسیر پوشه افزونه که قبلا extract کردین رو بهش بدین
4- تمام، لذتشو ببرین
🔰ریپازیتوری پروژه:
https://github.com/manojVivek/medium-unlimited
____________________
@DotNetZoom
addons.mozilla.org
Medium Unlimited: Read for free – Get this Extension for 🦊 Firefox (en-US)
Download Medium Unlimited: Read for free for Firefox. Unlocks medium.com for unlimited reads, no membership required
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ مفهوم Expression Tree در دات نت
میشه گفت یکی از advanced ترین قسمت های دات نت، مفهوم Expression Tree و کلاس Expression هست که یه جورایی قلب IQueryable رو هم تشکیل میده
شاید نهایت استفاده افراد، کار با <<Expression<Func برای شرط های predicate بر روی متد Where و یا selector برای متد Select باشه
ولی Expression خیلی بزرگتر از اینهاست
🔸درواقع مفهوم Expression Tree به مجموعه از از node ها در قالب یک ساختار درختی گفته میشه که هر node اون، خود یک Expression هست. اما خود Expression چیه؟
درواقع هر Expression یک operation (عملیات) برنامه نویسی رو بیان میکنه. توسط کلاس Expression در دات نت میتوان برای هر عملیات برنامه نویسی یک expression ساخت.
🔹به عنوان مثال:
- تعریف یک variable (متغیر)، constant یا parameter (پارامتر ورودی متد)
- انتصاب یک مقدار به یک variable یا parameter
- جمع، تفریق، ضرب، تقسیم و... کردن دو مقدار
- تعریف یک شرط (if/else) یا سویچ (switch) منطقی
- تعریف یک حلقه (for یا while)
- بازگرداندن (return کردن) خروجی متد
- فراخوانی یک متد، پاس دادن پارامتر های ورودی و گرفتن مقدار خروجی
- و... اکثر کار هایی که شما توسط کد نویسی میتونین انجام بدین
🔸فرق expression با کد نویسی معمولی برای operation های برنامه نویسی اینه که توسط Expression میتوان یک ساختار (data structure) قابل توصیف برای کد ها ایجاد کرد.
در نتیجه میتوان از روی این ساختار قابل توصیف، کار های متفاوت و خلاقانه ای انجام داد. مثلا میشه از روی ساختار کد هامون Transpilation انجام بدیم و کوئری (مثلا SQL) معادل اون رو تولید کرد.
🔹در واقع هنگامی که شما یک عبارت lambda رو به یکی از متد های linq که ورودی <Expression<Func داره پاس میدین، پشت صحنه به هنگام Compile یک LambdaExpression از روی عبارت lambda شما ساخته میشه و اون هست که به متد شما پاس داده میشه.
چرا؟ چون که ساختار کد شما رو لازم داره تا بتونه از روی اون Transpilation انجام بده و کوئری (مثلا SQL) معادل اون رو تولید کنه. (این مثال رو ببینید)
🔸یا حتی میتوان به کمک Transpilation، از روی یک expression یک عبارت readable (خوانا) جهت توصیف کاری که قراره انجام بده تولید کرد. همانند کاری که کتابخانه ReadableExpressions کرده و توسط افزونه ویژوال استادیو ReadableExpressions.Visualizers این امکان رو میده که به هنگام دیباگ بتونین یک readable view از روی expression هاتون ببینید
🔹کار دیگه ای که توسط Expression میشه انجام داد. تولید کد IL (مخفف Intermediate Language) از روی اون هست. مثلا شما نمیتونین توسط Reflection حتی، یک متد جدید (شامل مجمومه ای از operation ها) ایجاد کنین ولی توسط Expression میتونین به جای اینکه کد شما به هنگام compile تبدیل به IL بشه، اون رو به هنگام run-time (در زمان اجرای برنامه) از روی همون expression (که یک ساختار قابل توصیف از یک تیکه کد هست) به کد IL تبدیل کنین یا اصطلاحات Emit کنین (بیرون بدین)
در نتیجه میتونین به هنگام run-time کد جدید تولید کنین و این همون تکنیکی هست که کتابخانه های Object Mapper از جمله AutoMapper و Mapster و... از اون استفاده میکنن
🔸گفتم Emit، جا داره از Reflection.Emiit هم یادی بکنیم که پایه ای ترین روش برای تولید کد IL در زمان run-time هست و میشه Expression رو به عنوان یک wrapper روی Reflection.Emit محسوب کرد که کار با اون رو ساده تر میکنه. هرچند کار هایی میشه با Reflection.Emit انجام داد که توسط Expression Tree نمیشه انجام داد (و بلعکس) پس اینجا به هیچ عنوان جایگزین هم نیستند بلکه فقط توی تولید کد IL وجه مشترک دارند.
🔰 جمع بندی
قابلیت Expression Tree یک قابلیت پیشرفته هست و نیاز اکثر افراد نمیشه ولی مزایای غیر قابل چشم پوشی ایی رو به ما میده که حرفه ای ها میتونین کار جالبی باهاش بکنن. توسط این قابلیت که یکی از جذاب ترین امکانات دات نت هست میتونین کار های جالبی انجام بدین از جمله:
1️⃣ گردش روی node ها و فهمیدن ساختار کد (MetaProgramming)
2️⃣ ترجمه کد ها به یک زبان دیگر (Transpilation)
3️⃣ تولید کد IL از روی اون (Code Generation)
💎در آخر یکی از بهترین مقالاتی که این مفهوم رو به خوبی به همراه مثال توضیح داده مقاله زیر هست که پیشنهاد میکنم حتما بخونین
https://tyrrrz.me/blog/expression-trees
____________________
@DotNetZoom
میشه گفت یکی از advanced ترین قسمت های دات نت، مفهوم Expression Tree و کلاس Expression هست که یه جورایی قلب IQueryable رو هم تشکیل میده
شاید نهایت استفاده افراد، کار با <<Expression<Func برای شرط های predicate بر روی متد Where و یا selector برای متد Select باشه
ولی Expression خیلی بزرگتر از اینهاست
🔸درواقع مفهوم Expression Tree به مجموعه از از node ها در قالب یک ساختار درختی گفته میشه که هر node اون، خود یک Expression هست. اما خود Expression چیه؟
درواقع هر Expression یک operation (عملیات) برنامه نویسی رو بیان میکنه. توسط کلاس Expression در دات نت میتوان برای هر عملیات برنامه نویسی یک expression ساخت.
🔹به عنوان مثال:
- تعریف یک variable (متغیر)، constant یا parameter (پارامتر ورودی متد)
- انتصاب یک مقدار به یک variable یا parameter
- جمع، تفریق، ضرب، تقسیم و... کردن دو مقدار
- تعریف یک شرط (if/else) یا سویچ (switch) منطقی
- تعریف یک حلقه (for یا while)
- بازگرداندن (return کردن) خروجی متد
- فراخوانی یک متد، پاس دادن پارامتر های ورودی و گرفتن مقدار خروجی
- و... اکثر کار هایی که شما توسط کد نویسی میتونین انجام بدین
🔸فرق expression با کد نویسی معمولی برای operation های برنامه نویسی اینه که توسط Expression میتوان یک ساختار (data structure) قابل توصیف برای کد ها ایجاد کرد.
در نتیجه میتوان از روی این ساختار قابل توصیف، کار های متفاوت و خلاقانه ای انجام داد. مثلا میشه از روی ساختار کد هامون Transpilation انجام بدیم و کوئری (مثلا SQL) معادل اون رو تولید کرد.
🔹در واقع هنگامی که شما یک عبارت lambda رو به یکی از متد های linq که ورودی <Expression<Func داره پاس میدین، پشت صحنه به هنگام Compile یک LambdaExpression از روی عبارت lambda شما ساخته میشه و اون هست که به متد شما پاس داده میشه.
چرا؟ چون که ساختار کد شما رو لازم داره تا بتونه از روی اون Transpilation انجام بده و کوئری (مثلا SQL) معادل اون رو تولید کنه. (این مثال رو ببینید)
🔸یا حتی میتوان به کمک Transpilation، از روی یک expression یک عبارت readable (خوانا) جهت توصیف کاری که قراره انجام بده تولید کرد. همانند کاری که کتابخانه ReadableExpressions کرده و توسط افزونه ویژوال استادیو ReadableExpressions.Visualizers این امکان رو میده که به هنگام دیباگ بتونین یک readable view از روی expression هاتون ببینید
🔹کار دیگه ای که توسط Expression میشه انجام داد. تولید کد IL (مخفف Intermediate Language) از روی اون هست. مثلا شما نمیتونین توسط Reflection حتی، یک متد جدید (شامل مجمومه ای از operation ها) ایجاد کنین ولی توسط Expression میتونین به جای اینکه کد شما به هنگام compile تبدیل به IL بشه، اون رو به هنگام run-time (در زمان اجرای برنامه) از روی همون expression (که یک ساختار قابل توصیف از یک تیکه کد هست) به کد IL تبدیل کنین یا اصطلاحات Emit کنین (بیرون بدین)
در نتیجه میتونین به هنگام run-time کد جدید تولید کنین و این همون تکنیکی هست که کتابخانه های Object Mapper از جمله AutoMapper و Mapster و... از اون استفاده میکنن
🔸گفتم Emit، جا داره از Reflection.Emiit هم یادی بکنیم که پایه ای ترین روش برای تولید کد IL در زمان run-time هست و میشه Expression رو به عنوان یک wrapper روی Reflection.Emit محسوب کرد که کار با اون رو ساده تر میکنه. هرچند کار هایی میشه با Reflection.Emit انجام داد که توسط Expression Tree نمیشه انجام داد (و بلعکس) پس اینجا به هیچ عنوان جایگزین هم نیستند بلکه فقط توی تولید کد IL وجه مشترک دارند.
🔰 جمع بندی
قابلیت Expression Tree یک قابلیت پیشرفته هست و نیاز اکثر افراد نمیشه ولی مزایای غیر قابل چشم پوشی ایی رو به ما میده که حرفه ای ها میتونین کار جالبی باهاش بکنن. توسط این قابلیت که یکی از جذاب ترین امکانات دات نت هست میتونین کار های جالبی انجام بدین از جمله:
1️⃣ گردش روی node ها و فهمیدن ساختار کد (MetaProgramming)
2️⃣ ترجمه کد ها به یک زبان دیگر (Transpilation)
3️⃣ تولید کد IL از روی اون (Code Generation)
💎در آخر یکی از بهترین مقالاتی که این مفهوم رو به خوبی به همراه مثال توضیح داده مقاله زیر هست که پیشنهاد میکنم حتما بخونین
https://tyrrrz.me/blog/expression-trees
____________________
@DotNetZoom
Oleksii Holub
Working with Expression Trees in C# • Oleksii Holub
Expression trees is an obscure, although very interesting feature in .NET. Most people probably think of it as something synonymous with object-relational mapping frameworks, but despite being its most common use case, it's not the only one. There are a…
Forwarded from کدهک
بررسی نقش کلمه کلیدی await در برنامه نویسی Async در دات نت و ASP NET Core
https://youtu.be/4sscBQdVrfI
https://youtu.be/4sscBQdVrfI
✅ بهبود SEO سایت های AspNet Core توسط کتابخانه SeoTags به کمک قابلیت Structred Data و JSON-LD
قابلیت Structured Data یکی از مباحث پیشرفته SEO هست که با تعریف ساختار صفحه به موتور های جستجو کمک میکنه محتوای صفحه شما رو بهتر متوجه بشن و نمایش بدن. نمونه نمایش نتایج در صفحه سرچ گوگل این موضوع رو میتونین از این لینک مشاهده کنین. همانطور که میبینین بعضی موارد به صورت rich result نمایش داده میشوند.
گوگل داکیومنت کاملی در مورد پیاده سازی Structured Data داره که از این لینک میتونین مشاهده کنین.
پیاده سازی این قابلیت توسط یکی از سه روش زیر انجام میشه
1- روش JSON-LD
2- روش Microdata
3- روش RDFa
روش اول یعنی JSON-LD روش پیشنهادی گوگل هست و در اون محتوای صفحه به صورت json در قالب استاندارد Schema.org درون یک تگ script از نوع application/ld+json تعریف میشه. که در این لینک میتونین نمونه پیاده سازیش رو برای یک product مشاهده کنین.
در روش های Microdata و RDFa هم محتوای صفحه در قالب attribute هایی بر روی تگ های html نشانه گذاری میشن.
داکیومنت گوگل یک قسمت از نحوه پیاده سازی این مورد برای مثال های پرکاربرد از جمله Article و Product و Book و ... نیز ارائه کرده.
حالا کتابخانه SeoTags از JSON-LD هم پشتیبانی میکنه و علاوه بر تولید تمام تگ های SEO برای سایت شما، محتوای JSON-LD رو هم خروجی میده.
داکیومنت استفاده از این کتابخانه برای تولید تگ های meta و link و... در اینجا مشاهده کنید.
و نمونه استفاده از قابلیت JSON-LD رو هم در اینجا و اینجا مشاهده کنید.
https://mjebrahimi.github.io/SeoTags/
__________________
@DotNetZoom
قابلیت Structured Data یکی از مباحث پیشرفته SEO هست که با تعریف ساختار صفحه به موتور های جستجو کمک میکنه محتوای صفحه شما رو بهتر متوجه بشن و نمایش بدن. نمونه نمایش نتایج در صفحه سرچ گوگل این موضوع رو میتونین از این لینک مشاهده کنین. همانطور که میبینین بعضی موارد به صورت rich result نمایش داده میشوند.
گوگل داکیومنت کاملی در مورد پیاده سازی Structured Data داره که از این لینک میتونین مشاهده کنین.
پیاده سازی این قابلیت توسط یکی از سه روش زیر انجام میشه
1- روش JSON-LD
2- روش Microdata
3- روش RDFa
روش اول یعنی JSON-LD روش پیشنهادی گوگل هست و در اون محتوای صفحه به صورت json در قالب استاندارد Schema.org درون یک تگ script از نوع application/ld+json تعریف میشه. که در این لینک میتونین نمونه پیاده سازیش رو برای یک product مشاهده کنین.
در روش های Microdata و RDFa هم محتوای صفحه در قالب attribute هایی بر روی تگ های html نشانه گذاری میشن.
داکیومنت گوگل یک قسمت از نحوه پیاده سازی این مورد برای مثال های پرکاربرد از جمله Article و Product و Book و ... نیز ارائه کرده.
حالا کتابخانه SeoTags از JSON-LD هم پشتیبانی میکنه و علاوه بر تولید تمام تگ های SEO برای سایت شما، محتوای JSON-LD رو هم خروجی میده.
داکیومنت استفاده از این کتابخانه برای تولید تگ های meta و link و... در اینجا مشاهده کنید.
و نمونه استفاده از قابلیت JSON-LD رو هم در اینجا و اینجا مشاهده کنید.
https://mjebrahimi.github.io/SeoTags/
__________________
@DotNetZoom
GitHub
GitHub - mjebrahimi/SeoTags: 🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph…
🚀 SeoTags generates All SEO Tags you need such as meta, link, Twitter card (twitter:), Open Graph (for Facebook) (og:), and JSON-LD schema (structured data). - mjebrahimi/SeoTags
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ تامین امنیت دیتا های حساس و مهم در EF Core
در این پست به معرفی 2 راهکار (یک کتابخانه و دیگری یک مقاله) جهت تامین امنیت اطلاعات حساس و مهم در EF Core میپردازیم
🔸راهکار اول: توسط کتابخانه EntityFrameworkCore.DataEncryption میتونین اطلاعاتتون رو توی دیتابیس رمزنگاری کنین. این کار به سادگی قرار دادن یک اتریبیوت
مثلا برای مقایسه برابری (متد Equals یا دستور ==) مشکلی نداره ولی برای دستور Contains یا ... به مشکل میخورین
🔰ریپازیتوری گیتهاب پروژه + اطلاعات بیشتر
https://github.com/Eastrall/EntityFrameworkCore.DataEncryption
🔹راهکار دوم: فرض کنین شخصی که به دیتابیس دسترسی داره، به صورت دستی و مستقیم (نه از طریق اپلیکیشن ما)، مقداری رو تغییر میده بدون اینکه دسترسی لازم به لحاظ بیزینسی رو داشته باشه.
چطور میتونیم متوجه این قضیه بشیم؟ چطوری از صحت اطلاعات خودمون مطمئن بشیم؟ چطوری میتونیم اصالت اون ها رو تضمین کنیم؟
جواب این سوال رو میتونین توی مقاله زیر که توسط وحید نصیری نوشته شده و از روشی خلاقانه استفاده میکنه پیدا کنین
🔰 تشخیص اصالت ردیفهای یک بانک اطلاعاتی در EF Core
https://www.dotnettips.info/post/3100
نکته: هر دو راهکار بالا database-agnostic هستند یعنی فرقی نمیکنه شما از کدوم دیتابیس پشت EF Core استفاده میکنین؛ با هر دیتابیسی کار میکنه
_______________
@DotNetZoom
در این پست به معرفی 2 راهکار (یک کتابخانه و دیگری یک مقاله) جهت تامین امنیت اطلاعات حساس و مهم در EF Core میپردازیم
🔸راهکار اول: توسط کتابخانه EntityFrameworkCore.DataEncryption میتونین اطلاعاتتون رو توی دیتابیس رمزنگاری کنین. این کار به سادگی قرار دادن یک اتریبیوت
[Encrypted]
بر پروپرتی های entity ها تون انجام میشه. در این روش اطلاعات شما موقع insert/update به صورت خودکار Encrypt شده و به صورت رشته توی دیتابیس ذخیره میشن و موقع واکشی هم به صورت خودکار Decrypt میشن لذا برای اعمال بعضی از دستورات شرطی ممکنه دچار مشکل بشین (به خاطر تفاوت مقدار encrypt شده که البته طبیعی هم هست و راه گریزی نیست)مثلا برای مقایسه برابری (متد Equals یا دستور ==) مشکلی نداره ولی برای دستور Contains یا ... به مشکل میخورین
🔰ریپازیتوری گیتهاب پروژه + اطلاعات بیشتر
https://github.com/Eastrall/EntityFrameworkCore.DataEncryption
🔹راهکار دوم: فرض کنین شخصی که به دیتابیس دسترسی داره، به صورت دستی و مستقیم (نه از طریق اپلیکیشن ما)، مقداری رو تغییر میده بدون اینکه دسترسی لازم به لحاظ بیزینسی رو داشته باشه.
چطور میتونیم متوجه این قضیه بشیم؟ چطوری از صحت اطلاعات خودمون مطمئن بشیم؟ چطوری میتونیم اصالت اون ها رو تضمین کنیم؟
جواب این سوال رو میتونین توی مقاله زیر که توسط وحید نصیری نوشته شده و از روشی خلاقانه استفاده میکنه پیدا کنین
🔰 تشخیص اصالت ردیفهای یک بانک اطلاعاتی در EF Core
https://www.dotnettips.info/post/3100
نکته: هر دو راهکار بالا database-agnostic هستند یعنی فرقی نمیکنه شما از کدوم دیتابیس پشت EF Core استفاده میکنین؛ با هر دیتابیسی کار میکنه
_______________
@DotNetZoom
Telegram
Attach Files
Forwarded from DotNetZoom (Ali Abdolmaleki)
❇️ نکاتی در مورد کار با PDF در دات نت و برترین کتابخانه های آن
کتابخونه های کار با pdf به 2 دسته کلی تقسیم میشن
🔸دسته اول کتابخونه هایی هستند که باهاشون میشه فایل های PDF رو خوند، محتواشو Extract کرد، Edit کرد و یا فایل جدید ساخت
از معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️iTextSharp
✔️iTextSharp.LGPLv2.Core
✔️itext7
✔️PdfSharpCore
معروف ترین شون iTextSharp هست که فقط NET Framework Full. رو پشتیبانی میکنه اما وحید نصیری یه نسخه port شده ازش رو برای NET Core. رو براش درست کرده به نام iTextSharp.LGPLv2.Core
همچنین کتابخونه itext7 که توسط سازنده iTextSharp توسعه داده شده و به عنوان نسخه بعدی iTextSharp و با پشتیبانی از NET Core. اون رو توسعه داده و توصیه میکنه از itext7 استفاده کنین.
🔹دسته دوم کتابخونه هایی هستند که میتونن محتوای یه صفحه html (شامل المان ها و css ها و ...) رو به صورت PDF رندر کنن و خروجی PDF ازشون بگیرن
از جمله معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️DinkToPdf
✔️itext7.pdfhtml
✔️Rotativa.AspNetCore
✔️Wkhtmltopdf.NetCore
طرز کار همشونم به این صورته که اینا معمولا wrapper ایی بر روی کتابخانه wkhtmltopdf هستند که کارش Render کردن خروجی html به pdf هست و پشت صحنه هم از موتور Qt WebKit استفاده میکنن که یک Browser Engine سورس باز هست
🔸اکثر مواقع نیاز برنامه نویسا همین دسته دوم هست. معمولا میخوان از گزارشاتشون خروجی pdf بگیرن که دسته دوم گزینه راحت تری هست چرا که اینجا ما دیگه با یه صفحه html+css سرو کار داریم و خیلی راحت میتونیم هر فرم و جدولی رو که بخوایم طراحی کنیم و وقتی از خروجی html ایی اون مطمئن شدیم اون رو به pdf تبدیل کنیم
دسته اول معمولا کاربرد خاص تری دارند. مثلا اگه بخواین فایل pdf تون رو بخونین، محتواش رو پردازش یا ویرایش کنین یا مثلا ساخت صفحاتتون رو خیلی سفارشی سازی کنین باید از کتابخونه های دسته اول استفاده کنین
یه سری کتابخونه قدرتمند دیگه هم هستند مثل Aspose و Syncfusion ولی چون اونا پولی هستند و نسخه رایگانشون محدودیت داره تو لیست نیاوردمشون
_______________
@DotNetZoom
کتابخونه های کار با pdf به 2 دسته کلی تقسیم میشن
🔸دسته اول کتابخونه هایی هستند که باهاشون میشه فایل های PDF رو خوند، محتواشو Extract کرد، Edit کرد و یا فایل جدید ساخت
از معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️iTextSharp
✔️iTextSharp.LGPLv2.Core
✔️itext7
✔️PdfSharpCore
معروف ترین شون iTextSharp هست که فقط NET Framework Full. رو پشتیبانی میکنه اما وحید نصیری یه نسخه port شده ازش رو برای NET Core. رو براش درست کرده به نام iTextSharp.LGPLv2.Core
همچنین کتابخونه itext7 که توسط سازنده iTextSharp توسعه داده شده و به عنوان نسخه بعدی iTextSharp و با پشتیبانی از NET Core. اون رو توسعه داده و توصیه میکنه از itext7 استفاده کنین.
🔹دسته دوم کتابخونه هایی هستند که میتونن محتوای یه صفحه html (شامل المان ها و css ها و ...) رو به صورت PDF رندر کنن و خروجی PDF ازشون بگیرن
از جمله معروف ترین این کتابخونه ها میشه به ترتیب به موارد زیر اشاره کرد
✔️DinkToPdf
✔️itext7.pdfhtml
✔️Rotativa.AspNetCore
✔️Wkhtmltopdf.NetCore
طرز کار همشونم به این صورته که اینا معمولا wrapper ایی بر روی کتابخانه wkhtmltopdf هستند که کارش Render کردن خروجی html به pdf هست و پشت صحنه هم از موتور Qt WebKit استفاده میکنن که یک Browser Engine سورس باز هست
🔸اکثر مواقع نیاز برنامه نویسا همین دسته دوم هست. معمولا میخوان از گزارشاتشون خروجی pdf بگیرن که دسته دوم گزینه راحت تری هست چرا که اینجا ما دیگه با یه صفحه html+css سرو کار داریم و خیلی راحت میتونیم هر فرم و جدولی رو که بخوایم طراحی کنیم و وقتی از خروجی html ایی اون مطمئن شدیم اون رو به pdf تبدیل کنیم
دسته اول معمولا کاربرد خاص تری دارند. مثلا اگه بخواین فایل pdf تون رو بخونین، محتواش رو پردازش یا ویرایش کنین یا مثلا ساخت صفحاتتون رو خیلی سفارشی سازی کنین باید از کتابخونه های دسته اول استفاده کنین
یه سری کتابخونه قدرتمند دیگه هم هستند مثل Aspose و Syncfusion ولی چون اونا پولی هستند و نسخه رایگانشون محدودیت داره تو لیست نیاوردمشون
_______________
@DotNetZoom
Telegram
Attach Files
Forwarded from DotNetZoom (محمد جواد ابراهیمی)
✅ برترین افزونه های رایگان Visual Studio که هر کسی باید داشته باشه
🔰بهترین افزونه های Code Analyzer سی شارپ
این افزونه ها کد های شما رو آنالیز میکنن و اشتباهات رایج هنگام کدنویسی سی شارپب رو به همراه اصلاحات لازم رو بهتون پیشنهاد میده
از جمله موارد مهمی که توسط این کد آنالیزر ها میشه تشخیص داد:
✔️ کد هایی که Naming Convention و Coding Style استاندارد رو رعایت نکردن
✔️ کد های کثیف و Code Smell ها
✔️ کد هایی که به لحاظ ساختاری bug دارند یا مستعد bug هستند
✔️ کد هایی که به لحاظ آسیب پذیری دارند یا منسوخ شدند
✔️ پیشنهاداتی برای تمیز تر کردن کدتون و استفاده از ویژگی های جدید سی شارپ
✔️ پیشنهاداتی که باعث بهبود Performance میشه
🔸SonarLint - Nuget
🔹Roslynator - Nuget
🔸CodeCracker - Nuget
🔹CodeMaid
🔸Sharpen
🔰بهترین افزونه های Code Analyzer مخصوص Async/Await
این دو کد آنالیزر اشتباهات رایج هنگام کدنویسی async رو به همراه اصلاحات لازم بهتون پیشنهاد میدن
🔸AsyncFixer - Nuget
🔹AsyncMethodNameFixer - Nuget
🔰نمایش بهتر خطا ها و هشدار ها
یه افزونه باحال و کاربردی که خطا ها و هشدار های هر فایل رو داخل Solution Explorer کنار اون فایل نشون میده
🔸ErrorVisualizer
🔰فرمت خودکار کد ها به هنگام Save
افزونه محبوب من که کد ها رو موقع ذخیره، به صورت اتوماتیک Format میکنه (معادل میانبر Ctrl+K+D) در نتیجه همیشه کد هاتون فرمت شده و تمیز باقی میمونه بدون اینکه دغدغه اش رو داشته باشین یا یادتون بره
🔹FormatDocumentOnSave
🔰هایلایت متون پنجره Output
یه افزون کاربردی که متون پنجره Output رو highlight میکنه. خیلی وقتا جزئیات و اطلاعاتی از خطا ها داخل پنجره Output نمایش داده میشه که خوندنش خیلی بهتون کمک میکنه
🔸OutputEnhancer
🔰نکته:
بعضی از Code Analyzer ها پکیج Nuget هم دارند کنارشون که این امکان رو میده که بتونید ازش هرجا که NET CLI. هست استفاده کنین. مثلا توی VSCode و مهم تر از اون برای CI/CD، به این صورت که میتونین جز pipeline CD/DI تنظیمش کنین که اگر کدی خطا های Naming Convention یا Coding Style داشت متوجه بشین یا حتی اجازه ندین Pull Request اش Merge بشه
________________
@DotNetZoom
🔰بهترین افزونه های Code Analyzer سی شارپ
این افزونه ها کد های شما رو آنالیز میکنن و اشتباهات رایج هنگام کدنویسی سی شارپب رو به همراه اصلاحات لازم رو بهتون پیشنهاد میده
از جمله موارد مهمی که توسط این کد آنالیزر ها میشه تشخیص داد:
✔️ کد هایی که Naming Convention و Coding Style استاندارد رو رعایت نکردن
✔️ کد های کثیف و Code Smell ها
✔️ کد هایی که به لحاظ ساختاری bug دارند یا مستعد bug هستند
✔️ کد هایی که به لحاظ آسیب پذیری دارند یا منسوخ شدند
✔️ پیشنهاداتی برای تمیز تر کردن کدتون و استفاده از ویژگی های جدید سی شارپ
✔️ پیشنهاداتی که باعث بهبود Performance میشه
🔸SonarLint - Nuget
🔹Roslynator - Nuget
🔸CodeCracker - Nuget
🔹CodeMaid
🔸Sharpen
🔰بهترین افزونه های Code Analyzer مخصوص Async/Await
این دو کد آنالیزر اشتباهات رایج هنگام کدنویسی async رو به همراه اصلاحات لازم بهتون پیشنهاد میدن
🔸AsyncFixer - Nuget
🔹AsyncMethodNameFixer - Nuget
🔰نمایش بهتر خطا ها و هشدار ها
یه افزونه باحال و کاربردی که خطا ها و هشدار های هر فایل رو داخل Solution Explorer کنار اون فایل نشون میده
🔸ErrorVisualizer
🔰فرمت خودکار کد ها به هنگام Save
افزونه محبوب من که کد ها رو موقع ذخیره، به صورت اتوماتیک Format میکنه (معادل میانبر Ctrl+K+D) در نتیجه همیشه کد هاتون فرمت شده و تمیز باقی میمونه بدون اینکه دغدغه اش رو داشته باشین یا یادتون بره
🔹FormatDocumentOnSave
🔰هایلایت متون پنجره Output
یه افزون کاربردی که متون پنجره Output رو highlight میکنه. خیلی وقتا جزئیات و اطلاعاتی از خطا ها داخل پنجره Output نمایش داده میشه که خوندنش خیلی بهتون کمک میکنه
🔸OutputEnhancer
🔰نکته:
بعضی از Code Analyzer ها پکیج Nuget هم دارند کنارشون که این امکان رو میده که بتونید ازش هرجا که NET CLI. هست استفاده کنین. مثلا توی VSCode و مهم تر از اون برای CI/CD، به این صورت که میتونین جز pipeline CD/DI تنظیمش کنین که اگر کدی خطا های Naming Convention یا Coding Style داشت متوجه بشین یا حتی اجازه ندین Pull Request اش Merge بشه
________________
@DotNetZoom
Forwarded from کدهک