<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Kaveh Kardel</title>
        <link>https://virgool.io/feed/@Kavekardel</link>
        <description>برنامه نویس</description>
        <language>fa</language>
        <pubDate>2026-04-15 08:19:03</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/119702/avatar/ivs8oP.jpg?height=120&amp;width=120</url>
            <title>Kaveh Kardel</title>
            <link>https://virgool.io/@Kavekardel</link>
        </image>

                    <item>
                <title>چرا باید الگوریتم و ساختمان داده یاد بگیریم؟</title>
                <link>https://virgool.io/codenevis/%DA%86%D8%B1%D8%A7-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%88-%D8%B3%D8%A7%D8%AE%D8%AA%D9%85%D8%A7%D9%86-%D8%AF%D8%A7%D8%AF%D9%87-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%DB%8C%D9%85-e39dosxkyb0q</link>
                <description>1. برنامه‌هامون سریع‌تر و بهینه‌تر میشن2. حل مسائل پیچیده راحت‌تر میشه3. پایه‌ی تکنولوژی‌های پیشرفته4. کاربردشون توی پروژه‌های واقعیاینا که واضحه، هیچی... اما؟5. موفقیت توی مصاحبه‌های شغلیاگر برای نقش برنامه نویسی اپلای میکنید به احتمال خیلی بالا شاید تو 90 درصد مصاحبه ها یه سوال الگوریتمی و ساختمان داده ای ازتون میپرسن در نتیجه نمیشه ازش فرار کرد. (الان یادمون نیاد آآ من با فلان شرکت مصاحبه کردم الگوریتم نپرسید منم قبول شدم!! شرکتای خوب میپرسن...)6. تقویت مهارت حل مسئلهاین ازون دسته مسائله که شاید خودمون به صورت خیلی ملموس متوجهش نشیم. فرض کنیم یه نوزاد تا سن 18 ماهگیش که شروع میکنه به تمرین راه رفتن آیا فقط اون تمرینه هست که باعث میشه راه رفتنو یاد بگیره؟ در واقع خیر. نوزاد از خیلی وقت پیش داشته راه رفتن پدر مادر و اطرافیانش رو میدیده و پترنشو تو ذهنش داشته. الگوریتم هم تو برنامه نویسی اولین مواجهه برنامه نویس با راه رفتنه! در واقع تو ناخودآگاه یه تاثیری میزاره که تا سالها مدل فکری و دست خط کد نویسی تحث تاثیرش هست.در نتیجه1- اگر شروع مسیر برنامه نویسی هستی حتما درمورد الگوریتما مطالعه کن و گول اینایی که میگن دوماهه برنامه نویس شو رو نخور.2- حالا گول خوردی الانم برنامه نویس شدی مهندس؟ اشکال نداره. ماهی رو هر وقت از آب بگیری تازس (چاره ای نداری، الان بخون و سعی کن سبک فکری و دست خطت رو تطبیق بدی با استاندارد ها)</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Tue, 31 Dec 2024 21:54:56 +0330</pubDate>
            </item>
                    <item>
                <title>اثر دانینگ-کروگر و سندروم ایمپاستر: تعریف و تفاوت‌ها</title>
                <link>https://virgool.io/@Kavekardel/%D8%A7%D8%AB%D8%B1-%D8%AF%D8%A7%D9%86%DB%8C%D9%86%DA%AF-%DA%A9%D8%B1%D9%88%DA%AF%D8%B1-%D9%88-%D8%B3%D9%86%D8%AF%D8%B1%D9%88%D9%85-%D8%A7%DB%8C%D9%85%D9%BE%D8%A7%D8%B3%D8%AA%D8%B1-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-%D9%88-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D9%87%D8%A7-hjdy4uftcxet</link>
                <description>در دنیای روان‌شناسی، دو پدیده مهم که بر قضاوت افراد در مورد توانایی‌های خود تأثیر می‌گذارند، &quot;اثر دانینگ-کروگر&quot; و &quot;سندروم ایمپاستر&quot; هستند. هر دو پدیده به احساسات و تصورات نادرست درباره شایستگی فرد مرتبط هستند، اما در جهات کاملاً متفاوت عمل می‌کنند. این مقاله به تعریف این دو پدیده، ویژگی‌های آن‌ها و تفاوت‌های کلیدی میانشان می‌پردازد.اثر دانینگ-کروگراثر دانینگ-کروگر (Dunning-Kruger Effect) وضعیتی است که در آن افراد با سطح دانش یا مهارت پایین، توانایی خود را بیش از حد واقعی ارزیابی می‌کنند. این پدیده به دلیل عدم آگاهی از ناآگاهی رخ می‌دهد؛ به عبارتی، فرد نمی‌داند که چه چیزهایی را نمی‌داند.ویژگی‌ها:اعتماد به نفس بالا با دانش کم: افراد در مراحل ابتدایی یادگیری معمولاً اعتماد به نفس بسیار بالایی دارند.عدم توانایی در ارزیابی خود: این افراد نمی‌توانند درک کنند که توانایی‌هایشان پایین‌تر از سطح مورد انتظار است.کاهش اعتماد به نفس با افزایش دانش: با افزایش یادگیری، اعتماد به نفس کاهش می‌یابد زیرا فرد متوجه می‌شود که چقدر چیزهای بیشتری برای یادگیری وجود دارد.مثال: فردی که به تازگی یک مهارت مانند برنامه‌نویسی را یاد گرفته است و تصور می‌کند می‌تواند پروژه‌های پیچیده را بدون مشکل انجام دهد، در حالی که هنوز چالش‌های واقعی را تجربه نکرده است.سندروم ایمپاسترسندروم ایمپاستر (Imposter Syndrome) وضعیتی است که در آن افراد با وجود شایستگی و موفقیت، احساس می‌کنند که لیاقت جایگاه خود را ندارند و موفقیت‌هایشان نتیجه شانس یا عوامل خارجی است.ویژگی‌ها:اعتماد به نفس پایین با دانش بالا: افراد معمولاً بسیار ماهر یا متخصص هستند، اما دائماً به خود شک دارند.ترس از افشا: این افراد نگران هستند که دیگران متوجه شوند که آن‌ها &quot;تقلبی&quot; هستند.نادیده گرفتن موفقیت‌ها: افراد مبتلا به این سندروم معمولاً موفقیت‌های خود را کوچک می‌شمارند یا به عوامل بیرونی نسبت می‌دهند.مثال: فردی که در یک محیط کاری حرفه‌ای به موفقیت‌های زیادی دست یافته است، اما همچنان احساس می‌کند که به اندازه همکاران خود شایسته نیست و به زودی دیگران متوجه خواهند شد که او &quot;صلاحیت کافی&quot; ندارد.تفاوت‌های کلیدی بین اثر دانینگ-کروگر و سندروم ایمپاستراثر دانینگ-کروگر و سندروم ایمپاستر در چندین جنبه اساسی تفاوت دارند:سطح دانش و مهارت: در اثر دانینگ-کروگر، فرد دانش یا مهارت کمی دارد و از آن آگاه نیست، در حالی که در سندروم ایمپاستر فرد با وجود دانش یا مهارت بالا، به شایستگی خود شک دارد.اعتماد به نفس: اثر دانینگ-کروگر باعث ایجاد اعتماد به نفس بیش از حد می‌شود، در حالی که سندروم ایمپاستر به کاهش اعتماد به نفس منجر می‌شود.خود ادراکی: در اثر دانینگ-کروگر، فرد نمی‌داند که نمی‌داند؛ اما در سندروم ایمپاستر، فرد نمی‌داند که می‌داند.نگرش به موفقیت‌ها: در اثر دانینگ-کروگر، افراد موفقیت را نتیجه شایستگی خود می‌دانند، در حالی که در سندروم ایمپاستر، موفقیت به شانس یا عوامل خارجی نسبت داده می‌شود.واکنش به بازخورد: افراد مبتلا به اثر دانینگ-کروگر اغلب بازخوردها را نادیده می‌گیرند، در حالی که افراد مبتلا به سندروم ایمپاستر، بازخوردها را به عنوان تایید ناتوانی خود تفسیر می‌کنند.شباهت‌هابا وجود تفاوت‌های اساسی، این دو پدیده در برخی جنبه‌ها شباهت دارند:هر دو به ارزیابی نادرست از توانایی‌های فرد مربوط هستند.هر دو می‌توانند بر تصمیم‌گیری و رفتار فرد تأثیر منفی بگذارند.هر دو نیازمند آگاهی و خودشناسی برای مدیریت بهتر هستند.راهکارهای مقابله با این دو پدیدهبرای اثر دانینگ-کروگر:یادگیری مداوم: تلاش برای افزایش دانش و مهارت در حوزه مورد نظر.درخواست بازخورد: گرفتن نظرات از افراد با تجربه برای شناخت بهتر نقاط ضعف و قوت.فروتنی: پذیرش اینکه همیشه چیزهایی برای یادگیری وجود دارد.برای سندروم ایمپاستر:قدردانی از موفقیت‌ها: یادگیری ارزش‌گذاری برای دستاوردهای شخصی.صحبت با دیگران: به اشتراک گذاشتن احساسات با دوستان یا مشاور.تمرکز بر حقایق: یادآوری موفقیت ها مانند نظرات مثبت، جوایز یا پروژه‌های موفق.اثر دانینگ-کروگر و سندروم ایمپاستر دو سوی مختلف از طیف ارزیابی خود هستند. یکی به دلیل ناآگاهی، اعتماد به نفس بیش از حد ایجاد می‌کند و دیگری با وجود شایستگی، باعث شک به خود می‌شود. شناخت این دو پدیده و استفاده از راهکارهای مناسب می‌تواند به بهبود خودآگاهی و عملکرد فرد کمک کند. آگاهی از این مفاهیم به ما کمک می‌کند تا در مسیر رشد شخصی و حرفه‌ای، تصمیم‌های بهتری بگیریم.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Sat, 28 Dec 2024 17:25:58 +0330</pubDate>
            </item>
                    <item>
                <title>خداحافظی با اینستاگرام و ایکس</title>
                <link>https://virgool.io/@Kavekardel/%D8%AE%D8%AF%D8%A7%D8%AD%D8%A7%D9%81%D8%B8%DB%8C-%D8%A8%D8%A7-%D8%A7%DB%8C%D9%86%D8%B3%D8%AA%D8%A7%DA%AF%D8%B1%D8%A7%D9%85-%D9%88-%D8%A7%DB%8C%DA%A9%D8%B3-bkwiys5lmzsa</link>
                <description>میگن وقتی یه چیزیو نداشته باشی ارزششو میدونی.ولی بعضی چیزا هستن که وقتی نداشه باشیش تازه بی ارزش بودنش رو میفهمی.روی صحبتم شبکه های اجتماعی ای هستن که هممون داریم و به اندازه کافی میدونیم چقدر بده ولی دل کندن ازش برامون سخته.من یه مدت به شدت دچار مشکل تمرکز شدم و بیرون اومدن ازون شرایط یکی از سخت ترین کارهاس. چون شما همیشه دنبال یه فرصت مناسبی که بشینی فکراتو جمع کنی و تصمیم بگیری که چطور حلش کنی... ولی اصلا اون فرصت مناسبرو پیدا نمیکنی... برای همین مثل یه باتلاق که هرچی دستو پا میزنی بیشتر توش فرو میری و یهو به خودت میای میبینی وسط فکر در حال اسکرول کردنی و هی از این برنامه به اون برنامه میپری... این اصلا موضوع چیپی نیست که از بیانش بخوایم خجالت بکشیم.... اصلا به معنای اراده ضعیفو اینحرفا هم نیست... انقدر این مسئله مهم و قوی هست که هممون هم دردیم و در عین حال همه سعی میکنیم که چهره همچی خوبه ما چقدر خوشحالیم تو همین فضای پر استرس از خودمون به جا بزاریم...برای من خارج شدن ازین وضع ماه ها طول کشید... برنامه ریزی های مختلف رو تست کردم. از محدودیت زمانی گذاشتن رو اپ ها تا تنظیم فوکس مود های مختلف و...در انتها تو یه غروب بارونی در حال نوشیدن کافیم از پشت پنجره، تصمیم گرفتم که به کل همچیز رو حذف کنم...اوایل یه ترس فومو ای هست که باهاتونه و هی نگرانید نکنه چیز مهمی باشه که از دستش بدم. این سخت ترین جاشه. یه هفته از هیچ طریقی وارد این فضا نشید(برای من صراحتا اینستاگرام و ایکس). بعد یه هفته وارد بشین احتمالا چنتا پیام داشته باشید که بخواید بهش جواب بدید. اینکارو هم بکنید. قسمت قشنگ دقیقا بعد از جواب دادن به پیاما و دیدن چنتا ازون استوری ها که هر روز میدیدن هست. متوجه میشید که هیچ چیزی رو از دست ندادید. کار مهمی نبوده که به گوشتون نرسیده باشه. همش یه سری پیامو نوتیفیکشن بوده که بعد یه هفته چک کردن هم کاملا به همشون میرسید و از چیزی عقب نموندین. البته اینا تجربیات منه. بعد چند هفته هم که فقط آخر هفته ها اینکارو انجام بدید یه جایی تو یه هفته ای میبینید اصلا یادتون رفته دیگه :)حالا از بعد پاکی هم براتون بگم! انگار وارد یه دنیای دیگه میشی... ولی حقیقتا وقت بیشتری دارین به کاراتون برسین. کم کم شروع کنید به کتاب خوندن چون مغزتون دنبال محتوا میگرده و بجای اون محتوای بد میتونید محتوای خوب بهش بدید. به حد زیادی درگیری ذهنیتون پایین میاد. حالا یکی مثل منم آلردی ذهنش همیشه مشغوله ولی حداقل به سوالای بهتری تو زندگی جواب خواهید داد.بازم میگم این تجربه من بود و اصل مطلب اینه که آقا با کمو زیاد کردن فشار نمیشه از این فضای زرد دل کند. باید یبار تصمیم بگیرید (نمیگم برای همیشه چون به هر حال آدمیزاده و ممکنه برگرده به اعتیادش) برای یه مدت زیاد از شرش خلاص بشید. بعد خودتون متوجه بد و نامفید بودنش میشید.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Sat, 02 Dec 2023 13:37:43 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی Bit Platform</title>
                <link>https://virgool.io/bitplatform/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-bit-platform-hikory2ffnmt</link>
                <description>پلتفرم Bit یک پروژه تماما Open Source در GitHub میباشد که هدف آن تسهیل توسعه نرم افزار با کیفیت و پرفرمنس بالا بر بستر ASP.NET Core و زبان #C است که با آن بتوان فقط با یکبار کدنویسی و با کمک استانداردهای وب همچون HTML / CSS و Web Assembly ، خروجی‌هایی چون Android / iOS / Windows را با دسترسی کامل به امکانات سیستم‌عامل به همراه برنامه‌های تحت وب SPA و PWA (با یا بدون Pre-Rendering) گرفت.پلتفرم Bit‌ تا به اینجا از دو قسمت Bit Blazor Components (شامل بیش از ۳۰ کمپوننت کاربردی، کم حجم و High Performance مانند Tree / Multi Select / Data Grid / Date Picker / Color Picker و...) به همراه Bit Project Templates (قالب پروژه‌های حاوی امکانات پر استفاده) تشکیل شده است.برخی مواردی که در رابطه با آنها صحبت شد، ممکن است برای شما آشنا نباشند، بنابراین قبل از بررسی مفصل‌ تر Bit Platform، نگاهی به آن می اندازیم:وب اسمبلی چیست؟برای درک بهتر وب اسمبلی ابتدا باید بدانیم این تکنولوژی اصلا از کجا آمده و هدف آن چیست؟میدانیم که مرورگر ها پروایدر صفحات وب هستند و ما برای اینکه بتوانیم اپلیکیشنی که ساختیم را در محیط وب برای کاربران به اشتراک بگذاریم باید از این مرورگر ها و زبان ارتباطی آن ها پیروی کنیم. این زبان های ارتباطی مشخصا  سه چیز است: HTML CSS JavaScript اما آیا راهی هست که بتوان بجای JavaScript از زبان های دیگر هم در سمت مرورگر استفاده کرد؟ وب اسمبلی یا همان WASM، آمده تا به ما اجازه دهد از هر زبانی که خروجی به Web Assembly دارد، برای تعاملات UI استفاده کنیم. یعنی با زبان هایی مثل #C / C++ / C و... میتوان کدی نوشت که مرورگر آن را اجرا کند. این یک تحول بزرگ است که امروزه تمامی مرورگرها (به جز مرورگرهایی که از دور خارج شده اند) از آن پشتیانی می‌کنند چرا که Web Assembly به یکی از اجزای استاندارد وب تبدیل شده است.اطلاعات بیشتر در رابطه با وب اسمبلی را میتوانید از این مقاله بخوانید.تعریف SPA و PWA:SPA: Single Page ApplicationPWA: Progressive Web Applicationدر گذشته برای رندر کردن صفحات وب با عوض شدن URL یا درخواست کاربر برای دریافت اطلاعات جدید از سرور و نمایش آن، صفحه مرورگر ملزم به رفرش شدن مجدد و از سر گیری کل فرایند تولید HTML میشد. طبیعتا این تکرار برای کاربر هنگام استفاده از اپلیکیشن خیلی خوشایند نبود چرا که هربار میبایست زمانی بیشتر صرف تولید مجدد صفحات را منتظر میماند. اما در مقابل آن Single Page Application (SPA) ها این پروسه را تغیر داد.در رویکرد SPA ، کل CSS , HTML و JS ای که برای اجرای هر صفحه ای از اپلیکیشن نیاز هست در همان لود اولیه برنامه توسط مرورگر دانلود خواهد شد. با این روش هنگام تغیر URL صفحات مرورگر دیگر نیازی به لود دوباره اسکریپ ها ندارد. همچنین وقتی قرار است اطلاعات جدیدی از سرور آپدیت و نمایش داده شود این درخواست بصورت یک دستور Ajax به سرور ارسال شده و سرور با فرمت JSON اطلاعات درخواست شده را پاسخ میدهد. در نهایت مرورگر نیز اطلاعات برگشتی از سرور را مجدد جای گذاری میکند و کل این روند بدون هیچگونه رفرش دوباره صفحه انجام میشود.در نتیجه این امر، کاربر تجربه خوشایند تری هنگام کار کردن با SPA ها خواهد داشت. اما همانقدر که این تجربه در طول زمان استفاده از برنامه بهبود یافت، لود اولیه اپلیکیشن را کند تر کرد چرا که اپلیکیشن میبایست همه کدهای مورد نیاز خود برای صفحاتش را در همان ابتدا دانلود کند.(در ادامه با قابلیت Pre-Rendering این اشکال را تا حدود زیادی رفع میکنیم)با استفاده از PWA میتوانید وبسایت های SPA را بصورت یک برنامه نصبی و تمام صفحه با آیکون مجزایی همانند اپلیکیشن های دیگر در موبایل و دسکتاپ داشته باشید. همچنین وقتی از PWA استفاده میکنیم  برنامه وب میتواند به صورت آفلاین نیز کار کند. البته حتی در برنامه‌هایی که لازم نیست آفلاین کار کنند، در صورت قطعی ارتباط کاربر با شبکه به جای دیدن دایناسور معروف، اینکه برنامه در هر حالتی باز شود و به صورتی کاربر پسند و قطعی نت به وی اعلام شود ایده خیلی بهتری است (&quot;:قابلیت Pre-Rendering:هدف Pre-Rendering بهبود گشت گذار کاربر در سایت است. شیوه کارکرد آن به این صورت است که وقتی کاربر وارد وبسایت میشود، سرور در همان ابتدای کار و جلوتر از اتمام دانلود اسمبلی ها، فایلی حاوی HTML ، CSS های صفحه ای که کاربر درخواست کرده را در سمت سرور می‌سازد و به مرورگر ارسال میکند. در همین حین، اسمبلی ها نیز توسط مرورگر دانلود می‌شوند و برنامه از محتوای صرف خارج شده و حالت تعاملی می‌گیرد. اصطلاحا به این قابلیت Server-Side Rendering (SSR) نیز میگویند. در این حالت کاربر زودتر محتوایی از برنامه را میبیند و تجربه بهتری خواهد داشت. این امر در بررسی Search Engine ها و سئو وبسایت نیز تاثیر بسزایی دارد.نگاهی به Blazor:تا اینجا هر آنچه که نیاز بود برای درک بهتر از Blazor بدانیم را فهمیدیم، اما خود Blazor چیست؟ در یک توضیح کوتاه، فریمورکی ارائه شده توسط مایکروسافت میباشد برای پیاده‌سازی UI و منطق برنامه‌ها شامل امکانات Routing، Binding و...بلیزر در انواع مختلفی ارائه شده که هرکدام کاربرد مشخصی دارد:Blazor Serverدر بلیزر سرور پردازش ها جهت تعامل UI درون سرور اجرا خواهد شد. برای مثال وقتی کاربر روی دکمه ای کلیک میکند و آن دکمه مقداری عددی را افزایش می‌دهد که از قضا متن یک Label به آن عدد وابسته است، رویداد کلیک شدن این دکمه توسط SignalR WebSocket به سرور ارسال شده و سرور تغیر متن Label را روی همان وب سوکت به کلاینت ارسال می‌کند.با توجه به این که تعامل کاربر با صفحات برنامه، بسته به میزان کندی اینترنت کاربر، ممکن است کند شود و همچنین Blazor Server قابلیت PWA شدن ندارد و علاوه بر این بار پردازش زیادی روی سرور می‌اندازد (بسته به پیچیدگی پروژه) و در نهایت ممکن است در آن از Component هایی استفاده کنیم که چون در حالت Blazor Server پردازش سمت سرور بوده، متوجه حجم دانلود بالای آنها نشویم و کمی بعدتر که با Blazor Hybrid می‌خواهیم خروجی Android / iOS بگیریم متوجه حجم بالای آنها شویم، استفاده از Blazor Server را در Production توصیه نمی‌کنیم، ولی این حالت برای Debugging بهترین تجربه را ارائه می‌دهد، بالاخص با امکان Hot Reload و دیدن آنی تغییرات C# / HTML / CSS در ظاهر و رفتار برنامه موقع کدنویسی. Blazor WebAssemblyدر بلیزر وب اسمبلی منطق مثال قبلی که با C# .NET نوشته شده است، روی مرورگر و با کمک Web Assembly اجرا می‌شود و نیازی به ارتباط جاری با سرور توسط SignalR نیست. این باعث میشود که با بلیزر وب اسمبلی بتوان اپلیکیشن های PWA نیز نوشت.یک برنامه Blazor Web Assembly می‌تواند چیزی در حدود دو الی سه مگ حجم داشته باشد که در دنیای امروزه حجم بالایی به حساب نمیاید، با این حال با کمک Pre Rendering و CDN می‌توان تجربه کاربر را تا حدود زیادی بهبود داد.برای مثال سایت Component های Bit Platform جزو معدود دموهای Component های Blazor است که در حالت Blazor Web Assembly ارائه می‌شود و شما می‌توانید با باز کردن آن، تجربه حدودی کاربرانتان را در حین استفاده از Blazor Web Assembly ببینید. به علاوه، در dotnet 7 سرعت عملکرد Blazor Web Assembly بهبود قابل توجهی پیدا کرده است.Blazor Hybridاز Blazor Hybrid زمانی استفاده می‌کنیم که بخواهیم برنامه‌های موبایل را برای Android , iOS و برنامه‌های Desktop را برای ویندوز، با کمک HTML , CSS توسعه دهیم. نکته اصلی در Blazor Hybrid این است که اگر چه از Web View برای نمایش HTML / CSS استفاده شده، اما منطق سمت کلاینت برنامه که با C# .NET توسعه داده شده است، بیرون Web View و به صورت Native اجرا می‌شود که ضمن داشتن Performance بالا، به تمامی امکانات سیستم عامل دسترسی دارد. علاوه بر دسترسی به کل امکانات Android / iOS Sdk در همان C# .NET ، عمده کتابخانه‌های مطرح مانند Firebase، با ابزار Binding Library ارائه شده توسط مایکروسافت، دارای Wrapper قابل استفاده در C# .NET هستند و ساختن Wrapper برای هر کتابخانه Objective-C ، Kotlin، Java، Swift با این ابزار فراهم است.اگر شما در حال حاضر فقط #HTML , CSS , C بدانید، اکنون با بلیزر میتوانید هر اپلیکیشنی که بخواهید توسعه دهید. از وبسایت های SPA گرفته تا اپ های موبایل Android ، IOS و برنامه های دسکتاپی برای Windows , Mac و بزودی نیز برای Linuxسری آموزش بلیزر را میتوانید از این لینک ها (1 ، 2) دنبال کنید.معرفی پکیج Bit Blazor UI: پکیج Bit Blazor UI مجموعه ای از کامپوننت های مرسومی است که بر پایه بلیزر نوشته شده و به ما این امکان را میدهد تا المان های پیچیده ای مثل Date Picker , Grid , Color Picker , File Upload , DropDown و بسیاری از المان های دیگر را با شکلی بهینه، بدون نیاز به اینکه خودمان بخواهیم برای هر یک از اینها از نو کدنویسی کنیم، آن را در اختیار داشته باشیم.عمده مشکل کامپوننت های ارائه شده برای بلیزر حجم نسبتا بالای آن است که باعث میشد بیشتر در مصارفی از قبیل ایجاد Admin Panel کارایی داشته باشد. اما این موضوع به خوبی در Bit Blazor UI مدیریت شده و در حال حاضر با بیش از 30 کامپوننت با حجم بسیار پایینی، چیزی حدود 200 کیلوبایت قابل نصب است. از لحاظ حجمی نسبت به رقبای خود برتری منحصر به فردی دارد که باعث میشود به راحتی حتی در اپلیکیشن های موبایل هم قابل استفاده باشد و کماکان پرفرمنس خوبی ارائه دهد.این کامپوننت ها با ظاهر Fluent پیاده سازی شده و میتوانید لیست کامپوننت های بلیزر Bit را از این لینک ببینید.معرفی Bit TodoTemplate: قبل از اینکه به معرفی Bit TodoTemplate بپردازیم باید بدانیم که اصلا پروژه های Template چه هستند. در واقع وقتی شما Visual Studio را باز میکنید و روی گزینه Create New Project کلیک میکنید با لیستی از پروژه های تمپلیت روبرو میشوید که هرکدام چهارچوب خاصی را با اهدافی متفاوت در اختیارتان قرار میدهند.Bit Platform هم  Project Template ای با نام TodoTemplate توسعه داده که میتوانید پروژه های خودتان را از روی آن بسازید، اما چه امکاناتی به ما میدهد؟در یک جمله، هر آنچه تا به اینجا توضیح داده شد بصورت یکجا در TodoTemplate وجود دارد.در واقع TodoTemplate چهارچوبی را فراهم کرده تا شما تنها با دانستن همین مفاهیمی که در این مقاله خواندید، از همان ابتدا امکاناتی چون صفحات SignUp، SignIn یا Email Confirmation و... را داشته باشید و در نهایت بتوانید تمامی خروجی های قابل تصور را بگیرید.اما چگونه؟در TodoTemplate همه این قابلیت ها تنها درون یک فایل و با کمترین تغیر ممکن نوع خروجی کدی که نوشته اید را مشخص میکند. این تنظیمات به شکل زیر است:        &lt;BlazorMode&gt; ... &lt;/BlazorMode&gt;        &lt;WebAppDeploymentType&gt; ... &lt;/WebAppDeploymentType&gt;شما میتوانید با تنظیم &lt;BlazorMode&gt; بین انواع hosting model های بلیزر سوییچ کنید. مثلا برای زمانی که در محیط development هستید نوع بلیزر را Blazor Server قرار دهید تا از قابلیت های debugging بهتری برخوردار باشید، وقتی میخواهید وبسایت تکمیل شده تان را بصورت SPA / PWA پابلیش کنید نوع بلیزر را به Blazor WebAssembly و برای پابلیش های  Android ، IOS ، Windows ، Mac نوع بلیزر را به Blazor Hybrid تغیر دهید.به علاوه، شما تنها با تغیر &lt;WebAppDeploymentType&gt; قادر خواهید بود بین SPA (پیش فرض)، SSR و PWA سوئیچ کنید.قابلیت های Todo-Template در اینجا به پایان نمیرسد و بخشی دیگر از این قابلیت ها به شرح زیر است:وجود سیستم Exception handling در سرور و کلاینت (این موضوع به گونه ای بر اساس Best Practice ها پیاده سازی شده که اپلیکیشن را از بروز هر خطایی که بخواهد موجب Crash کردن برنامه شود ایزوله کرده)وجود سیستم User Authentication بر اساس JWT که شما در همان ابتدا که از این تمپلیت پروژه جدیدی میسازید صفحات SignIn ، SignUp را خواهید داشت. پکیج Bit Blazor UI که بالاتر درمورد آن صحبت کرده ایم از همان ابتدا در TodoTemplate نصب و تنظیم شده تا بتوانید به راحتی صفحات جدید با استفاده از آن بسازید.کانفیگ استاندارد Swagger در سمت سرور.ارسال ایمیل در روند SignUp.وجود خاصیت AutoInject برای ساده‌سازی تزریق وابستگی ها.و بسیاری موراد دیگر که در داکیومنت های پروژه میتوانید آنهارا ببینید.با استفاده از TodoTemplate پروژه ای با نام Todo ساخته شده که میتوانید چندین مدل از خروجی های این پروژه را در لینکهای پایین ببینید و پرفرمنس آن را بررسی کنید.- Todo app with pre rendering- Todo app PWA- Todo Android app in App Centerتوجه داشته باشید هدف TodoTemplate ارائه ساختار Clean Architecture نبوده، بلکه هدف ارائه بیشترین امکانات با ساده‌ترین حالت کدنویسی ممکن بوده که قابل استفاده برای همگان باشد و شما میتوانید از هر پترنی که میخواهید براحتی در آن استفاده کنید.پلتفرم Bit یک تیم توسعه کاملا فعال تشکیل داده که بطور مداوم در حال بررسی و آنالیز خطاهای احتمالی ، ایشو های ثبت شده و افزودن قابلیت های جدید میباشد که شما به محض استفاده از این محصولات میتوانید در صورت بروز هر اشکال فنی برای آن ایشو ثبت کنید تا تیم مربوطه آن را بررسی و در دستور کار قرار دهد. در ادامه پلتفرم Bit قصد دارد بزودی تمپلیت جدیدی با نام Admin Panel Template با امکاناتی مناسب برای Admin Panel مثل Dashboard و Chart و... با تمرکز بر Clean Architecture نیز ارائه کند. چیزی که مشخص است اوپن سورس بودن تقریبا %100 کارها میباشد از جلسات و گزارشات کاری گرفته تا جزئیات کارهایی که انجام میشود و مسیری که در آینده این پروژه طی خواهد کرد .میتوانید اطلاعات بیشتر و مرحله به مرحله برای شروع استفاده از این ابزار ها را در منابعی که معرفی میشود دنبال کنید.منابع :سایت Bit Platformشروع کار با Bit Blazor UIشروع کار با TodoTemplateمشارکت در پروژه :شما میتوانید این پروژه را در گیتهاب مشاهده کنید.برای اشکالات یا قابلیت هایی که میخواهید برطرف شود Issue ثبت کنید.پروژه را Fork کنید و Star دهید.ایشوهایی که وجود دارد را برطرف کنید و Pull Request ارسال کنید. برای در جریان بودن از روند توسعه در جلسات برنامه ریزی (Planning Meeting) و گزارشات هفتگی (Standup Meeting) که همه اینها در Microsoft Teams برگزار میشود شرکت کنید.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Tue, 12 Jul 2022 11:23:09 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش زمانبندی کارها با HangFire در Asp.Net Core</title>
                <link>https://virgool.io/dotnetzoom/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hangfire-%D8%AF%D8%B1-aspnet-core-gn4yeejcbafx</link>
                <description>در این مقاله برای نمایش کد ها از GitHub Gist استفاده شده و ممکن است Load شدن کد ها کمی طول بکشد یا به نرم افزار های رفع تحریم نیاز داشته باشید.تسک های پس زمینه (Background Job) چیست؟بطور کلی تسک های پس زمینه کارهایی هستند که برنامه باید بصورت خودکار در زمان های مشخص آن هارا انجام دهد برای مثال :شرایطی را در نظر بگیرید که متدی با حجم زیادی از محاسبات پیچیده دارید که وقتی کاربر درخواست خود را ارسال میکند شروع به محاسبه میشود و کاربر جاری چاره ای جز انتظار نخواهد داشت اما اگر اینکار در زمانی دیگر قبل از درخواست کاربر محاسبه میشد و صرفا نتیجه به کاربر نمایش داده میشد قطعا تصمیم بهتری نسبت به محاسبه آنی آن متد در زمان درخواست کاربر بوده.در سناریو دیگر تصور کنید میخواهید هر شب در ساعتی مشخص خلاصه ای از مطالب وبسایتتان را برای کاربران وبسایت ایمیل کنید در این حالت برنامه باید هر شب در فلان ساعت اینکار را برای ما انجام دهد و تماما باید این اتفاق بدون دخالت هیچ اراده انسانی و بصورت خودکار توسط برنامه انجام گیرد.همچنین شرایطی از این قبیل ، ارسال ایمیل تایید هویت یک ساعت بعد از ثبت نام ، گرفتن بک آپ از اطلاعات برنامه بصورت هفتگی و دیگر این موارد همه در دسته تسک های پس زمینه(Background Job) از یک برنامه قرار دارند.سوال : HangFire چیست؟همانطور که دانستید تسک های پس زمینه نیاز به یک سیستم مدیریت زمان دارد که کارها را در زمان های مشخص شده به انجام برساند. HangFire یک پکیج متن باز برای ایجاد سیستم زمانبندی شده کارها است و اینکار را به ساده ترین روش انجام خواهد داد.همچنین HangFire در کنار Quartz که یک سیستم دیگر جهت پیاده سازی زمانبندی است از معروف ترین پکیج ها برای زمانبندی تسک های پس زمینه بشمار میرود که در ادامه بیشتر به مزایا و معایب این دو میپردازیم.مقایسه HangFire و Quartz : میتوان گفت این دو پکیج تا حد زیادی شبیه به هم هستند و تفاوت اصلی آن ها در لایه های زیرین و نوع محاسبات زمانی که هریک نهفته است که الگوریتم مختص به خود را برای این محاسبه دارند اما در نهایت یک کار را انجام میدهند.دیتابیس :تفاوتی که میتوان از آن نام برد وجود قابلیت Redis Store در HangFire است که Quratz چنین قابلیتی را از سمت خودش اراعه نداده و برای استفاده از Redis در Quartz باید شخصا این دو را باهم کانفیگ کنید. دیتابیس Redis بخاطر ساختار دیتابیسی که دارد سرعت و پرفرمنس بالاتری را اراعه میدهد که استفاده از این قابلیت در پروژه هایی با تعداد تسک ها و رکورد های زیاد کاملا مشهود است. البته این ویژگی در HangFire رایگان نیست و برای داشتن آن از سمت HangFire لازم است هزینه آن را نیز پرداخت کنید اما اگر هم نمیخواهید پولی بابتش بپردازید و همچنان از آن استفاده کنید یک پکیج اوپن سورس برای آن نیز طراحی شده که از لینک پایین میتوانید مشاهده کنید. https://github.com/marcoCasamento/Hangfire.Redis.StackExchange ساختار :پکیج HangFire از ابتدا با دات نت و معماری های دات نتی توسعه داده شده اما Quartz ابتدا برای زبان جاوا نوشته شده بود و به نوعی از این زبان ریلیزی برای دات نت تهیه شد و این موضوع طبعا تاثیرات خودش را داشته و برخی از معماری ها و تفکرات جاوایی در آن مشهود است که البته مشکلی ایجاد نمیکند و محدودیتی نسبت به HangFire از لحاظ کارکرد دارا نیست شاید تنها چیزی که میتوان در این باب گفت DotNet Friendly تر بودن HangFire است که کار با متد های آن آسان تر و به اصطلاح خوش دست تر است.داشبورد :هردو پکیج از داشبورد پشتیبانی میکنند که میتوانید در این داشبورد و ui اختصاصی که برای نمایش تسک ها طراحی شده تسک های ایجاد شده را مدیریت کنید. داشبورد HangFire بصورت پیشفرض همراه با آن قرار دارد که بعد از نصب HangFire میتوانید براحتی داشبورد سوار بر آن را نیز مشاهده کنید اما در Quartz ، داشبورد باید بصورت Extension در پکیجی جدا به آن اضافه شود و مورد استفاده قرار گیرد. در لینک پایین دوتا از بهترین داشبورد ها برای Quartz را مشاهده میکنید که در صورت نیاز میتوانید از آن استفاده کنید. https://github.com/jlucansky/Quartzmin  https://github.com/guryanovev/CrystalQuartz استفاده از HangFire :1. نصب :برای نصب HangFire در پروژه Asp.Net Core لازم است ابتدا پکیج های مورد نیاز آن را نصب کنید که شامل :Install-Package Hangfire.Core Install-Package Hangfire.SqlServerInstall-Package Hangfire.AspNetCoreپس از نصب پکیج ها باید تنظیمات مورد نیاز برای پیاده سازی HangFire در برنامه را اعمال کنیم. این تنظیمات شامل افزودن سرویس ها و اینترفیس های HangFire به برنامه است که اینکار را با افزودن HangFire به متد ConfigureService کلاس Startup انجام خواهیم داد : https://gist.github.com/sajadkardel/b2fe809e07e406eea12e6beeb8ba6d6e پکیج HangFire برای مدیریت کار و زمان ، Table هایی دارد که پس از نصب روی دیتابیس برنامه شما قرار میگیرد فقط باید دقت داشته باشید ConnectionString دیتابیس خود را در متد AddHangFire مقدار دهی کنید تا از این طریق دیتابیس برنامه را شناخته و Table های مورد نظر را در Schema جدیدی با نام HangFire به آن اضافه کند.پ ن : HangFire بصورت پیشفرض با دیتابیس SqlServer  ارتباط برقرار میکند.این پکیج یک داشبورد اختصاصی دارد که در آن لیستی از انواع تسک های در صف انجام و گزارشی از انجام شده ها را در اختیار ما قرار میدهد. برای تنظیم این داشبورد باید Middleware مربوط به آن و endpoint جدیدی برای شناسایی مسیر داشبورد HangFire در برنامه را در متد Configure کلاس Startup اضافه کنید : https://gist.github.com/sajadkardel/fb9088bf0aab1f506b297577a922c0f6 برای اینکه به داشبورد HangFire دسترسی داشته باشید کافیست پس از نصب و انجام تنظیمات مذکور ، برنامه را اجرا کنید و در انتهای Url برنامه ، کلمه &quot;hangfire&quot; را وارد کنید سپس وارد پنل داشبورد آن خواهید شد.http://localhost:50255/hangfireالبته میتوانید آدرس داشبورد HangFire در برنامه را از کلمه &quot;hangfire&quot; به هر چیزی که میخواهید شخصی سازی کنید. برای اینکار کافیست درون Middleware تعریف شده بصورت ورودی string آدرس جدیدی برای HangFire تعریف کنید.app.UseHangfireDashboard(&amp;quot/mydashboard&amp;quot);و به طبع در Url :http://localhost:50255/mydashboard2. داشبورد :داشبورد HangFire شامل چندین بخش و تب مختلف است که به اختصار هر یک را بررسی خواهیم کرد.تب Job :همه تسک های تعریف شده شامل Enqueued, Succeeded, Processing, Failed و... در این تب نشان داده میشود.تب Retries :این تب مربوط به تسک هایی است که در روال زمانبندی و اجرا به دلایل مختلف مثل Stop شدن برنامه توسط iis یا Down شدن سرور و یا هر عامل خارجی دیگر شکست خوردند و در زمانبندی مشخص شده اجرا نشدند. همچنین قابلیت دوباره به جریان انداختن job مورد نظر را در اختیار ما قرار میدهد که از این طریق میتوان تسک های از دست رفته را مدیریت کرد و دوباره انجام داد.تب Recurring Jobs :وقتی شما یک تسک مانند گرفتن بکاپ از دیتابیس بصورت ماهانه تعریف میکنید و قرار است در هر ماه این اتفاق رخ دهد این یک تسک تکراری تلقی شده و این تب مسئول نشان دادن اینگونه از تسک ها میباشد.تب Servers :این بخش سرویس هایی که HangFire برای محاسبه زمانبندی از آن استفاده میکند را نشان میدهد. وقتی متد services.AddHangfireServer را به متد ConfigureService کلاس Startup اضافه میکنید سرویس های HangFire جهت محاسبه زمانبندی ها فعال میشود.3. امنیت داشبورد :همانطور که دانستید داشبورد ، اطلاعات کاملی از نوع کار و زمان اجرای آن و نام متدها  را در اختیار ما قرار میدهد و همچنین اجازه تغییراتی مثل حذف یک تسک یا دوباره به اجرا در آوردن تسک ها و یا اجرای سریع تسک های به موعد نرسیده را به کاربر میدهد. گاهی ممکن است این اطلاعات شامل محتوایی امنیتی و غیر عمومی باشد که هرکسی در برنامه حق دسترسی به آنهارا ندارد. برای مدیریت کردن این امر میتوانید مراحل زیر را طی کنید :مرحله اول :  یک کلاس ایجاد میکنیم (مثلا با نام MyAuthorizationFilter) که این کلاس از اینترفیسی با نام IDashboardAuthorizationFilter ارث بری خواهد کرد. https://gist.github.com/sajadkardel/5d5f2d9470e9e04d2c8a8daa732021f9 درون این کلاس متدی با نام Authorize از اینترفیس مربوطه impliment میشود که شروط احراز هویت و صدور یا عدم صدور دسترسی را کنترل میکند. این متد یک خروجی Boolian دارد که اگر هر یک از شروط احراز هویت شما تایید نشد خروجی false برمیگرداند. در این مثال ما برای دسترسی محدودیت Login بودن را اعمال کرده ایم که این را از HttpContext میگیریم.مرحله دوم : در این مرحله کلاسی که بعنوان فیلتر احراز هویت برای کاربران ساخته ایم را در option های middleware پکیج HangFire اضافه میکنیم. https://gist.github.com/sajadkardel/06fb146cfda06d14a37b33d7fd323f9b یکی دیگر از option های این middleware که میتوان برای کنترل دسترسی در HangFire استفاده کرد آپشن Read-only view نام دارد. https://gist.github.com/sajadkardel/f73171e49cd2e6b69fbb3f4a2b31a52a  این آپشن اجازه هرگونه تغییر در روند تسک ها از طریق صفحه داشبورد را از هر کاربری سلب میکند و داشبورد را صرفا به جهت نمایش کار ها استفاده میکند نه چیز دیگر.انواع تسک ها در HangFire : 1. تسک های Fire-And-Forget :تسک های Fire-And-Forget زمانبندی خاصی ندارند و بلافاصله بعد از فراخوانی اجرا میشوند. برای مثال شرایطی را در نظر بگیرید که میخواهید پس از ثبت نام هر کاربر در وبسایت ، یک ایمیل خوش آمد گویی ارسال کنید. این عمل یک تسک پس زمینه تلقی میشود اما زمانبندی خاصی نیز نمیخواهید برایش در نظر بگیرید در چنین شرایطی میتوانید از متد Enqueue استفاده کنید و یک تسک Fire-And-Forget ایجاد کنید تا این تسک صرفا در تسک های پس زمینه تان نام برده شود و قابل مشاهده باشد. https://gist.github.com/sajadkardel/b3324e010d4ee653c96ff95848e72553 همانطور که میبینید در مثال بالا ابتدا برای استفاده از تسک های Fire-and-Forget در HangFire باید اینترفیس IBackgroundJobClient را تزریق کنیم و با استفاده از متد Enqueue در این اینترفیس یک تسک پس زمینه ایجاد میکنیم که کار آن فراخوانی متد SendWelcomeMail خواهد بود.2. تسک های Delayed : همانطور از اسم آن پیداست تسک های Delayed تسک هایی هستند که با یک تاخیر در زمان اجرا خواهند شد. بطور کلی زمانبندی این تسک ها به دو دسته تقسیم میشود : دسته اول : اجرا پس از تاخیر در زمان مشخص.همان شرایط ارسال ایمیل به کاربرانی که در وبسایتتان ثبت نام میکنند را در نظر بگیرید اما اینبار میخواهید نه بلافاصله بلکه 10 دقیقه بعد از ثبت نام کاربر ایمیل خوش آمد گویی را ارسال کنید. در این نوع شما یک تاخیر 10 دقیقه ای میخواهید که Delayed Job ها اینکار را برای ما انجام میدهند. https://gist.github.com/sajadkardel/52f55f6f9bc8e2629e3ba93e8514d262 در این مثال با استفاده از متد Schedule در اینترفیس IBackgroundJobClient توانستیم متد SendWelcomeMail را صدا بزنیم و با ورودی TimeSpan یک تاخیر 10 دقیقه ای در متد HangFire اعمال کنیم.همچنین میتوانید از ورودی های دیگر TimeSpan شامل  TimeSpan.FromMilliseconds و  TimeSpan.FromSecondsو TimeSpan.FromMinutes و TimeSpan.FromDays برای تنظیم تاخیر در تسک های خود استفاده کنید.دسته دوم : اجرا در زمان مشخص.نوع دیگر استفاده از متد Schedule تنظیم یک تاریخ و زمان مشخص برای اجرا شدن تسک های در آن تاریخ و زمان واحد میباشد. برای مثال سناریو ای را در نظر بگیرید که دستور اجرا و زمانبندی آن در اختیار کاربر باشد و کاربر بخواهد یک Reminder در تاریخ مشخص برایش ارسال شود که در اینصوررت میتوانید با استفاده از instance دیگری از متد Schedule که ورودی ای از جنس DateTimeOffset دریافت میکند ، تاریخ مشخص برای اجرا انتخاب کنید. https://gist.github.com/sajadkardel/496c958231b6d57d48e4337f34cb4bab در این مثال تاریخ مشخص برای اجرای تسک های خود را از کاربر در ورودی اکشن دریافت کرده ایم و به متد Schedule در غالب DateTimeOffset تعریف شده پاس میدهیم.3. تسک های Recurring :تسک های Recurring به تسک هایی گفته میشود که باید در یک بازه گردشی از زمان اجرا شوند. در یک مثال بیشتر با آن آشنا خواهیم شد. فرض کنید میخواهید هر هفته برنامه از اطلاعات دیتابیس موجود بکاپ بگیرد. در اینجا تسکی دارید که قرار است هر هفته و هربار به تکرر اجرا شود. https://gist.github.com/sajadkardel/58739a4ec12c713cf6cd8c9504a4beb2 برای تنظیم یک Recurring Job باید اینترفیس دیگری بنام IRecurringJobManager را تزریق کرده و متد AddOrUpdate را استفاده کنید. در ورودی این متد یک جنس تعریف شده در HangFire بنام Cron دریافت میشود که بازه گردش در زمان را دریافت میکند که در اینجا بصورت هفتگی است.انواع دیگر Cron شامل : هر دقیقه (Cron.Minutely) :این Cron هر دقیقه یکبار اجرا خواهد شد. _recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; job , Cron.Minutely);هر ساعت (Cron.Hourly) :این Cron هر یک ساعت یکبار و بصورت پیشفرض در دقیقه اول هر ساعت اجرا میشود._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Hourly);اما میتوانید یک ورودی دقیقه به آن بدهید که در اینصورت در N اُمین دقیقه از هر ساعت اجرا شود. _recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Hourly(10)); هر روز (Cron.Daily) :این Cron بصورت روزانه و در حالت پیشفرض در اولین ساعت و اولین دقیقه هر روز اجرا خواهد شد._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Daily);در حالتی دیگر میتوانید ورودی ساعت و دقیقه را به آن بدهید تا در ساعت و دقیقه ای مشخص در هر روز اجرا شود._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Daily(3,10)); هر هفته (Cron.Weekly) :این Cron هفتگی است. بصورت پیشفرض هر هفته شنبه در اولین ساعت و در اولین دقیقه اجرا میشود._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Weekly);در حالتی دیگر چندمین روز هفته و ساعت و دقیقه مشخص را در ورودی میگیرد و حول آن میچرخد._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job,Cron.Weekly(DayOfWeek.Monday,3,10));هر ماه (Cron.Monthly) :این Cron بصورت ماهانه اولین روز ماه در اولین ساعت روز و در اولین دقیقه ساعت زمانبندی خود را اعمال میکند._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Monthly);و در صورت دادن ورودی میتوانید زمانبندی آن در چندمین روز ماه در چه ساعت و دقیقه ای را نیز تنظیم کنید._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Monthly(10,3,10));هر سال (Cron.Yearly) :و در نهایت این Cron بصورت سالانه و در اولین ماه ، روز ، ساعت و دقیقه هر سال وظیفه خود را انجام خواهد داد._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Yearly);که اینهم مانند بقیه ، ورودی هایی دریافت میکند که به ترتیب شامل ماه ، روز ، ساعت و دقیقه است._recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; Job, Cron.Yearly(2,4,3,10));در نهایت با استفاده از این Cron ها میتوانید انواع مختلفی از Recurring Job هارا بسازید.4. تسک های Continuations :این نوع از تسک های ، وابسته به تسک های دیگر هستند و بطور کلی وقتی استفاده میشود که ما میخواهیم تسکی را پس از تسک دیگری با یک زمانبندی به نسبت زمان اجرای تسک اول ، اجرا کنیم. برای مثال میخواهیم 10 دقیقه بعد از ثبت نام کاربر برای او ایمیل احراز هویت ارسال شود که شبیه اینکار را در تسک های Delayed انجام داده بودیم. اما همچنین قصد داریم 5 دقیقه بعد از ارسال ایمیل احراز هویت لینک فرستاده شده را منسوخ کنیم. در این سناریو ما دو زمانبندی داریم اول 10 دقیقه بعد از ثبت نام کاربر و دوم 5 دقیقه بعد از اجرای متد اول. https://gist.github.com/sajadkardel/6f007357fb1138d16f77761236d96ed7 برای ایجاد یک Continuations Job باید از متد ContinueJobWith در اینترفیس IBackgroundJobClient  استفاده کنیم و در ورودی اول این متد آیدی تسک ایجاد شده قبلی را پاس دهیم.برخی از نکات و ترفند های HangFire :1. استفاده از Cron Expression در Recurring Job ها :بطور کلی Cron ها ساختاری تعریف شده برای تعیین بازه های زمانی است. Cron اختصار یافته کلمات Command Run On میباشد که به اجرا شدن یک دستور در زمان مشخص اشاره دارد. برای استفاده از آن ابتدا به تعریف این ساختار میپردازیم :  https://gist.github.com/sajadkardel/83d9afe714c732868defdd6c4d886319 این ساختار را از پایین به بالا در زیر برایتان تشریح میکنیم :* * * * *فیلد اول (Minute) : در این فیلد بایستی دقیقه ای مشخص از یک ساعت را وارد کنید.مانند دقیقه 10 (میتوانید محدوده هم تعیین کنید)فیلد دوم (Hour) : در این فیلد بایستی زمان معلوم را با فرمت ساعت وارد کنید.مانند ساعت 7 (میتوانید محدوده هم تعیین کنید) ، مانند ساعات 12-7فیلد سوم (Day of Month) : در این فیلد بایستی یک روز از ماه را وارد کنید مانند روز 15 ام از ماه (میتوانید محدوده هم تعیین کنید)فیلد چهارم (Month) : در این فیلد بایستی یک ماه از سال را وارد کنید مثلا ماه 4 ام(آوریل) (میتوانید محدوده هم تعیین کنید)فیلد پنجم (Day of Week) : در این فیلد بایستی روزی از روز های هفته یا محدوده ای از آن روز ها را تعیین کنید.مانند صفرم هفته که در کشور های اروپایی و آمریکایی معادل روز یکشنبه است.همانطور که میبینید Cron ها دسترسی بهتری از تعیین بازه های زمانی مختلف اراعه میدهند که میتوانید از آن در Recurring متد ها بجای ورودی های Yearly - Monthly - Weekly - Daily - Hourly - Minutly استفاده کنید. در واقع خود این ورودی ها نیز متدی تعریف شده در کلاس Cron هستند که با فراخوانی آن خروجی Cron Expression میسازند و در درون ورودی متد Recurring قرار میگیرند. در ادامه مثالی خواهیم زد تا نیازمندی به Cron Expression ها را بیشتر درک کنید. فرض کنید میخواهید یک زمانبندی داشته باشید که &quot;هر ماه بین بازه 10 ام تا 15 ام ،  بطور روزانه در ساعت 4:00&quot; اجرا شود. اعمال این زمانبندی با متد های معمول در کلاس Cron امکان پذیر نیست اما میتوانید با Cron Expression این را اعمال کنید که به این شکل خواهد بود : 0 4 10-15 * *برای ساخت Cron Expression ها وبسایت هایی وجود دارند که کمک میکنند انواع Cron Expression های پیچیده را طراحی کنیم و با استفاده از آن زمانبندی های دقیق تر و جزئی تر بسازیم. یکی از بهترین وبسایت ها برای اینکار crontab.guru است.پ ن : برای استفاده از Cron Expression در متد های Recurring کافی است بجای ورودی های Yearly - Monthly - Weekly - Daily - Hourly - Minutly ، خود Cron Expression را درون ورودی متد تعریف کنیم : _recurringJobManager.AddOrUpdate(&amp;quottest&amp;quot, () =&gt; job , &amp;quot0 4 10-15 * *&amp;quot );2. متد Trigger : متد Trigger یک متد برای اجرای آنی تسک ها Recurring است که به کمک آن میتوانید این نوع از تسک های را بدون در نظر گرفتن زمانبندی آن در لحظه اجرا کنید و البته تاثیری در دفعات بعدی تکرار نداشته باشد.RecurringJob.Trigger(&amp;quotsome-id&amp;quot);3. تعیین تاریخ انقضا برای  Recurring Job ها : گاهی ممکن است در تسک های Recurring شرایطی پیش آید که برفرض میخواهید کاری را هر ماه انجام دهید اما این تکرار در پایان همان سال تمام میشود. در اینصورت باید یک Expire Time برای متد Recurring خود تنظیم کنیم تا بعد از 12 ماه تکرار در تاریخ 140X/12/30 به پایان برسد. HangFire برای متد های Recurring ورودی با عنوان ExpireTime تعریف نکرده اما میتوان از طریق ایجاد یک زمانبندی Schedule تاریخ مشخصی برای حذف کردن متد Recurring تعریف کرد همانند یک ExpireTime عمل میکند. https://gist.github.com/sajadkardel/0301ec39846292b1429bebe165d38560 با اجرای این متد اول کاری برای تکرار در زمانبندی ماهیانه ایجاد میشود و در متد دوم زمانی برای حذف متد اول مشخص میکند.در آخر امیدوارم این مقاله برایتان مفید واقع شده باشد. میتوانید فیدبکتان را در قالب کامنت یا یک قهوه برایم ارسال کنید. https://coffeebede.ir/buycoffee/sajadkardel مقالات بیشتر در دات نت زومhttps://t.me/DotNetZoom</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Sun, 09 May 2021 13:31:48 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش Cache در Asp.Net Core (قسمت دوم : EasyCaching)</title>
                <link>https://virgool.io/dotnetzoom/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-cache-%D8%AF%D8%B1-aspnet-core-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-ljkjb2vs1xcn</link>
                <description>در این مقاله برای نمایش کد ها از GitHub Gist استفاده شده و ممکن است Load شدن کد ها کمی طول بکشد یا به نرم افزار های رفع تحریم نیاز داشته باشید.در قسمت اول درمورد سیستم Cache دیفالت موجود در Asp.Net Core و مزیت ها و معایب آن گفتیم.  قسمت اول مقاله را میتوانید از این لینک بخوانید. https://vrgl.ir/9mIBO در این قسمت میخواهیم یک پکیج محبوب و کاربردی برای پیاده سازی کش در Asp.Net Core را بررسی کنیم.در دنیای امروز برنامه نویسی ، پکیج ها و فریمورک ها نقش بسیار مهمی را ایفا میکنند بطوری که در بسیاری ازین موارد استفاده از این پکیج ها عمل عاقلانه تری نسبت به دوباره نویسی فیچر های مربوطه است.برای عمل کشینگ در Asp.Net Core نیز پکیج های فوقالعاده ای وجود دارد که در این مقاله به بررسی و استفاده از پکیج EasyCaching میپردازیم.در این پکیج هر یک از متد های موجود در عملیات کشینگ بصورت بهینه ای تعریف شده که قابل استفاده است. سیستمی که این پکیج برای کش کردن داده ها استفاده میکند همان سیستم کش Asp.Net Core هست و بنوعی سوار بر این سیستم قابلیت های بیشتر و بهتری را اراعه میدهد.این متد ها شامل :TrySet/TrySetAsyncSet/SetAsyncSetAll/SetAllAsyncGet/GetAsync(with data retriever)Get/GetAsync(without data retriever)GetByPrefix/GetByPrefixAsyncGetAll/GetAllAsyncRemove/RemoveAsyncRemoveByPrefix/RemoveByPrefixAsyncRemoveAll/RemoveAllAsyncFlush/FlushAsyncGetCountGetExpiration/GetExpirationAsyncRefresh/RefreshAsync(This will be discarded later, just use set directly) یکی از قابلیت های دیگر این پکیج سازگاری آن با انواع Cache Provider های موجود است. بطور خلاصه Cache Provider ها همان اراعه دهندگان حافظه Ram در قالب ها و ابزارهای مختلف هستند. برخی از این ها با داشتن الگوریتم های بهینه تر ، سرعت بالاتری از ردو بدل کردن اطلاعات در Ram را در اختیار ما قرار میدهند و Local بودن یا Distributed بودن را کنترل میکنند. Cache provider های گوناگونی وجود دارد که هریک به شکلی کار میکند ، برای مثال شما میتوانید با Provider ای مستقیما با خود Ram برای Get و Set کردن کش های خود در ارتباط باشید و یا در روشی دیگر از یک دیتابیس(Redis) ، جدا از دیتابیس اصلی برنامه ، که حافظه مصرفی آن Ram هست و منابع حافظه شمارا نیز مدیریت میکند ، برای کش های خود استفاده کنید  و اطلاعات را بصورت ایندکس گذاری شده در Ram ذخیره کنید که به سرعت واکشی آن میفزاید.بطور کل Cache Provider هایی که پکیج EasyCaching با آن ها سازگار است شامل :In-MemoryMemcachedRedis(Based on StackExchange.Redis)Redis(Based on csredis)SQLiteHybridDiskLiteDbیکی دیگر از مزیت های این پکیج سازگاری آن با Serializer های مختلف است. همانطور که میدانید دیتا های ورودی و خروجی در برنامه نیاز به Serialize شدن دارند. وقتی میخواهید دیتایی در دیتابیس ذخیره کنید آن را در قالب یک شی (Model) از کاربر دریافت میکنید و شما باید برای ذخیره این دیتا ، اطلاعات درون شی را به قالبی که قابل ذخیره شدن باشد در آورید که این عمل Serialize نام دارد. دقیقا برعکس این روند بعد از واکشی اطلاعات از دیتابیس ، اطلاعات را در قالب اشیایی که قابل نمایش به کاربر باشد (DeSerialize) در میاوریم.در کش کردن هم چیزی که شما با آن سروکار دارید دیتا است پس برای ذخیره و واکشی این دیتا از هر حافظه ای چه دیتابیس چه Ram باید از یک Serializer استفاده کنید تا عملیات Serialize و DeSerialize را برایتان انجام دهد. Serializer  های مختلفی وجود دارد که بصورت پکیج هایی اراعه شده اند و اما Serializer  هایی که سیستم EasyCaching آن هارا پشتیبانی میکند شامل :BinaryFormatterMessagePackNewtonsoft.JsonProtobufSystem.Text.Jsonدر ادامه به پیاده سازی کش با استفاده از EasyCaching در سه Provider مختلف از این پکیج میپردازیم.1_ پروایدر InMemory :پروایدر InMemory یک سیستم Local Caching را برای ما به وجود میاورد. (در قسمت قبلی مقاله سیستم های Local(InMemory) و Distributed را بررسی کردیم و تفاوت های میان آن ها را گفتیم.)برای استفاده از پروادر InMemory در EasyCaching باید پکیج زیر را نصب کنید :Install-Package EasyCaching.InMemoryدر مرحله بعد کانفیگ های مربوط به این پکیج را در کلاس Startup برنامه خود میاوریم :راحت ترین روش افزودن این پکیج به Startup صرفا افزودن حالت پیشفرض آن به متد ConfigureServices است که به شرح زیر عمل میکنیم : https://gist.github.com/sajadkardel/6a613272d506676611c300d11194ffd2 این حالت از کانفیگ پکیج ، تنظیمات دیفالت خود پکیج را برای برنامه قرار میدهد و شما میتوانید با استفاده از option های دیگر که در متد ()UseInMemory وجود دارد تنظیمات شخصی سازی شده از سیستم کشینگ خود را اعمال کنید.و تمام. هم اکنون میتوان با استفاده از اینترفیس IEasyCachingProvider که این سرویس در اختیارمان قرار داده و عمل تزریق وابستگی آن در کلاس ها و کنترلر های مان دیتای در حال عبور را کش کنیم. متد های موجود در این اینترفیس به شرح زیر میباشد :  https://gist.github.com/sajadkardel/f3cd53e88b3ff39c9e92682193cedeb0 همانطور که قبلا گفته شد سیستم کش با دیتا مرتبط است و نیازمند یک Object Serializer جهت Serialize کردن اطلاعات ورودی و ذخیره آن در Target Storage مشخص شده است.پکیج EasyCaching برای Provider های خود یک Object Serializer دیفالت قرار داده است و تا وقتی که شما آن را طبق نیازی خاص بصورت کاستوم تغییر نداده باشید از آن استفاده میکند.در میان پنج Serializer معرفی شده که EasyCaching آن هارا ساپورت میکند ، BinaryFormatter بصورت دیفالت در همه Provider ها برقرار است و تا وقتی که یک Serializer انتخابی به EasyCaching معرفی نکنید این پکیج از این Serializer استفاده میکند.برای استفاده از Serializer های دیگری که معرفی شده میتوانید از لینک های زیر کمک بگیرید :MessagePackNewtonsoft.JsonProtobufSystem.Text.Json2 _ پروایدر Redis :ردیس یک دیتابیس Key Value محور هست که محل ذخیره سازی آن Ram هست و اطلاعات بصورت موقت در آن ذخیره میشود. بطور خلاصه Key Value یعنی یکبار کلید و مقداری برای آن کلید تعریف میشود و هروقت نام کلید تعریف شده صدا زده شد مقدار نسبت داده شده به آن در اختیار ما قرار میگیرد. برای مثال کلید &quot;Name&quot; و مقدار &quot;James&quot;. با این انتصاب هروقت &quot;Name&quot; فراخوانده شود مقدار &quot;James&quot; را خواهیم داشت. سیستم Key Value بخاطر عدم پیچیدگی و سادگی ای که دارد بسیار سریع عمل میکند و همچنین ایندکس گذاری هایی که ردیس روی دیتا ها انجام میدهد باعث افزایش سرعت آن نیز خواهد شد که ردیس را به سریع ترین دیتابیس Key Value دنیا تبدیل کرده.در اینجا با توجه به قابلیت هایی که ردیس داراست یکی از بهترین گزینه ها برای انتخاب بعنوان فضای ذخیره سازی کش ها بصورت Distributed است. برای استفاده از این دیتابیس قدرتمند ابتدا باید از طریق یکی از روش های معمول اقدام به نصب آن کنید. میتوانید فایل نصبی را از وبسایت رسمی آن دانلود کنید و یا یا با استفاده از Docker اقدام به نصب آن نمایید.پس از نصب این دیتابیس روی سیستم خود ، برای استفاده از آن در EasyCaching ابتدا باید پکیج مورد نیاز را نصب کنید.Install-Package EasyCaching.Redisادامه کار به همان سادگی پروایدر قبلی هست و فقط کافیست EasyCaching و option ردیس را به کلاس Startup اضافه کنید. https://gist.github.com/sajadkardel/fd18a917badcbb544df4cf1ab4007215 با استفاده از متد UseRedis شما قابلیت استفاده از ردیس را در EasyCaching فعال میکنید و سپس باید اطلاعات Host و Port ردیس نصب شده روی سیستم خود را به این متد معرفی کنید.اگر ردیس را بدون تنظیمات شخصی سازی شده و در همان حالت دیفالت خودش نصب کرده باشید Host و Port شما مانند نمونه بالا 127.0.0.1 و 6379 خواهد بود و نیازی به تغییر نیست.در مرحله بعد برای استفاده از پروایدر ردیس ، اینترفیس IRedisCachingProvider در سرتاسر برنامه در دسترس خواهد بود. این اینترفیس علاوه بر اینکه متد های اصلی موجود در EasyCaching را ساپورت کرده ، بخاطر ساختار دیتابیسی که خود ردیس در اختیار ما قرار میدهد قابلیت های بیشتری نیز اراعه خواهد داد. این قابلیت ها خصیصه های ردیس هست چرا که  این دیتابیس هم دقیقا شبیه به ساختار سیستم کش Key , Value را پشتیبانی میکند و در پی آن قابلیت هایی برای مدیریت بهتر کلید ها و مقادیر اراعه میدهد.اینترفیس IRedisCachingProvider شامل تعداد زیادی از متد ها برای پشتیبانی از قابلیت های ردیس است که در ادامه همه آنهارا نام برده و برخی را توضیح مختصری خواهیم داد :متد های Keys https://gist.github.com/sajadkardel/31f37d9bb6817daffe99b41d833c0cf3 متد های String https://gist.github.com/sajadkardel/acc7662d61be50754fa0809c8eac169b متد های Hashes https://gist.github.com/sajadkardel/5d445599d64fed9ddc396b00bf9a3eb9 متد های List https://gist.github.com/sajadkardel/47feecd3c0e3852f2e10fa9f5da82767 متد های Set https://gist.github.com/sajadkardel/fdb87cb498f0e239935c347cba029e14 متد های Stored Set https://gist.github.com/sajadkardel/2d29996d114587c084cfc2d5c5a68108 متد های Hyperloglog https://gist.github.com/sajadkardel/ca13228927ef5e9cf1fdb3a2f0fc862a متد های Geo https://gist.github.com/sajadkardel/1ebea94c35c50e78068c11cbaa776e1f برای اطلاعات بیشتر از متد های دیگر موجود در ردیس میتوانید از این لینک استفاده کنید.3_ پروایدر Hybrid :این پروایدر روشی از کشینگ مابین Local Caching و Distributed Caching را اراعه میدهد و میتوانید از یک پروایدر Local مثل InMemory و پروایدر Distributed مثل Redis همزمان باهم استفاده کنید که در یک کانال باهم و در راستای هم کار میکنند.اما سوال اینجاست که این قابلیت دقیقا چه کاری انجام میدهد؟همانطور که قبلا گفته شد کش In-Memory سرعت بالاتری نسبت به کش Distributed دارد اما دچار معایبی در حالت چند سروری هست که این معایب از جمله حذف شدن دیتا یک سرور در صورت Down شدن آن ، Sync نبودن کش سرور ها باهم دیگر و دو نسخه کش کردن دیتا در هر سرور و موارد دیگر که میتوان نام برد.اما از طرفی کش Distributed مشکلات چند سروری را با قرار دادن یک مرکزیت واحد کش در حافظه شبکه شده سرور ها برطرف میکند و اطلاعات سرور ها از یک منبع خوانده میشود و طبعا مشکلات In-Memory را نخواهیم داشت اما به دلیل ردو بدل شدن دیتا در محیط شبکه و عمل Serialize , Deserialize که هنگام عبور دیتا روی آن صورت میگیرد ، بخشی از سرعت کاهش خواهد یافت و درنهایت Performance کمتری نسبت به In-Memory اراعه میدهد.حالا برای اینکه بتوانیم سیستم کش خودمان را طوری طراحی کنیم که عیب های (Local)In-Memory و Distributed را نداشته باشیم و هم بتوانیم از هریک به شکلی درست استفاده کنیم که هم اطلاعاتمان Sync باشد و هم از سرعت بالای In-Memory برخوردار شویم میتوانیم از پروایدر Hybrid استفاده کنیم.شیوه کار این پروایدر به این صورت است که وقتی برنامه برای بار اول به کش In-Memory درخواستی ارسال میکند و کش مورد نظر در آن وجود ندارد ، برنامه یک درخواست دیگر به کش Distributed ارسال میکند و دیتای مورد نظر را به کاربر بازگشت میدهد و علاوه بر آن یک کپی از کش آن دیتا ، در کش In-Memory هم ایجاد میکند. با این ساختار از دفعات بعد که کاربر درخواستی ارسال کند دیتای درخواستی در In-Memory نیز موجود خواهد بود و سریع تر از بار اول پاسخ را ارسال خواهد کرد.از طرفی نیز وقتی کاربر دیتای جدیدی را ذخیره میکند ابتدا آن دیتا در In-Memory کش شده و سپس با درخواست خود پروایدر در کش Distributed هم اعمال میشود تا در نهایت دیتابیس نیز آن را ذخیره کند.وقتی این اتفاق میفتد پروایدر Hybrid با کمک پکیج Bus.Redis به کش In-Memory سرور های دیگر دستور Pull کردن دیتا کش های جدید را ارسال میکند و در نهایت همه سرور ها نیز به کمک Distributed مرکزی باهم Sync خواهند بود.برای فعال سازی این پروایدر باید پکیج های زیر را در برنامه خود نصب کنید:Install-Package EasyCaching.HybridCacheInstall-Package EasyCaching.InMemoryInstall-Package EasyCaching.RedisInstall-Package EasyCaching.Bus.Redisدر این مجموعه از پکیج ها از یک پروایدر Local(InMemory) و یک پروایدر distributed(Redis) استفاده شده و همانطور که گفته شد مدیریت هماهنگ سازی این دو توسط پکیج دیگری بنامEasyCaching.Bus.Redisصورت میگیرد.تنظیمات فعالسازی این پروایدر هم متشکل از تنظیمات دو پروایدر In-Memory و Redis بعلاوه معرفی این دو به هم در متد UseHybrid خواهد بود. https://gist.github.com/sajadkardel/c357f0f7b6aeab853532924ca62acc47 برای استفاده از این پروایدر باید اینترفیس IHybridCachingProvider را فراخوانی کنیم. متد های موجود در این اینترفیس همان متد هایی است که در اینترفیس IEasyCachingProvider وجود دارد و از نظر نام متد و روش استفاده تفاوتی میان آن نیست.پیشنهاد شخصی در Distributed Cache ها : همانطور که گفته شد Distributed کش ها گزینه مناسب تری برای برنامه های چند سروری هست اما در این حالت مواردی مثل  Round Trip شبکه و جابجایی اطلاعات در این محیط بعلاوه Serialize , Deserialize هایی که باید انجام شود دلیلی میشود تا سرعت آن در پاسخ به درخواست های برنامه نسبت به حالت تک سروری(In-Memory) کمتر باشد. Hybrid Provider یکی از روش های حل این مشکل بوده که معرفی کردیم. اما برای اینکه تیر خلاص را به پیکره سیستم Distributed Cache خود بزنید و تریک فنی آخر را نیز روی آن اجرا کنید پیشنهاد میکنم از پکیج EasyCaching.Extensions.EasyCompressor که بر پایه پکیج EasyCaching نوشته شده استفاده کنید. این پکیج اطلاعات را قبل از کش شدن فشرده سازی میکند و حجم اطلاعات را به طور محسوسی کاهش میدهد که میزان فضای اشغالی Ram را کم کرده و همچنین عمل جابجایی اطلاعات را نیز تسریع میبخشد. میتوانید از این پکیج هم در Redis و هم در Hybrid استفاده کنید. چگونگی استفاده از آن نیز در لینک Github ذکر شده موجود است.معرفی پروژه :تا اینجا با مفاهیمی که برای شروع استفاده حرفه ای از کش در پروژه تان نیاز بود ، آشنا شدید. در پروژه های واقعی میتوانیم از این سیستم به روش های مختلفی در سطوح مختلفی از برنامه استفاده کنیم برای مثال کد های مربوط به عملیات کش را میتوان بصورت ساده در هر کنترلر تزریق و در اکشن ها استفاده کرد یا از لایه کنترلر آن را به لایه سرویس منتقل کرد ، در روشی دیگر میتوانیم یک Attribute برای این عمل در نظر بگیریم و یا اینکه آن را بصورت یک Middleware اختصاصی در برنامه پیاده کنیم. https://github.com/sajadkardel/EasyCaching در این پروژه علاوه بر اینکه سعی کرده ام استفاده از Provider های معرفی شده را در محیط واقعی تر پیاده سازی کنم ، علاوه بر آن در هر پروژه از این Solution کش را به شیوه ای متفاوت در لایه های مختلفی از برنامه قرار داده ام تا شما همراهان بتوانید طبق نیازتان از روشی مناسب و بهینه در پروژه های واقعی خود از آن استفاده کنید. https://coffeebede.ir/buycoffee/sajadkardel مقالات بیشتر در دات نت زوم https://t.me/DotNetZoom</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Mon, 29 Mar 2021 22:26:24 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@Kavekardel/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7%DB%8C-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B9-eiysbqqagcqa</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/wmw7k5wctdp4-7dnaL.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۵,۷۴۹ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۱۸ مرتبه پسندیدند و  ۴ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۴ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۴۴۲ بار خوانده شدند و ۵۳,۲۱۱ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۰۷۲۹۵۱۷ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۲,۱۱۱ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۰۷۲۹۵۱۷ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Mon, 22 Mar 2021 23:43:39 +0430</pubDate>
            </item>
                    <item>
                <title>آموزش Cache در Asp.Net Core (قسمت اول : مفاهیم اولیه)</title>
                <link>https://virgool.io/@Kavekardel/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-cache-%D8%AF%D8%B1-aspnet-core-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-itox6yopizht</link>
                <description>در این مقاله برای نمایش کد ها از GitHub Gist استفاده شده و ممکن است Load شدن کد ها کمی طول بکشد یا به نرم افزار های رفع تحریم نیاز داشته باشید.امروزه در وبسایت های شخصی و تجاری یکی از مهم ترین پارامتر ها سرعت پاسخگویی درخواست ها به وبسایت است. طبق آمار ، کاربران آنلاین کنونی که ما با آن ها طرفیم سطح تحملشان به سه ثانیه در یک صفحه میرسد پس ما باید بتوانیم سرعت وبسایت های خودمان را تا حد ممکن بهبود بخشیم. از طرفی پارامتر سرعت ، روی سئو گوگل هم تاثیر بسزایی داره و Ranking وبسایت شمارا تا حد زیادی افزایش میدهد. قطعا همه میدانید که سرعت وبسایت و برنامه چقدر مهم هست پس زیاده گویی نمیکنیم و میرویم سراغ اصل مطلب.یکی از کارهایی که میتوانیم برای افزایش سرعت برنامه انجام دهیم استفاده از Cache هست. خیلی ساده Cache یعنی قرار دادن دیتای پرکاربرد در یک حافظه نزدیک تر از دیتابیس که هروقت به آن نیاز داشتیم دسترسی سریعی داشته باشیم و سرعت واکشی اطلاعات از سرعتی که دیتابیس به ما میدهد بیشتر باشد تا درخواست های ما با پاسخ سریع تری همراه شوند.این حافظه Ram هست و عمل Caching به اینصورت خواهد بود که هر وقت دیتای مورد نظر یکبار از دیتابیس واکشی شود از دفعات بعد آن دیتا را در Ram ذخیره میکند و برای درخواست های بعدی به دیتابیس Query نمیزند و دیتای مورد نیازش را از Ram میگیرد.این امر در کنار مزایایی که دارد ، حساسیت بالایی هم بهمراه خواهد داشت چرا که حافظه مورد استفاده Ram و یک حافظه محدود هست همچنین میتواند برای هر سخت افزاری متفاوت باشد پس پیاده سازی این سیستم نیاز به دو دو تا چهارتا و ساختار درست دارد ، در غیر اینصورت Cache کردن دیتای غلط میتواند به تنهایی وبسایتتان را Down کند پس خیلی باید به این موضوع دقت داشت.چه زمانی از کش استفاده کنیم؟وقتی دیتایی داریم که به تکرار از آن در برنامه استفاده میکنیم.وقتی بعد از گرفتن دیتایی از دیتابیس محاسبات روی آن انجام میدهیم و پاسخ نهایی محاسبه را به کاربر نمایش میدهیم میتوانیم یکبار پاسخ را کش کنیم تا از محاسبه هر باره آن جلوگیری شود.آیا همه اطلاعات را میتوان کش کرد؟خیر.سخت افزاری که برای کش استفاده میکنیم یعنی Ram بسیار گران تر از دیتابیس برای ما تمام میشود چرا که محدود است.اگر همه دیتاهارا کش کنید عمل سرچ میان آن زمان بیشتری خواهد برد.پس اکنون میدانید که میتوانیم داده های بی نهایت در دیتابیس ذخیره کنیم و فقط با ارزش ترین ها و پر مصرف ترین هارا در حافظه کش ذخیره میکنیم.عملیات Cache در Asp.Net Core  توسط اینترفیس های IMemoryCache  و IDistributedCache مدیریت میشود و میتوانید با تزریق این اینترفیس ها براحتی از متدهایشان استفاده کنید اما قبل از استفاده لازم است با عملکرد هر یک آشنا شویم.روش اول : In-memory Caching (Local Caching)معمول ترین و ابتدایی ترین روش برای کش کردن اطلاعات روش Local Caching و بصورت In-Memory است که اطلاعات را در حافظه Ram همان سروری که برنامه در آن اجرا میشود کش میکند.این روش تا زمانی که برنامه ما برای اجرا شدن تنها از یک سرور استفاده کند بهترین انتخاب خواهد بود چرا که به دلیل نزدیک بودن سریع ترین بازخورد را نیز به درخواست ها اراعه میدهد.اما شرایطی را فرض کنید که برنامه از چندین سرور برای اجرا شدن استفاده میکند و به طبع هر سرور درخواست های خودش را داراست که ما باید برای هر یک بصورت جداگانه یک کش In-Memory در حافظه Ram هرکدام ایجاد کنیم.فرض کنید دیتای ما 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 باشد. بخشی از دیتا در Server 1 کش میشود (1 , 3 , 5 , 9) و بخشی دیگر در Server 2 کش خواهد شد (2 , 4 , 6 ,7 , 8 , 10).در اینجا مشکلات و ضعف هایی به وجود خواهد آمد : برای مثال اگر Server 1 به هر دلیلی از بین برود یا Down شود اطلاعات کش درون آن نیز پاک خواهد شد و بعد از راه اندازی باید همه آن را دوباره از دیتابیس بخواند.هر کدام از سرور ها کش های جدایی دارند و باهم Sync نیستند و امکان وجود یک داده حیاتی در یکی و عدم وجود آن در دیگری بالاست. فرض کنید برنامه برای هر درخواست نیاز به اطلاعات دسترسی کاربر دارد. دسترسی های کاربر در Server 1 کش شده اما در Server 2 موجود نیست. در Server 2 به دلیل عدم وجود این کش ، برنامه برای درخواست های معمول خود و چک کردن دسترسی کاربر یا باید هربار به دیتابیس درخواست ارسال کند که این برخلاف خواسته ماست و یا باید دیتای مربوط به دسترسی های کاربر را بعد از یکبار درخواست از دیتابیس در خودش کش کند که اینهم دوباره کاری به حساب میاید و دوبار کش کردن یک دیتا امر مطلوبی نخواهد بود.روش هایی وجود دارد که بتوان از سیستم Local Caching در حالت چند سروری هم استفاده کرد و این مشکلات را از بین برد اما روش استاندارد در حالت چند سروری استفاده از Distributed Cache ها است.روش دوم : Distributed Cachingدر این روش برنامه ما برای اجرا شدن از چندین سرور شبکه شده به هم در حال استفاده هست  و Cache برنامه توسط سرورها به اشتراک گذاشته شده.در این حالت سرور های ما از یک کش عمومی استفاده میکنند که مزایای آن شامل :■ درخواست ها به چندین سرور مختلف از هم ارسال شده اما دیتای کش بصورت منسجم در هریک وجود خواهد داشت.■ با خراب شدن یا Down شدن یک سرور ، کش موجود در سرور های دیگر پاک نمیشود و کماکان قابل استفاده است.■ به حافظه Ram یک سرور محدود نیست و مشکلات زیادی همچون کمبود سخت افزاری و محدودیت های حافظه Ram را تا حد معقولی کاهش میدهد.طریقه استفاده از Cache در Asp.Net Core :بر خلاف ASP.NET web forms و ASP.NET MVC در نسخه های Core به بعد Cache بصورت توکار وجود ندارد. کش در Asp.Net Core با فراخوانی سرویس های مربوطه آن قابل استفاده است و نیاز است قبل از استفاده سرویس آن را در کلاس Startup برنامه فراخوانی کنید. https://gist.github.com/sajadkardel/adf2583f5716e4e8e023222d90818e76  اینترفیس IMemoryCache از سیستم تزریق وابستگی در Core استفاده میکند و برای استفاده از اینترفیس آن ، پس از اضافه کردن MemoryCache به Startup ، باید در کنترلر عمل تزریق وابستگی (DI) را انجام دهید سپس متد های مورد نیاز برای کش در دسترس خواهد بود. https://gist.github.com/sajadkardel/a633ea81d0c319a59aeed725f10f9e69 برای ذخیره کش میتوانید از متد Set موجود در این اینترفیس استفاده کنید. https://gist.github.com/sajadkardel/fccb7e121bb00aa43c6de9b17ac31b01 در پارامتر اول این متد (CacheKey) یک کلید برای اطلاعاتی که میخواهیم کش کنیم قرار میدهیم. دقت کنید که این کلید شناسه دیتای شماست و باید طوری آن را در نظر گرفت که با صدا زدن این کلید از سرویس کش همان دیتای مورد نظر را برگشت دهد (هر Object دیتا باید کلید Uniq خود را داشته باشد).در پارامتر دوم دیتای مورد نظر که میخواهیم کش کنیم را به متد میدهیم و در پارامتر سوم نیز زمان اعتبار و تاریخ انقضای دیتای کش شده را وارد میکنیم به این معنی که دیتای کش شده بعد از مدت زمان گفته شده از حافظه کش(Ram) حذف شود و برای دسترسی دوباره و کش کردن دوباره اطلاعات ، نیاز به خواندن مجدد از دیتابیس باشد.برای دسترسی به اطلاعات کش شده میتوانید از متد Get استفاده کنید. https://gist.github.com/sajadkardel/60ffe9261caf7ae4f4c0233520d61387 تنها پارامتر ورودی این متد کلید از قبل نسبت داده شده به اطلاعات کش هست که با استفاده از یکسان بودن کلید در ورودی این متد و کلید Set شده از قبل در حافظه Ram ، دیتا مربوط به آن را برگشت میدهد.متد TryGetValue برای بررسی وجود یا عدم وجود یک کلید در حافظه کش هست و یک Boolean خروجی میدهد. https://gist.github.com/sajadkardel/50d09798263aa7491d9ab49569eb8f19 این متد ابتدا بررسی میکند که کلیدی با نام  &quot;CacheKey&quot;  وجود دارد یا خیر. در صورت عدم وجود آن را میسازد و دیتای مورد نظر را به آن نسبت میدهد.با استفاده از متد GetOrCreate میتوانید کار متد های Get و Set را باهم انجام دهید و در یک متد وجود یا عدم وجود کش را بررسی و در صورت وجود مقدار را return و در صورت عدم وجود ، ابتدا ایجاد کش و بعد return مقدار کش شده را انجام دهید. https://gist.github.com/sajadkardel/a6047b1c2d9b014ca1d3b5d1da4dbbb6 برای مدیریت حافظه Ram شما باید یک Expiration Time برای کش های خود مشخص کنید تا هم حافظه Ram را حجیم نکنید و هم در هر بازه زمانی دیتای بروز را از دیتابیس بخوانید. برای این کار option های متفاوتی از جمله absolute expiration و sliding expiration وجود دارد.در اینجا absolute expiration به این معنی است که یک زمان قطعی را برای منقضی شدن کش ها مشخص میکند به عبارتی میگوییم کش با کلید فلان در تاریخ و ساعت فلان حذف شود.اما در sliding expiration یک بازه زمانی برای منقضی شدن کش ها مشخص میکنیم یعنی میگوییم بعد از گذشت فلان دقیقه از ایجاد کش ، آن را حذف کن.این تنظیمات را میتوانید در قالب یک option زمان Set کردن یک کش به آن بدهید. https://gist.github.com/sajadkardel/b7d47616f1bd28a64eb232542c169c51 در مثال بالا هردو option اضافه شده یک کار را انجام میدهند با این تفاوت که absolute expiration تاریخ now را گرفته و یک دقیقه بعد را به آن اضافه کرده و تاریخ انقضای کش را با آن تاریخ set میکند. اما sliding expiration از حالا بمدت یک دقیقه اعتبار دارد.یکی از روش های مدیریت حافظه Ram در کش ها این است که برای حذف شدن کش ها از حافظه اولویت بندی هایی تعریف کنید. اولویت ها در چهار سطح قابل دسترسی است:1_ NeverRemove = 32_ High = 24_ Normal = 15_ Low = 0این الویت بندی ها زمانی کاربرد خواهد داشت که حافظه اختصاصی Ram برای کش ها پر شده باشد و در این حالت سیستم کشینگ بصورت خودمختار کش های با الویت پایین را از حافظه حذف میکند و کش ها با الویت ببیشتر در حافظه باقی میماند. این با شماست که الویت را برای دیتا های خود تعیین کنید پس باید با دقت و فکر شده این کار را انجام دهید. https://gist.github.com/sajadkardel/56c4ebcbc98938e12073ef48db094e13 به این صورت میتوانید الویت های متفاوت را در قالب option به کش های خود اختصاص دهید.در این مقاله سعی شد مفاهیم اولیه Cache طوری گفته شود تا برای افرادی که میخواهند به تازگی این سیستم را بیاموزند و در پروژه های خود استفاده کنند کاربردی باشد و درک نسبی را نسبت به مزایا و محدودیت های این سیستم بدست آورند.در قسمت دوم همین مقاله بطور تخصصی تر به این مبحث میپردازیم و یک پکیج آماده را معرفی میکنیم که خیلی راحت تر و اصولی تر کش را برای ما پیاده سازی میکند. https://coffeebede.ir/buycoffee/sajadkardel مقالات بیشتر در دات نت زوم  https://t.me/DotNetZoom</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Tue, 02 Feb 2021 12:51:28 +0330</pubDate>
            </item>
                    <item>
                <title>✅ معرفی سیستم Logging در  Asp.Net Core</title>
                <link>https://virgool.io/@Kavekardel/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-logging-%D8%AF%D8%B1-aspnet-core-zpbzratv926m</link>
                <description>سیستم Logging  در نسخه Core بصورت پیشفرض موجوده اما در پروژه های غیر Core اگر نیاز به استفاده از اون رو داشتید باید اول پکیج Microsoft.Extensions.Logging.Console رو نصب کنید.طریقه استفاده ازین سیستم بسیار راحته و کانفیگ خیلی خاصی نداره که بخوایم درموردش صحبت کنیم اما قبل از استفاده باید با اصطلاحات اولیه اون آشنا بشیم.چیزی که مسعولیت ثبت Log در برنامه های Core را دارد Logging Api تعریف شده در خود پلتفرم Asp.Net Core میباشد. Log ها طبق این سیستم ذخیره میشوند و توسط Provider های مختلف قابل نمایش میباشند. اما Logging Provider چیست؟ ابزاری که با استفاده از آن میتوانیم Log های ذخیره شده توسط Logger را مشاهده کنیم و یا بعضا دستور ذخیره Log  هارا به Logger  ارسال کنیم.در ادامه لیستی از Logging Provider های موجود را میبینیم که شامل Debug  , Console , EventSource , EventLog , AzureAppService , Application Insights و... میباشد. Log Provider های متنوعی وجود دارد که بعضی از آن ها مزایا و معایب خود را دارند و قابل همگام سازی با سیستم Asp.Net Core Logging میباشند مثل Provider های Serilog , NLog و دیگر پکیج هایی که برای این موضوع وجود دارد.در وهله بعد وقتی صحبت از ذخیره Log ها به میان میاید تعاریفی برای درجه اهمیت هر Log و الویت بندی Log ها مطابق اهمیتشان وجود دارد که به ما کمک میکند دسته بندی و نظم بهتری در Log های برنامه خودمان بیابیم. به این الویت ها اصطلاحا Log Level گفته میشود که به شرح زیر میباشد.◾️الویت 0  Traceگزارش هایی که شامل دقیق ترین پیام ها هستند. این پیام ها ممکن است حاوی داده های حساس برنامه باشند. این پیام ها به طور پیش فرض غیرفعال هستند و هرگز نباید در محیط تولید فعال شوند.◾️الویت 1 Debugاطلاعات مربوط به بررسی لحظه ای در حین رفع خطا یا روند Debuging. این گزارش ها در درجه اول باید حاوی اطلاعات مفید برای رفع اشکال باشند و هیچ ارزش طولانی مدت ندارند.◾️الویت 2 Informationگزارش هایی که جریان کلی برنامه را ردیابی می کنند. این Log ها باید چرخه درازمدت داشته باشند.◾️الویت 3 Warningگزارش هایی که یک رویداد غیر عادی یا غیر منتظره را در جریان برنامه ثبت میکنند ، اما در غیر این صورت باعث توقف اجرای برنامه نمی شوند.◾️الویت 4 Errorگزارش هایی که هنگام توقف جریان اجرای فعلی به دلیل خرابی ، ثبت می شوند. اینها باید نشان دهنده یک شکست در فعالیت فعلی باشد ، نه یک شکست در کل برنامه.◾️الویت 5 Criticalاطلاعات غیرقابل بازیابی برنامه یا خرابی سیستم  که نیاز به توجه فوری دارد.برای فعالسازی Logging پیشفرض در Core ابتدا باید در کلاس Program برنامه Provider مورد استفاده را مشخص کنید. اطلاعات مربوط به Log Level نمایشی برنامه در فایل AppSettingJson قرار دارد که معمولا Log Level نمایشی روی Information قرار دارد و Log هایی با الویت کمتر از Information را نمایش نمیدهد. میتوانید با تغیر در سطح الویت LogLevel اطلاعات مربوط به سطوح پایین تر یعنی Trace و  Debug را نیز مشاهده کنید.روش های دیگری نیز برای دسته بندی Log ها وجود دارد از جمله Log Category یا Log Event Id که میتوانید به سادگی از آن ها استفاده کنید و دسته بندی دلخواه خود را برای Log ها در برنامه داشته باشید.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Sat, 12 Dec 2020 01:08:21 +0330</pubDate>
            </item>
                    <item>
                <title>سوال : Security Stamp چیست؟؟</title>
                <link>https://virgool.io/@Kavekardel/%D8%B3%D9%88%D8%A7%D9%84-security-stamp-%DA%86%DB%8C%D8%B3%D8%AA-pzuuab6an9yc</link>
                <description>در روند احراز هویت کاربران وقتی برای کاربری cookie یا token ست میکنیم عملا احراز هویت برای هر request بعدی توسط اطلاعات ذخیره شده درون cookie یا token کاربر انجام میشود.این اطلاعات شامل هویت و دسترسی های هر کاربر هربار به سرور ارسال شده و در صورت Authorize شدن اجازه دسترسی از سمت سرور ارسال خواهد شد‌.میدانیم که هر کوکی یا توکن یک تاریخ انقضا یا اصطلاحا expiration date دارد که تا زمان سر رسید آن ، کوکی یا توکن مورد نظر معتبر خواهد بود. حالا این بین یعنی قبل از موعد سررسید تاریخ expire ، کاربری از مثلا role خاصی حذف شده باشد ولی در کوکی مرورگر خود آن role را داشته باشد چه خواهد شد؟ جواب ساده است که آن کاربر تا تاریخ منقضی نشدن کوکی همچنان به role موردنظر دسترسی دارد تا اینکه نهایتا کوکی منقضی شود و مجبور به دریافت کوکی جدید شود که با اطلاعات جدید برایش صادر شده و دیگر در آن امکان دسترسی برایش موجود نیست.همینطور که پیداست این یک اشکال بزرگ بشمار میرود و اینجا پای Security Stamp یا همان مهر امنیتی به میان میاید.استفاده از آن به این شکل است که همراه ذخیره اطلاعات کاربر در دیتابیس یک مهر امنیتی(معمولا از جنس Guid) ذخیره میکنیم که کوکی یا توکنی که میسازیم نیز حاوی آن خواهد بود.حالا تنها کاری که باید انجام دهیم این است که هربار اطلاعاتی از کاربر ویرایش شد این مهر امنیتی در دیتابیس تغییر کند. با اینکار در هر request کاربر میتوانیم مهر امنیتی درون کوکی یا توکن را با چیزی که در دیتابیس موجود است مقایسه کنیم. بدیهی است اگر یکسان بود یعنی کاربر ویرایش نشده و اطلاعاتش آخرین آپدیت از خودش را دارد و اما اگر مهر امنیتی آن متفاوت با مهرامنیتی درون دیتابیس بود یعنی کاربر ویرایش شده و ما باید کاربر را logout و به صفحه login هدایت کنیم تا دوباره کوکی یا توکن جدید با آخرین ورژن از اطلاعاتش را دریافت کند.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Fri, 13 Nov 2020 20:09:26 +0330</pubDate>
            </item>
                    <item>
                <title>احراز هویت(Authentication) کاربران با استفاده از Identity</title>
                <link>https://virgool.io/@Kavekardel/%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AAauthentication-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%A7%D9%86-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-identity-kjzpujsv2pon</link>
                <description>اگه این مقاله رو میخونید احتمالا نام Identity به گوشتون خورده و از امکانات اون کمو بیش آگاهید. توی این توضیح سعی کردم عصاره کلام Identity و مبحث احراز هویت رو بطور یکجا تقدیم حضورتون کنم.پرسش : Identity چیست؟؟؟در مجموع کار Identity در مرحله اول به وجود آوردن کاربران و شناسه گذاری برای هر کاربر و در مرحله دوم مدیریت دسترسی ها میان کاربران است. (منظور از کاربر هم User و هم Admin )کانفیگ ها و تنظیمات استفاده از Identity در Asp.Net Coreابتدا پکیج Microsoft.AspNetCore.Identity.EntityFrameworkCore را از Nuget در پروژه Core تان نصب کنید.(دقت کنید اگر این پکیج را نصب میکنید دیگر نیازی به پکیج Microsoft.EntityFrameworkCore نیست و همین پکیج رفرنس های لازم به Microsoft.EntityFrameworkCore را دارا است.)در Startup پروژه باید قابلیت های Identity را فراخوانی و تنظیمات را طبق نیازمان پیاده سازی کنیم. من در این مقاله روند کلی کار را توضیح خواهم داد که شما میتوانید آن را با نیاز های خود سازگار نمایید.ابتدا در متد ConfigureServices باید متد AddIdentity را اضافه کنیم.در متد AddIdentity باید &#x27;IdentityUser&#x27; , &#x27;IdentityRole&#x27; را بصورت جنریک به این متد پاس دهیم. این متد سرویس های UserManager , RoleManager , SigninManager را در خود دارد و قابلیت های مورد نیاز  برای  مدیریت کاربران را در اختیار ما قرار می دهد.کد های درون این متد شامل موارد زیر است که این اعمال را بر عهده دارد :سرویس UserManager کار Add / Edit / Delete کاربر(User) را برعهده دارد.سرویس SignInManager کار Register / Login / LogOut کاربر را بر عهده دارد.سرویس RoleManager کار Add / Edit / Delete نقش(Role) برای کاربر را انجام میدهد.متد بعدی که به Service.AddIdentity اضافه شده متد &#x27;AddEntityFrameWorkStore&#x27; است که در این متد DbContext را بصورت جنریک به آن پاس میدهیمو بعد از آن متد AddDefaultTokenProviders را به Service.AddIdentity اضافه میکنیم که این دو متد برای کارکرد درست سرویس های Identity لازم است.در این متد قابلیت های Identity را نیز میتوانید شخصی سازی کنید.همانطور که از نام option ها مشخص است می توانید محدودیت های پسورد و شروط لاگین در وبسایت را از این طریق کنترل نمایید.سپس در متد Configure کلاس Startup باید MiddleWare های Identity را اضافه کنیم.بطور خلاصه UseAuthentication نقش کاربر را مورد بررسی قرار میدهد و متد UseAuthorization دسترسی ها و محدودیت های نقش کاربر را بررسی میکند.در کلاس Context پروژه بجای ارث بری از &#x27;DbContext&#x27; از &#x27;IdentityDbContext&#x27; ارث بری می کنیم با این کار هم از خاصیت Identity و هم DbContext باهم برخورداریم و هردو کلاس ارث بری می شنود.با این ارث بری بطور خودکار پس از اولین Migration جداول مخصوص Identity به پروژه اضافه خواهد شد.این جداول شامل موارد زیر میباشد.پیاده سازی Register / Login / LogOutبرای مدیریت کاربران و اعمال مربوط به   Register / Login / LogOut  بهتر است یک کنترلر مجزا ترجیهاً با نام AccountController بسازیم و کد های مربوط به این قسمت را در این کنترلر قرار دهیم.ثبت نام (Register) :در اکشن Register کاری که باید انجام دهیم افزودن یک کاربر با اطلاعاتی که میخواهیم به یک کاربر نسبت دهیم است. این اطلاعات طبق چیزی که ما میخواهیم متغیر است و به همان نسبت کد های این اکشن نیز میتواند تغییرات جزئی داشته باشد. برای مثال در جایی نیاز است شماره موبایل کاربر را دریافت نمایید و صحت آن را تایید کنید پس در اکشن Register باید کد های مربوط به ارسال پیام به شماره کاربر را فراخوانی کنید. این روند میتواند در هر پروژه نسبت به نیاز پروژه تغییر کند.ابتدا برای اینکه بتوانیم از سرویس های Identity استفاده کنیم باید آن را در کنترلر مورد نظر inject کنیم.برای این کار به این صورت عمل میکنیم.حالا میتوانیم با استفاده از سرویس_userManager.CreateAsync(user , Password);کاربر مورد نظر را به دیتابیس اضافه کنیم. در این سرویس اطلاعات User از جنس IdentityUser و پسورد از جنس string را در ورودی پاس میدهیم.کاربران در جدول AspNetUser قرار میگیرند.ورود (Login) :در اکشن Login کاری که نیاز است انجام شود تایید اطلاعات وارد شده از سوی کاربر و سپس لاگین کردن کاربر در برنامه. برای این کار نیز سرویس هایی وجود دارد که برای استفاده از آن اینگونه عمل میکنیم.اگر قابلیت های دیگر را نیز فعال کرده باشید مثل تایید ایمیل یا تایید پیامک در این قسمت میتوانید آن را نیز بررسی کنید.قابلیت IsLockedOut تعداد تلاش های ناموفق کاربر برای لاگین را محدود میکند و در حالت پیشفرض پس از هر 5 بار تلاش ناموفق تا چند دقیقه از تلاش کاربر برای ورود جلوگیری میکند. این موضوع از جنبه جلوگیری از هک شدن توسط ربات ها و بدافزار ها اهمیت دارد.خروج (LogOut) : برای خارج کردن کاربر از برنامه از سرویس_signInManager.SignOutAsync();استفاده میکنیم این متد کاربر جاری را که لاگین است لاگ اوت میکند.بطور کلی برای استفاده از قابلیت های دیگر متد های این سرویس هارا مشاهده کنید و به راحتی با پیدا کردن نام آنها بعنوان کلمه کلیدی میتوانید سرچ کنید و از آن استفاده کنید.احراز هویت (Authorization) :در مجموع در Authorization قصد ما این است که دسترسی های کاربر را طبق نقشی که دارد معین کنیم.برای این بخش یکسری کانفیگ ها و تنظیمات وجود دارد که به آن میپردازیم.کدهای بالا مربوط به تنظیمات Cookie در Identity است که آن را در متد ConfigureServices کلاس Startup مینویسیم.آپشن LoginPath و LogOutPath مسیر Login و LogOt پروژه را مشخص میکند.این برای زمانی است که کاربر قصد وارد شدن به جایی را دارد که دسترسی لازم را دارا نیست. در این صورت از اکانت خودش خارج شده و به صفحه لاگین هدایت می شود تا دوباره شاید با اکانتی که دسترسی دارد لاگین کند.آپشن Cookie Name نام کوکی که در مرورگر کاربر ذخیره میشود را مشخص میکند که معمولا نام وبسایت یا برنامه را برای آن قرار میدهند.اگر نمیدانید Cookie چیست بطور خلاصه وقتی عضو وبسایتی میشوید و به اکانت خود لاگین میکنید آن وبسایت یک شناسه به شما میدهد که درون مرورگرتان ذخیره میشود و این شناسه تاریخ انقضا دارد که به این معنی است تا سررسید تاریخ انقضای آن ، شما با این مرورگر از جانب این وبسایت شناخته شده اید و نیازی به دوباره لاگین کردن ندارید. بعد از گذشت این تاریخ دوباره لاگین میکنید و دوباره کوکی جدید برای شما ذخیره میشود.مدت زمان کوکی ها نیز با آپشن ExpireTimeSpan مشخص میشود.احراز هویت بر اساس Role :این نوع احراز هویت بر اساس مقام کاربر صورت میگیرد بعنوان مثال کاربر با مقام Admin باید بتواند به پنل مدیریت دسترسی داشته باشد اما کاربر با مقام User (صرفا به معنای بازدید کننده از برنامه یا وبسایت) نباید بتواند به پنل مدیریت دسترسی داشته باشد.در روش های Authentication روش احراز هویت بر اساس Role ساده ترین روش است که روند آن را در اینجا بررسی میکنیم. ابتدا باید Role های خود را در دیتابیس ثبت کنیم. این عمل توسط ادمین انجام میشود و ما باید سرویس ها و اکشن های مربوط به آن را کد نویسی کنیم.بسیار ساده است و چیزی جز Add / Delete اطلاعات در دیتابیس نیست. مقدار Role ها یک string با هر مقداری که شما میخواهید نام مقام مورد نظر قرار دهید مشخص میشود و هر نامی که در دیتابیس ثبت کنید با همان نام ، احراز هویت صورت میگیرد.پس کاری که انجام میدهیم شامل سه مرحله است:1 _ ایجاد یک Role(با هر نامی که میخواهیم مثلا Admin)2 _ نسبت دادن یک Role به User (مثلا user:sajad has role:Admin)3 _ بررسی Authorization ( چک کردن اینکه فلان User فلان Role را دراد یا نه)برای اینکار پیشنهاد میشود یک کنترلر مجزا برای مدیریت Role ها توسط ادمین در نظر بگیرید و سپس باید سرویس RoleManager&lt;IdentityRole&gt; _roleManager;را در کنترلر خود فراخوانی کنید.در تصویر زیر نحوه افزودن Role و سرویس مورد نظر برای اینکار را مشاهده میکنید.اکشن ویرایش و حذف Role را هم به همین صورت میتوانید پیاده سازی کنید.اطلاعات مربوط به Role در جدول AspNetRole ذخیره میشود.تا اینجا یک مرحله از سه مرحله گفته شده را پیش رفتیم حالا باید کاربر را به مقام مورد نظر نسبت دهیم.برای این کار به سرویس UserManager&lt;IdentityUser&gt; _userManager;نیاز داریم و با استفاده از متد _userManager.AddToRoleAsync( User , roleName );
or
_userManager.AddToRolesAsync( User , List&lt;roleName&gt; );در این سرویس ، کاربر و نام Role  مورد نظر را به متد پاس میدهیم.اطلاعات مربوط به اینکه چه کاربری چه نقش هایی را دارد در جدولی با نام AspNetUserRole ذخیره میشود که جدول واسط بین جداول User و Role است. در این جدول UserId و RoleId قرار دارد که مشخص میکند کدام User به کدام Role متصل است.سرویس متد حذف کردن مقام از یک کاربر نیز به شکل زیر است._userManager.RemoveFromRoleAsync( User , roleName ); 
or
 _userManager.RemoveFromRolesAsync( User , List&lt;roleName&gt; );تا حالا دو مرحله از سه مرحله را انجام دادیم تنها کاری که مانده چک کردن اینکه فلان کاربر فلان مقام را دارد یا خیر.اگر true بود اجازه دسترسی را صادر میکنیم در غیر اینصورت دسترسی مجاز نیست.برای انجام چنین کاری از Attribute های Identity استفاده میکنیم.[Authorize( Roles = &amp;quotAdmin&amp;quot)]
or ...در مثال بالا هر کاربری که نقش Admin را داشته باشد اجازه دسترسی دارد.از این Attribute بالای کنترلر ها یا اکشن هایی که میخواهیم برای آن محدودیت قائل شویم استفاده میکنیم.حالت های دیگری هم برای Attribute ها وجود دارد که به آن میپردازیم. [Authorize( Roles = &amp;quotAdmin , Seller&amp;quot)]در این مثال کاربر باید یا عضو مقام Admin باشد یا عضو مقام Seller[Authorize( Roles = &amp;quotAdmin&amp;quot)]
[Authorize( Roles = &amp;quotSeller&amp;quot)]در این مثال کاربر باید هم عضو مقام Admin باشد هم عضو مقام Seller تا بتواند به کنترلر یا اکشن مورد نظر دسترسی داشته باشد. تفاوت حالت اول و دوم برای زمانی است که دو یا چند Role را میخواهید در یک اکشن یا کنترلر بررسی کنید.[AllowAnonymous]این Attribute اجازه دسترسی برای همه کاربران را صادر میکند و اگر از آن در کنترلر یا اکشنی استفاده کنید همه کاربران با هر نقشی به آن دسترسی خواهند داشت.اگر میخواهید لینکی از صفحه را به کاربری که دسترسی به آن ندارد نمایش ندهید از ابتدا سرویس SignInManager را در Layout خود inject کنید سپس با استفاده از متد @inject SignInManager&lt;IdentityUser&gt; SignInManager

 @if (User.IsInRole(&amp;quotAdmin&amp;quot))      {
            html code....       }لینک یا المنت مورد نظر را از دید کاربر پنهان کنید.احراز هویت با Claim :احراز هویت بر اساس Claim ها میتواند قابلیت های بیشتری نسبت به روش قبلی در اختیار ما قرار دهد. Claim ها نوعی کلید و مقدار ( key , value ) هستند به عنوان مثالClaim1 = &quot;Car&quot; : &quot;red&quot;Claim2 = &quot;Car&quot; : &quot;blue&quot;در اینجا دو Claim داریم که هر دو کلید &quot;Car&quot; اما مقدار متفاوت دارند.در ادامه با Claim ها بیشتر آشنا خواهید شد.برای شروع کار با Claim ها ابتدا کلاسی در پروژه میسازیم و نقش هایی که میخواهیم برای آن دسترسی اعمال کنیم را در آن مینویسیم.در این مثال ما دو نقش Owner و Admin داریم که که وقتی تبدیل به Claim میشود این نام بعنوان کلید یا همان Type هر Claim قرار میگیرد. برای اینکه نقش های خود را به Claim تبدیل کنیم در کلاسی دیگر که لیستی از Claim های مارا برگشت میدهد آن را قرار میدهیم.در پارامتر اول ClaimType ها را وارد میکنیم و پارامتر دوم ClaimValue را فعلا خالی قرار میدهیم. در ادامه راجب Value ها و اینکه چرا برای Admin دو Claim قرار دادم توضیح خواهم داد.بقیه روند مثل Role ها باید Claim ها را به کاربری نسبت داده و پیرو آن احراز هویت را انجام دهیم.برای اینکار از سرویس _userManager.AddClaimAsync( User ,  Claim );
or
 _userManager.AddClaimsAsync( User , IList&lt;Claim&gt;);استفاده میکنیم.از طریق متد RemoveClaimAsync هم میتوانیم کاربری را از Claim مورد نظر Remove کنیم.اطلاعات مربوط به Claim ها در جدول AspNetUserClaim قرار میگیرد.برای استفاده از Claim ها بعنوان کلید احراز هویت خودمان باید تنظیماتی را نیز درون Startup اعمال کنیم.از متد AddAuthorization برای افزودن policy ها استفاده میکنیم. دقت کنید که ما در این نوع احراز هویت ابتدا Claim هارا به policy های ساخته شده پاس میدهیم و در نهایت policy هارا مورد بررسی و عمل احراز هویت قرار میدهیم.برای مثال policy با نام AdminPanel میسازیم که قرار است دسترسی به پنل ادمین را مدیریت کند. حالا Claim با کلید یا همان تایپ Admin را به این Policy میدهیم.زمانی که در کنترلر یا اکشن از اتریبیوت Authorize استفاده میکنیم نیز نام Policy مورد نظر را قرار میدهیم. حالا کاربر برای دسترسی به این Policy باید Claim هایی که درون این Policy  در تنظیمات متد AddAuthorization  تعریف شده را دارا باشد در غیر اینصورت مجوز دسترسی صادر نمیشود.[Authorize(Policy = &amp;quotAll&amp;quot)]
[Authorize(Policy = &amp;quotAdmin&amp;quot)]قبلا درمورد Value ها در Claim ها صحبت کردیم حالا میخواهیم از این خاصیت Claim در احراز هویت استفاده کنیم.ما میتوانیم دو Claim با تایپ یکسان ولی با مقدار متفاوت داشته باشیم برای مثالClaim 1 =    new Claim( &amp;quotAdmin&amp;quot , &amp;quotAdd&amp;quot )
Claim 2 =    new Claim( &amp;quotAdmin&amp;quot , &amp;quotDelete&amp;quot )در این مثال قادر به این هستیم که Admin های با مقدار Add را از Admin با مقدار Delete جدا کنیم و ادمین های با دسترسی های متفاوت داشته باشیم.ادمین با مقدار  Add فقط دسترسی به صفحات پنل مدیریت و دکمه یا همان اکشن Add دارد.ادمین با مقدار  Delete فقط دسترسی به صفحات پنل مدیریت و دکمه یا همان اکشن Delete دارد.برای اعمال این جزئیات در سیستم احراز هویت مقدار Claim های خود را درون کلاس Claims و درون تنظیمات Startup مدیریت کنید.احراز هویت داینامیک (Dynamic Authentication) :این مبحث بدلیل پیچیدگی هایی که در توضیح دارد در این مقاله نمیگنجد و من سعی میکنم زمانی دیگر در مقاله ای جدا بصورت حرفه ای و تخصصی تر درمورد آن بنویسم.ممنون که تا اینجا همراه بودید و از بابت طولانی شدن متن عذرخواهی من را بپذیرید. قصدم این بود آشنایی نسبی با مبحث Identity را به ساده ترین شیوه بیان کنم.فقط به یاد داشته باشید Identity خیلی بزرگ است و روش های متنوعی در Identity برای احراز هویت وجود دارد که هرکدام مزیت ها و معایب خود را دارد پس تحقیق کنید و بهترین روش را سازگار با پروژه خود انتخاب کنید.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Sat, 19 Sep 2020 18:54:08 +0430</pubDate>
            </item>
                    <item>
                <title>نقشه راه مایکروسافت</title>
                <link>https://virgool.io/@Kavekardel/%D9%86%D9%82%D8%B4%D9%87-%D8%B1%D8%A7%D9%87-%D9%85%D8%A7%DB%8C%DA%A9%D8%B1%D9%88%D8%B3%D8%A7%D9%81%D8%AA-hgywuoqr4jrk</link>
                <description>چند وقت پیش مایکروسافت اخباری درمورد آینده پلتفرم Net. و آپدیت جدیدش منتشر کرد که تاثیر قابل توجهی تو گرایش برنامه نویسا داشت و حسابی تو دنیا سرو صدا کرد.اولین تغیری که میشه ازش نام برد نامگذاری این زبان هست که از 3 NET Core. بجای حفظ مراتب نسخه که باید 4 NET Core. نامگذاری میشد به NET 5. تغیر پیدا کرد و کلمه Core ازش کم شد.اما اصلی ترین هدفش اینه که یه سیستم واحد بسازه برای برنامه نویسی در تمام بسترها مثل لینوکس،مک، IOS، اندروید، سیستم‌عامل‌های تلویزیون، اپل واچ ، Web Assembly، ابزارهای متنوع IoT، و بسترهای متفاوت دیگه.خب این چه مزیتی داره چه ارزش خاصیو خلق میکنه؟؟ قضیه از این قراره که اگر همچین وابستگی در یک زبان برنامه نویسی بوجود بیاد و شخص برنامه نویس بتونه با بلد بودن تنها یک زبان برای همه بستر ها کد بزنه و خروجی های متفاوت ایجاد کنه این میتونه خیلی مورد استقبال قرار بگیره و مخاطبای زیادی رو جذب خودش کنه.اما همه داستان این نیست و خیلی فیچرای خوب دیگه هم توراهه که وسوسه انگیزه برای برنامه نویسا و خب تا همین الانشم موفق بوده و خیلی از برنامه نویسا دارن کوچ میکنن به این پلتفرم.مایکروسافت چند سالی هست که در زبان های برنامه نویسی وارد بازار رقابتی شده و اخیرا هم در بین آزمون ها، سرعت و کاراییش خیلی از رقیب هارو کنار زده و رتبه اول رو بدست اورده.این قضیه نشون میده که برنامه نویسی با پلتفرم این شرکت بزرگ کاملا آینده تضمین شده ای داره و اتفاقات خوبی تو این زمینه قراره رخ بده.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Fri, 18 Sep 2020 00:59:49 +0430</pubDate>
            </item>
                    <item>
                <title>پرش 1000 تایی Identity Id در Sql</title>
                <link>https://virgool.io/@Kavekardel/%D9%BE%D8%B1%D8%B4-1000-%D8%AA%D8%A7%DB%8C%DB%8C-identity-id-%D8%AF%D8%B1-sql-juc4qcobt4la</link>
                <description>گاها توی Sql پیش میاد که Identity Id از اخرین مقدارش 1000 یا 10,000 رکورد پرش میکنه و ترتیب اعداد رو بهم میریزه.توی حالت معمول مشکلی ایجاد نمیکنه اما زمانی مهم میشه که از Id برای نمایش یا جایی که ترتیب مهم هست استفاده بشه.دیتابیس Sql وقتی run میشه به طور معمول خودش 1000 سطر بعدی رو برای table رزرو میکنه و درون حافطه رم قرار میده تا برای رکورد های بعدی ازش استفاده کنه مشکل زمانی ایجاد میشه که Sql موقع بسته شدن فرصت خارج کردن این مقادیر از رم رو نداشته باشه و نتونه این رکورد هارو از رزرو خارج کنه مثلا وقتی که یهو برق میره یا تو حالت اجرای برنامه سیستم‌ Force_Shutdown بشه یا هرزمان دیگه ای که ممکنه این اتفاق بیوفته و ما متوجهش نباشیم.برای حل کردن این مشکل لازمه فقط با توجه به یکی نبودن مقادیر Current Identity Value و  Current Column Value اونها رو یکی کنیم. یعنی (Column Value رو در Identity Value) قرار بدیم. هر کدوم از دو دستور زیر این کارو انجام میدن:[CENTER]DBCC CHECKIDENT(table_name)یا DBCC CHECKIDENT(&#x27;table_name&#x27;,RESEED,1)GODBCC CHECKIDENT(&#x27;table_name&#x27;,RESEED)GO</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Mon, 20 Jul 2020 00:19:09 +0430</pubDate>
            </item>
                    <item>
                <title>آینده برنامه نویسی</title>
                <link>https://virgool.io/@Kavekardel/%D8%A2%DB%8C%D9%86%D8%AF%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-avw9l9dckrih</link>
                <description>برنامه نویسی در شکل شمایل امروزی خود کم و کاستی های بسیاری دارد که در آینده دچار تغیراتی اساسی خواهد شد.امروزه شاهد آنیم که در مدارس زبان های برنامه نویسی به کودکان تدریس شده و بعنوان یک مهارت همه گیر در حال گسترش است. زبان های برنامه نویسی روز به روز در حال محاوره ای تر شدن هستند بطوریکه با یادداشتن زبان انگلیسی قادر به ترجمه بخش عمده ای از آنها خواهیم بود.همینطور شاهد پیشرفت در حوزه Machine Learning هستیم و بطور قطع نرم افزار هایی قابل طراحی هستند که از دست بهترین برنامه نویسان دنیا کد زدن را فرا بگیرند و جایگزینی قاطع برای سبک امروزی برنامه نویسی باشند.از نظر من تخصصی که ما امروز داریم در آینده قابلیت تبدیل شدن به یک مهارت عمومی که همه افراد از آن بهرهمند خواهند بود را داراست و از طرفی نیز سرعت در پیشرفت علم میتواند جایگزین هایی برای نیروی انسانی در نظر داشته باشد.شاید با خواندن اینها نگران از دست دادن شغتان شوید یا آینده برنامه نویسی را مبهم بپندارید اما حوزه های بکر و کمتر پرداخته شده بسیاری در این رشته وجود دارد و این تازه شروع راه است پس نگران نباشید. برنامه نویسی آینده ای روشن در انتظار دارد و تغیر ذات تکنولوژی است.در زمانه امروز باید اشراف کامل به پیشرفت های تکنولوژی داشته باشید و با تشخیص مناسب فرصت ها آن هارا شکار کنید. آینده از آن افرادیست که دائم یاد میگیرند اگر چنین فردی هستید بدانید که این تغیرات غربالی هستند که شما دانه درشته آنید.برای درک بهتر مقاله زیر را مطالعه کنید. https://goo.gl/46ztsZ </description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Tue, 07 Jul 2020 20:47:10 +0430</pubDate>
            </item>
                    <item>
                <title>روابط مدیر و کارمندی</title>
                <link>https://virgool.io/@Kavekardel/%D8%B1%D9%88%D8%A7%D8%A8%D8%B7-%D9%85%D8%AF%DB%8C%D8%B1-%D9%88-%DA%A9%D8%A7%D8%B1%D9%85%D9%86%D8%AF%DB%8C-cxcys8sgqvbn</link>
                <description>روابط مدیر و کارمندی؟ مسئله این است!موضوع جدیدی نیست اما وقتی در کنار مقوله کرونا میاید اهمیتش تشدید شده و جای بحث دارد.از دوران انقلاب صنعتی اروپا تا همین حالا که کرونا تیتر اول دنیاست روابط مدیرها و کارمندان جزء مسائل حیاتی و تاثیرگذار در سبک زندگی و سلامت افراد بود و نقش بسزایی در رشد سازمان ها ایفا کرد.قبل تر نگرش صاحبان کسب و کار و کارمندان صرفا نگاه مالی بود یعنی معنای کار و احساسات انسانی در اون دخیل نبود و اهمیتی نداشت.برای مثال فردی فقط با هدف دریافت مبلغ مالی سالها کاری را انجام میداد و صاحب کار هم چون اصطلاحا (پولشو داده بود) فارغ از همه بدنبال بازدهی بود. این موضوع در زمان طولانی به زندگی افراد لطمه میزد و کمیت و کیفیت تولید را کاهشی میکرد.امروزه هنوز هم این نگرش را در رفتار برخی از مدیرها میتوان دید که اشتباه بودنش شکی نیست و باید که تغیرش داد و تلاش در ایجاد روابطی فراتر از روابط مالی و معنا بخشیدن به کار کرد اما مسئله نزدیکتر به حال کنونی ما این است که در برهه ای که کرونا ضربه های مالی به شرکت ها زده و مدیرها متضرر و کارمندان چندین ماه است حقوق دریافت نکردند این مسئله بیشتر از پیش دچار اهمیت شده و اگر این روابط تصحیح و تشدید پیدا نکند میتواند حتی به فروپاشی سازمان منجر شود.نمونه های کوچکی مثل یک تماس تلفنی از جانب مدیر یا صحبت شخصی با‌ کارمندان درمورد مشکلاتشان، تشویق و تصدیق ها و چیزهایی از این قبیل میتواند القاء کننده اهمیت روابط و پل عبور ازاین بحران باشد.</description>
                <category>Kaveh Kardel</category>
                <author>Kaveh Kardel</author>
                <pubDate>Tue, 07 Jul 2020 20:42:03 +0430</pubDate>
            </item>
            </channel>
</rss>