C# Programming Guide
191 subscribers
113 photos
9 videos
14 files
102 links
سلام دوستان در این کانال نکاتی در مورد مسائل پیشرفته در سی شارپ ارائه میشه که مربوط به بیش از 15 سال تجربه ی کاری من هست.
ممنون از اینکه دنبال میکنید.
اگر نکات خاصی به ذهنتون رسید با ادمین در میون بذارید
تماس با ادمین:
@Ali_Visual_Studio
Download Telegram
کلاس های استاتیک اصولا کلاس های Single Instance هستند یعنی یکبار در حافظه ساخته میشن و تا اخر اجرای برنامه (یا لود بودن AppDomain) در حافظه میمونن،کانستراکتور های Static هم توی سی شارپ کاربرد های جالبی دارن مثلا هر وقت اون کلاس Static قرار بود یکبار توی حافظه ساخته بشه این کانستراکتور فقط یکبار توی کل روند برنامه صدا زده میشه، مثلا شما برای شروع یک Engine و یا Background worker میتونید از این کانستراکتور جالب استفاده کنید و داخلش job رو شروع کنید بدون اینکه نگران باشید که جایی لازم باشه متد Start رو صدا بزنید چون کلاس های استاتیک و کانستراکتور های استاتیک فقط وقتی بارگزاری میشن (یعنی یک Instance از کلاس ساخته میشه) که توی کد ازشون استفاده بشه و در روند اجرا شدن برنامه توی حافظه ساخته نمیشن بلکه فقط وقتی ساخته میشن که توی یک خط کدی ازش استفاده کنید.مثلا اگر کاربر روی یک دکمه کلیک کنه که توی متد اون دکمه از اون کلاس استاتیک استفاده کنید اینجا تازه اون کلاس استاتیک توی حافظه ساخته میشه و کانستراکتور استاکیش صدا زده میشه.
و همچنین اگر یک کلاس جنریک داشته باشید به ازای هر نوع مختلف از T یک Instance جداگونه از اون کلاس استاتیک و کانستراکتورش خواهید داشت، مثلا MyClass<int>.Name با MyClass<string>.Name مقادیرش توی حافظه مختلف خواهند بود ولی هر کدام Static هستند و یکبار در حافظه ساخته شدند و کانستراکتور های خودشون رو هم دارند.
#سی_شارپ
#Static
#CSharp

@CsharpTips
کدهک
چرا نباید از Async void استفاده کنیم؟ https://tinyurl.com/codehaks-avoid-async-void
این دیدگاه اشتباه هست که چرا نباید از async void استفاده کنیم.چون این خودش یکی از ویژگی های سی شارپ هست، توی برنامه نویسی Multi-Threading وقتی شما به صورت دستی یک Thread میسازید اگر توی اون ترد عملیات try catch انجام نداده باشید هم با خطای unhandle exception مواجه میشید و اپلیکیشن شما کرش میکنه و کاملا متوقف میشه هرچند با روش هایی میشه حتی unhandle exception ها رو هم هندل کرد.اما هیچ برنامه نویس Multi-Threading ای نمیاد یک ترد رو بدون try catch اجرا کنه تا با این خطا مواجه بشه در نتیجه استفاده از async void مستقیم هیچ اشکالی نداره که هیچ خیلی جاها هم کاربرد داره منتهی باید حواستون باشه که توی تابع باید از try catch استفاده کنید تا هنگام مواجه شدن با خطای unhandle exception خطا رو catch کرده باشید.

#csharp
#multi_threading

@csharptips
دو تا از مهمترین مولفه هایی که Dependency Injection باعث کندی پرفورمنس توی سیستم شما و شلخته شدن معماری پروژه شما میشه اینا هستند:

1.شما در یک کلاس سرویس دوتا interface رو inject میکنید در حالی که ممکنه در بعضی از سرویس هاتون (متد هاتون) از اونا استفاده نکنید.این یعنی بخواید نخواید اون Dependency توی constructor کلاس inject خواهد شد و علاوه بر اینکه اینکار یک سربار اضافه بر روی سرویس های شماست حتی اینکه چرا از اون کلاس inject شده استفاده نمی کنید ولی اونو inject میکنید و یا در فیلد های کلاس شما هست خودش مساله هست که معماری سیستم شمارو زیر سوال میبره.بنابراین راه کار اینه که کلاسیرو inject کنید که حتما از اون توی تمامی سرویس ها استفاده میکنید یا اگر نمی کنید توابع رو در یک سرویس جداگانه بزنید که این عمل هم خودش ممکنه باعث زیاد شدن کلاس های سرویس ها به ازای هر interface ای که inject میکنید بشه.

2.به طور کلی استفاده از عملیات runtime برای instance گرفتن کلاس ها از طریق Activator.CreateInstance و روش های دیگه ی Runtime چندین برابر نسبت به عملیات کامپایل تایم کند هست.یعنی شما اگر به صورت دستی یک کلاس رو new کنید صد ها برابر سریعتر از کلاسی هست که به صورت runtime در حافظه new میشه.در Dependency Injection به طور کاملا صد در صد کلاس های سرویس شما به ازای هر بار صدا زدن توسط Activator در حافظه new میشن و همونجا هم constructor هایی که باید inject بشن هم new یا به صورت cache توی اون کلاس inject میشن نمیتونم بگم این عملیات چقدر کند هست اما وقتی این اتفاق توی بک اند کم کم اتفاق میوفته به قول معروف قطره قطره جمع شود وانگهی دریا شود، سیستم شما رو بشدت کند میکنه و شما کماکان دنبال کدهایی در ساختار خودتون برای بالا بردن پرفورمنس میگردید در حالی که مشکل از جای دیگه آب میخوره.

#CSharp
#Dependency_Injection
@CsharpTips
چطوری میتونیم بین دوتا دیتابیس مجزا مثل SQL و NoSQL عملیات Transaction رو انجام بدیم؟
به طور طبیعی اینکار ممکن نیست، اما پترنی برای انجام اینکار وجود داره و شما میتونید توسط این پترن بین این دوتا دیتابیس transaction بزنید.
1.در صورتی که هر دو دیتابیس SQL و NoSQL قابلیت transaction رو داشته باشن:
در این روش شما میتونید ابتدا اطلاعات رو به صورت transaction توی دیتابیس ها ذخیره کنید بدون اینکه transaction ها رو commit کنید، سپس اگر هر دو transaction با موفقیت اطلاعات رو تونستن به ثبت یا حذف برسونن اونوقت transaction هر دو دیتابیس رو Commit کنید و اطلاعات رو ذخیره کنید.
2.در صورتی که فقط یکی از دو دیتابیس قابلیت transaction داشته باشن:
در این روش ابتدا کوئری رو روی اون دیتابیسی که قابلیت transaction داره اجرا می کنید ولی commit نمی کنید سپس کوئری رو روی دیتابیسی که transaction نداره اجرا می کنید اگر دیتابیس دوم به خطا نخورد transaction دیتابیس اول رو کامیت می کنید، در غیر این صورت اگر دیتابیس دوم خطا بخوره دیتابیس اول هم تغییراتش نباید commit بشه.

ما توی سیستم خودمون ساختار SQL و No SQL هامون یکی هست یعنی برنامه نویس اصلا متوجه این نمیشه که کوئری ها رو باید برای sql یا no sql مجزا بزنه هر دو یک شکل هستن فقط توی زیر ساخت مشخص میکنیم که این context قراره sql باشه یا no sql و تبدیل یک دیتابیس sql به no sql فقط با یک ارث بری فاصله داره و ساختار transaction بین دوتا دیتابیس مجزا رو توی هسته این سیستم پیاده سازی کردیم به همین روش هایی که در بالا توضیح دادم.

#CSharp
#EFCore
#Transaction

@CSharpTips
در راستای توضیح هسته:
این دو تابع دوتا ورودی فانکشن رو با هم And و Or میکنن و تبدیل به یک func می کنن.
نحوه ی استفاده از Expression ها برای And و Or کردن دو Func ورودی که جلوتر توضیح خواهم داد.
#Expression
#CSharp

@CSharpTips
توی ویژوال استادیو شما توانایی اینو دارید که از قابلیت Multiple target frameworks استفاده کنید و برای پکیج هاتون چندین نسخه از دات نت رو ساپورت کنید و برای هر کدوم کد خاص خودشون رو بزنید.

مثلا وقتی یک قابلیت جدید توی دات نت 6 اضافه میشه پکیج شما باید هم توانایی کامپایل و تست روی نسخه ی 6 رو داشته باشه و هم نسخه ی 2.1 استاندارد، اما اگر میخواهید قسمتی از کد رو تغییر بدید تا از نسخه ی جدید بهرمند بشید باید از شرط های بخصوصی استفاده کنید که توی تصویر دارید می بینید.

اما دغدغه‌ی من که سالهاست برای پکیج هام با این قابلیت کار میکنم اینه که کدهام رو ناخوانا میکنه و از کسانی که در ایده گذاری های مایکروسافت کار میکنن تقاضا دارم یک قابلیت اضافه کنند که توی کادر بالا وقتی من انتخابش میکنم تمامی #if ها رو حذف کنه و فقط کد مخصوص اون پلتفرم رو نشون بده.

اینطوری دیگه مشکل کد کلین هم رفع میشه و البته هر وقت بخوام میتونم با قابلیتی که وجود داره همه‌ی کد های همه ی پلتفرم هارو یکجا ببینم تا تشابه و رفع باگ گیجم نکنه.

#برنامه_نویسی
#تخصصی
#دات_نت
#سی_شارپ
#dotnet
#csharp
👍3
توابعی که خروجی Task دارند ولی از کیورد async توشون استفاده نشده در واقع sync هستند.
در مثالی که در تصویر میبینید شاید تصور بشه که متد Example باید در پس زمینه اجرا بشه ولی این اتفاق نمیوفته و کاملا به صورت sync اجرا خواهد شد. این متد در واقع مثل بقیه ی متد های sync فقط یک خروجی Task داره. مثل متد زیر:
static string Example()

پس حواستون باشه که اشتباه نکنید.

#تخصصی
#سی_شارپ
#dotnet
#csharp
#task
#async

@CSharpTips
👍4
#تخصصی
استفاده از Enumerable ها همیشه هم خوب نیست، یک برنامه نویس باید بدونه کجا باید از Enumerable استفاده کنه و کجا باید به استفاده از اون خاتمه بده، در مثال بالا تا زمانی که یک کوئری از Enumerable رو ToList نکنید، هربار که روی اون پردازش انجام بدید مجدد فرایند کوئری ها اجرا خواهد شد.
#Csharp
@CsharpTips
👍6
سلام دوستان عزیزم. مخصوصا اون عزیزانی که در حال پیدا کردن کار (#opentowork) هستند و در واقع الان نمیدونن چطوری باید خودشون رو بروز نگه دارن. یا اگر #کار دارید و بروز هم هستید دوست دارید یک ماجراجویی برای بالابردن کیفیت رزومه‌ی خودتون داشته باشید پیشنهاد میکنم با من همراه باشید. در غیر اینصورت ازتون خواهش میکنم با #لایک و و #کامنت و #اشتراک_گذاری #حمایت کنید.

ما در حال ساخت یک کامیونیتی بزرگ اپن سورس درمورد زیرساخت میکروسرویسی هستیم در صورتی که تمایل داشتید میتونیم باهم همکاری داشته باشیم.
اهداف ما:
1.زنده و فعال نگهداشتن پروفایل گیتهاب شما برای اینکه در آینده رزومه‌ی کاری شمارو افزایش بدیم.
2.آموزش به شما درباره‌ی زیر ساخت‌های میکروسرویس‌ها و بررسی معماری‌های موجود و چالش‌های پیش رو
3.بحث و گفتگو و ایجاد چالش، ساخت پکیج و بالا بردن کیفیت استفاده از میکروسرویس‌ها در آینده برای برنامه نویس ها

بعد از جوین شدن از شما انتظار میره:
1.معماری نرم افزار و OOP و Functional programming یاد بگیرید.
2.کار با nuget و ساخت و آپلود پکیج های خودتون رو یاد بگیرید.
3.کار با انواع بخش های گیتهاب از جمله issue, code review , pull request, project, wiki, actions, tests, code coverage رو یاد بگیرید.

این کامیونیتی کاملا رایگان و اوپن سورس هست و هدفش استخدام شما نیست، اگر بتونید یک ایده هم بدید یا حتی کدهای بقیه رو review کنید یا کامنت و تغییرات بزنید، شما پروفایل گیتهابتون عملا همیشه فعال میمونه و با بالابردن کیفیت اکانت گیتهابتون شما دیگه نیازی نیست دنبال کار بگردید بلکه کار به دنبال شما میگرده و ضمن اینکه عضو کانتریبیوترهای این پروژه شدید، خدارو چه دیدی شاید در آینده یه اتفاق خوب برای هممون افتاد :)

برای شروع میتونید به گروه تلگرامی ما بپیوندید:

https://t.me/easymicroservice

#github
#microservice
#oop
#functionalprogramming
#CSharp
#opensource
👍3
Forwarded from Easy Microservices (Ali Yousefi ˢᵒᶠᵗʷᵃʳᵉ ᴰᵉᵛᵉˡᵒᵖᵉʳ)
پکیج EasyMicroservices.Logger یک اینترفیس به شما ارائه میکنه که با استفاده از اون میتونید توی اپلیکیشن خودتون هرچی میخواید رو لاگ کنید.
این اینترفیس میتونه سطوح زیر رو لاگ کنه:

Verbose
Debug
Information
Warning
Error
Fatal

یک اینترفیس هم برای توابع async وجود داره که میتونید ازش استفاده کنید.

تا به اینجا هم تامین کننده های زیر برای لاگ کردن توی دات نت پیاده سازی شدن:


1 .Log4net
2. Logary
3. Loupe
4. NLog
5. Sentry
6. Serilog


با استفاده از این اینترفیس هر زمان که دوست داشتید میتونید پکیج تامین کننده لاگ خودتون رو با یک خط کد تغییر بدید بدون اینکه زیر ساخت پروژه ی شما دست بخوره.
سورس:
https://github.com/EasyMicroservices/Logger

@easymicroservice
@easymicroservices
@csharptips

#log
#logger
#csharp
#dotnet
Forwarded from Easy Microservices (Ali Yousefi ˢᵒᶠᵗʷᵃʳᵉ ᴰᵉᵛᵉˡᵒᵖᵉʳ)
Easy Microservices
Photo
ارث‌بری در رابط کاربری چگونه است؟ آیا قابلیت پیاده‌سازی دارد؟
ارث‌بری در رابط کاربری مانند برنامه‌نویسی نیست و پیاده‌سازی آن به‌مراتب دشوارتر است، چرا که ابزار‌های رابط کاربری هنوز در حال توسعه‌اند و به آن بلوغ نرسیده‌اند که بتوان روی آن‌ها معماری دقیق و کاملی را پیاده کرد.
امروز ما می‌خواهیم یک نمونه از ارث‌بری در رابط کاربری را به شما نشان دهیم تا ببینید که ما در Easy Microservices چگونه این موضوع را حل می‌کنیم.

تصور کنید که ما دو UI Kit قدرتمند MudBlazor و Radzen را در اختیار داریم. هر یک از این کامپوننت‌ها خصوصیات خود را دارند؛ به طور مثال یک دکمه در MudBlazor با نام MudButton و در Radzen با نام RadzenButton معرفی شده است و هر کدام ویژگی‌های خاص خود را دارند.

حال اگر به وابستگی‌ها بپردازیم، فرض کنید کل پروژه را با Radzen توسعه داده‌ایم و بعد متوجه شویم که پشتیبانی از RTL (متن چپ-به‌راست) را ندارد، دیگر چه عملی باید انجام داد؟ آیا باید وقت زیادی صرف کنیم تا کل پروژه را به MudBlazor تبدیل کنیم؟

راه‌حلی که ما ارائه کرده‌ایم به این ترتیب است که ما یک کنترل به نام EasyButton می‌سازیم و سپس آن را برای Radzen و MudBlazor پیاده‌سازی می‌کنیم، دقیقاً همان کاری که در ارث‌بری دو کلاس از یک interface انجام می‌دهیم.

در نتیجه، اگر سیاست‌مان تغییر کند، تنها کافی است که چند خط کد را تغییر دهیم و بین UI Kits جابه‌جا شویم.

شما می‌توانید نمونه پروژه ساده‌ای که من به صورت پیاده‌سازی شده در اینجا توصیف کردم را در گیت‌هاب مشاهده کنید:

https://github.com/EasyMicroservices/UI-Kits/

#inheritance
#csharp
#blazor
#microcomponent
#easymicroservices

@easymicroservice
@easymicroservices
@csharptips
👍2