اشتراکها
بهبود کد نویسی در c# 6
اشتراکها
سری 24 قسمتی بررسی design patterns
اشتراکها
ابزاری برای weaving .net assemblies
در یک برنامه فروشگاه، جداول مشتری و خریدهای او را درنظر بگیرید. خرید 3 سال قبل مشتری خاصی به آدرس قبلی او ارسال شدهاست. خرید امروز او به آدرس جدید او ارسال خواهد شد. سؤال: آیا با وارد کردن و به روز رسانی آدرس جدید مشتری، باید سابقه اطلاعاتی قبلی او حذف شود؟ اجناس ارسالی پیشین او، واقعا به آدرس دیگری ارسال شدهاند و نه به آدرس جدید او. چگونه باید اینگونه اطلاعاتی را که در طول زمان تغییر میکنند، در بانکهای اطلاعاتی رابطهای نرمال شده مدیریت کرد؟ از این نمونهها در دنیای کاری واقعی بسیارند. برای مثال قیمت اجناس نیز چنین وضعی را دارند. یک بستنی مگنوم، سال قبل 300 تومان بود؛ امسال شده است 1500 تومان. یک سطل ماست 2500 تومان بود؛ امروز همان سطل ماست 6500 تومان است. چطور باید سابقه فروش این اجناس را نگهداری کرد؟
منابع مطالعاتی مرتبط
این موضوع اینقدر مهم است که تابحال چندین کتاب در مورد آن تالیف شده است:
Temporal Data & the Relational Model
Trees and Hierarchies in SQL
Developing Time-Oriented Database Applications in SQL
Temporal Data: Time and Relational Databases
Temporal Database Entries for the Springer Encyclopedia of Database Systems
Temporal Database Management
نکته مهمی که در این مآخذ وجود دارند، واژه کلیدی «Temporal data » است که میتواند در جستجوهای اینترنتی بسیار مفید واقع شود.
بررسی ابعاد زمان
فرض کنید کارمندی را استخدام کردهاید که ساعتی 2000 تومان از ابتدای فروردین ماه حقوق دریافت میکند. حقوق این شخص از ابتدای مهرماه قرار است به ساعتی 2400 تومان افزایش یابد. اگر مامور مالیات در بهمن ماه در مورد حقوق این شخص سؤال پرسید، ما چه پاسخی را باید ارائه دهیم؟ قطعا در بهمن ماه عنوان میکنیم که حقوقش ساعتی 2400 تومان است؛ اما واقعیت این است که این عدد از ابتدای استخدام او ثابت نبوده است و باید تاریخچه تغییرات آن، در نحوه محاسبه مالیات سال جاری لحاظ شود.
بنابراین در مدل سازی این سیستم به دو زمان نیاز داریم:
الف) actual time یا زمان رخ دادن واقعهای. برای مثال حقوق شخصی در تاریخ ابتدای مهر ماه تغییر کرده است. به این تاریخ در منابع مختلف Valid time نیز گفته میشود.
ب) record time یا زمان ثبت یک واقعه؛ مثلا زمان پرداخت حقوق. به آن Transaction time هم گفته شده است.
یک مثال:
در این لیست، ریز حقوق پرداختی به یک شخص را ملاحظه میکنید. actual dateها، زمانهایی هستند که حقوق پایه شخص در آنها تغییر کرده و record dateها زمانهایی هستند که به شخص حقوق داده شدهاست.
به ترکیب Valid Time و Transaction Time، اصطلاحا Bitemporal data میگویند.
مشکلات طراحیهای متداول اطلاعات وابسته به زمان
در طراحیهای متداول، عموما یک جدول کارمندان وجود دارد و یک جدول لیست حقوقهای پرداختی. رکوردهای لیست حقوقهای پرداختی نیز توسط یک کلید خارجی به اطلاعات هر کارمند متصل است؛ از این جهت که نمیخواهیم اطلاعاتی تکراری را در جدول لیست حقوقی ثبت کنیم و طراحی نرمال سازی شدهای مدنظر میباشد.
خوب؛ اول مهرماه حقوق شخصی تغییر کرده است. بنابراین کارمند بخش مالی اطلاعات شخص را به روز میکند. با این کار، کل سابقه حقوقهای پرداختی شخص نیز از بین خواهد رفت. چون وجود این کلید خارجی به معنای استفاده از آخرین اطلاعات به روز شده یک کارمند در جدول لیست حقوقی است. الان اگر از جدول لیست حقوقی گزارش بگیریم، کارمندان همواره از آخرین حقوق به روز شده خودشان استفاده خواهند کرد.
راه حلهای متفاوت مدل سازی اطلاعات وابسته به زمان
برای رفع این مشکل مهم، راه حلهای متفاوتی وجود دارند که در ادامه آنها را بررسی خواهیم کرد.
الف) نگهداری اطلاعات وابسته به زمان در جداول نهایی مرتبط
اگر حقوق پایه شخص در زمانهای مختلف تغییر میکند، بهتر است عدد نهایی این حقوق پرداختی نیز در یک فیلد مشخص، در همان جدول لیست حقوقی ثبت شود. این مورد به معنای داشتن «دادهای تکراری» نیست. از این جهت که دادهای تکراری است که اطلاعات آن در تمام زمانها، دارای یک مقدار و مفهوم باشد و اطلاعات حقوق یک شخص اینچنین نیست.
ب) نگهداری اطلاعات تغییرات حقوقی در یک جداول جداگانه
یک جدول ثانویه حقوق جاری کارمندان مرتبط با جدول اصلی کارمندان باید ایجاد شود. در این جدول هر رکورد آن باید دارای بازه زمانی (valid_start_time و valid_end_time) مشخصی باشد. مثلا از تاریخ X تا تاریخ Y، حقوق کارمند شماره 11 ، 2000 تومان در ساعت بوده است. از تاریخ H تا تاریخ Z اطلاعات دیگری ثبت خواهند شد. به این ترتیب با گزارشگیری از جدول لیست حقوقهای پرداخت شده، سابقه گذشته اشخاص محو نشده و هر رکورد بر اساس قرارگیری در یک بازه زمانی ثبت شده در جدول ثانویه حقوق جاری کارمندان تفسیر میشود.
در این حالت باید دقت داشت که بازههای زمانی تعریف شده، با هم تداخل نکنند و برنامه ثبت کننده اطلاعات باید این مساله را به ازای هر کارمند کنترل کند و یا با ثبت record_date، اجازه ثبت بازههای تکراری را نیز بدهد (توضیحات در قسمت بعد).
به این جدول، یک Temporal table نیز گفته میشود. نمونه دیگر آن، نگهداری قیمت یک کالا است از یک تاریخ تا تاریخی مشخص. به این ترتیب میتوان کوئری گرفت که بستنی مگنوم فروخته شده در ماه آبان سال قبل، بر مبنای قیمت آن زمان، دقیقا چقدر فروش کرده است و نه اینکه صرفا بر اساس آخرین قیمت روز این کالا گزارشگیری کنیم که در این حالت اطلاعات نهایی استخراج شده صحیح نیستند.
حال اگر به این طراحی در جدولی دیگر Transaction time یا زمان ثبت یک رکورد یا زمان ثبت یک فروش را هم اضافه کنیم، به جداول حاصل Bitemporal Tables میگویند.
مدیریت به روز رسانیها در جداول Temporal
در جداول Temporal، حذف فیزیکی اطلاعات مطلقا ممنوع است؛ چون سابقه سیستم را تخریب میکند. اگر اطلاعاتی در این جداول دیگر معتبر نیست باید تنها تاریخ پایان دوره آن به روز شوند یا یک رکورد جدید بر اساس بازهای جدید ثبت گردد.
همچنین به روز رسانیها در این جداول نیز معادل هستند با یک Insert جدید به همراه فیلد record_date و نه به روز رسانی واقعی یک رکورد قبلی (شبیه به سیستمهای حسابداری باید عمل کرد).
یک مثال:
فرض کنید حقوق کارمندی که مثال زده شد، در مهرماه به ساعتی 2400 تومان افزایش یافته است و حقوق نهایی نیز پرداخته شده است. بعد از یک ماه مشخص میشود که مدیر عامل سیستم گفته بوده است که ساعتی 2500 تومان و نه ساعتی 2400 تومان! (از این نوع مسایل در دنیای واقعی زیاد رخ میدهند!) خوب؛ اکنون چه باید کرد؟ آیا باید رفت و رکورد ساعتی 2400 تومان را به روز کرد؟ خیر. چون سابقه پرداخت واقعی صورت گرفته را تخریب میکند. به روز رسانی شما ابدا به این معنا نخواهد بود که دریافتی واقعی شخص در آن تاریخ خاص، ساعتی 2500 بوده است.
بنابراین در جداول Temporal، تنها «تغییرات افزودنی» مجاز هستند و این تغییرات همواره به عنوان آخرین رکورد جدول ثبت میشوند. به این ترتیب میتوان اصطلاحا «مابه التفاوت» حقوق پرداخت نشده را به شخص خاصی، محاسبه و پرداخت کرد (میدانیم در یک بازه زمانی خاص به او چقد حقوق دادهایم. همچنین میدانیم که این بازه در یک record_date دیگر لغو و با عددی دیگر، جایگزین شدهاست).
برای مطالعه بیشتر
Bitemporal Database Table Design - The Basics
Temporal Data Techniques in SQL
Database Design: A Point in Time Architecture
Temporal database
Temporal Patterns
راه حلی دیگر؛ استفاده از بانکهای اطلاعاتی NoSQL
بانکهای اطلاعاتی NoSQL برخلاف بانکهای اطلاعاتی رابطهای برای اعمال Read بهینه سازی میشوند و نه برای Write. در چند دهه قبل که بانکهای اطلاعاتی رابطهای پدیدار شدند، یک سخت دیسک 10 مگابایتی حدود 4000 دلار قیمت داشته است. به همین جهت مباحث نرمال سازی اطلاعات و ذخیره نکردن اطلاعات تکراری تا این حد در این نوع بانکهای اطلاعاتی مهم بوده است. اما در بانکهای اطلاعاتی NoSQL امروزی، اگر قرار است فیش حقوقی شخصی ثبت شود، میتوان کل اطلاعات جاری او را یکجا داخل یک سند ثبت کرد (از اطلاعات شخص در آن تاریخ تا اطلاعات تمام اجزای فیش حقوقی در قالب یک شیء تو در توی JSON). به همین جهت بسیار سریع هستند برای اعمال Read و گزارشگیری. همچنین این نوع سیستمها برای نگهداری نگارشهای مختلف یک سند بهینه سازی شدهاند و جزو ساختار توکار آنها است. بنابراین در این نوع سیستمها اگر نیاز است از یک سند خاصی گزارش بگیریم، دقیقا اطلاعات همان تاریخ خاص را دارا است و اگر اطلاعات پایه سیستم را به روز کنیم، از امروز به بعد در سندهای جدید ثبت خواهد شد. این نوع سیستمها رابطهای نیستند و بسیاری از مباحث نرمال سازی اطلاعات در آنها ضرورتی ندارد. قرار است یک فیش حقوقی شخص را نمایش دهیم؟ خوب، چرا تمام اطلاعات مورد نیاز او را در قالب یک شیء JSON تو در توی حاضر و آماده نداشته باشیم؟
منابع مطالعاتی مرتبط
این موضوع اینقدر مهم است که تابحال چندین کتاب در مورد آن تالیف شده است:
Temporal Data & the Relational Model
Trees and Hierarchies in SQL
Developing Time-Oriented Database Applications in SQL
Temporal Data: Time and Relational Databases
Temporal Database Entries for the Springer Encyclopedia of Database Systems
Temporal Database Management
نکته مهمی که در این مآخذ وجود دارند، واژه کلیدی «Temporal data » است که میتواند در جستجوهای اینترنتی بسیار مفید واقع شود.
بررسی ابعاد زمان
فرض کنید کارمندی را استخدام کردهاید که ساعتی 2000 تومان از ابتدای فروردین ماه حقوق دریافت میکند. حقوق این شخص از ابتدای مهرماه قرار است به ساعتی 2400 تومان افزایش یابد. اگر مامور مالیات در بهمن ماه در مورد حقوق این شخص سؤال پرسید، ما چه پاسخی را باید ارائه دهیم؟ قطعا در بهمن ماه عنوان میکنیم که حقوقش ساعتی 2400 تومان است؛ اما واقعیت این است که این عدد از ابتدای استخدام او ثابت نبوده است و باید تاریخچه تغییرات آن، در نحوه محاسبه مالیات سال جاری لحاظ شود.
بنابراین در مدل سازی این سیستم به دو زمان نیاز داریم:
الف) actual time یا زمان رخ دادن واقعهای. برای مثال حقوق شخصی در تاریخ ابتدای مهر ماه تغییر کرده است. به این تاریخ در منابع مختلف Valid time نیز گفته میشود.
ب) record time یا زمان ثبت یک واقعه؛ مثلا زمان پرداخت حقوق. به آن Transaction time هم گفته شده است.
یک مثال:
record date actual date حقوق دریافتی 1392/01/01 1392/01/01 2000/روز 1392/02/01 1392/01/01 2000/روز ... 1392/07/01 1392/07/01 2400/روز ... 1392/17/01 1392/07/01 2400/روز
به ترکیب Valid Time و Transaction Time، اصطلاحا Bitemporal data میگویند.
مشکلات طراحیهای متداول اطلاعات وابسته به زمان
در طراحیهای متداول، عموما یک جدول کارمندان وجود دارد و یک جدول لیست حقوقهای پرداختی. رکوردهای لیست حقوقهای پرداختی نیز توسط یک کلید خارجی به اطلاعات هر کارمند متصل است؛ از این جهت که نمیخواهیم اطلاعاتی تکراری را در جدول لیست حقوقی ثبت کنیم و طراحی نرمال سازی شدهای مدنظر میباشد.
خوب؛ اول مهرماه حقوق شخصی تغییر کرده است. بنابراین کارمند بخش مالی اطلاعات شخص را به روز میکند. با این کار، کل سابقه حقوقهای پرداختی شخص نیز از بین خواهد رفت. چون وجود این کلید خارجی به معنای استفاده از آخرین اطلاعات به روز شده یک کارمند در جدول لیست حقوقی است. الان اگر از جدول لیست حقوقی گزارش بگیریم، کارمندان همواره از آخرین حقوق به روز شده خودشان استفاده خواهند کرد.
راه حلهای متفاوت مدل سازی اطلاعات وابسته به زمان
برای رفع این مشکل مهم، راه حلهای متفاوتی وجود دارند که در ادامه آنها را بررسی خواهیم کرد.
الف) نگهداری اطلاعات وابسته به زمان در جداول نهایی مرتبط
اگر حقوق پایه شخص در زمانهای مختلف تغییر میکند، بهتر است عدد نهایی این حقوق پرداختی نیز در یک فیلد مشخص، در همان جدول لیست حقوقی ثبت شود. این مورد به معنای داشتن «دادهای تکراری» نیست. از این جهت که دادهای تکراری است که اطلاعات آن در تمام زمانها، دارای یک مقدار و مفهوم باشد و اطلاعات حقوق یک شخص اینچنین نیست.
ب) نگهداری اطلاعات تغییرات حقوقی در یک جداول جداگانه
یک جدول ثانویه حقوق جاری کارمندان مرتبط با جدول اصلی کارمندان باید ایجاد شود. در این جدول هر رکورد آن باید دارای بازه زمانی (valid_start_time و valid_end_time) مشخصی باشد. مثلا از تاریخ X تا تاریخ Y، حقوق کارمند شماره 11 ، 2000 تومان در ساعت بوده است. از تاریخ H تا تاریخ Z اطلاعات دیگری ثبت خواهند شد. به این ترتیب با گزارشگیری از جدول لیست حقوقهای پرداخت شده، سابقه گذشته اشخاص محو نشده و هر رکورد بر اساس قرارگیری در یک بازه زمانی ثبت شده در جدول ثانویه حقوق جاری کارمندان تفسیر میشود.
در این حالت باید دقت داشت که بازههای زمانی تعریف شده، با هم تداخل نکنند و برنامه ثبت کننده اطلاعات باید این مساله را به ازای هر کارمند کنترل کند و یا با ثبت record_date، اجازه ثبت بازههای تکراری را نیز بدهد (توضیحات در قسمت بعد).
به این جدول، یک Temporal table نیز گفته میشود. نمونه دیگر آن، نگهداری قیمت یک کالا است از یک تاریخ تا تاریخی مشخص. به این ترتیب میتوان کوئری گرفت که بستنی مگنوم فروخته شده در ماه آبان سال قبل، بر مبنای قیمت آن زمان، دقیقا چقدر فروش کرده است و نه اینکه صرفا بر اساس آخرین قیمت روز این کالا گزارشگیری کنیم که در این حالت اطلاعات نهایی استخراج شده صحیح نیستند.
حال اگر به این طراحی در جدولی دیگر Transaction time یا زمان ثبت یک رکورد یا زمان ثبت یک فروش را هم اضافه کنیم، به جداول حاصل Bitemporal Tables میگویند.
مدیریت به روز رسانیها در جداول Temporal
در جداول Temporal، حذف فیزیکی اطلاعات مطلقا ممنوع است؛ چون سابقه سیستم را تخریب میکند. اگر اطلاعاتی در این جداول دیگر معتبر نیست باید تنها تاریخ پایان دوره آن به روز شوند یا یک رکورد جدید بر اساس بازهای جدید ثبت گردد.
همچنین به روز رسانیها در این جداول نیز معادل هستند با یک Insert جدید به همراه فیلد record_date و نه به روز رسانی واقعی یک رکورد قبلی (شبیه به سیستمهای حسابداری باید عمل کرد).
یک مثال:
فرض کنید حقوق کارمندی که مثال زده شد، در مهرماه به ساعتی 2400 تومان افزایش یافته است و حقوق نهایی نیز پرداخته شده است. بعد از یک ماه مشخص میشود که مدیر عامل سیستم گفته بوده است که ساعتی 2500 تومان و نه ساعتی 2400 تومان! (از این نوع مسایل در دنیای واقعی زیاد رخ میدهند!) خوب؛ اکنون چه باید کرد؟ آیا باید رفت و رکورد ساعتی 2400 تومان را به روز کرد؟ خیر. چون سابقه پرداخت واقعی صورت گرفته را تخریب میکند. به روز رسانی شما ابدا به این معنا نخواهد بود که دریافتی واقعی شخص در آن تاریخ خاص، ساعتی 2500 بوده است.
بنابراین در جداول Temporal، تنها «تغییرات افزودنی» مجاز هستند و این تغییرات همواره به عنوان آخرین رکورد جدول ثبت میشوند. به این ترتیب میتوان اصطلاحا «مابه التفاوت» حقوق پرداخت نشده را به شخص خاصی، محاسبه و پرداخت کرد (میدانیم در یک بازه زمانی خاص به او چقد حقوق دادهایم. همچنین میدانیم که این بازه در یک record_date دیگر لغو و با عددی دیگر، جایگزین شدهاست).
برای مطالعه بیشتر
Bitemporal Database Table Design - The Basics
Temporal Data Techniques in SQL
Database Design: A Point in Time Architecture
Temporal database
Temporal Patterns
راه حلی دیگر؛ استفاده از بانکهای اطلاعاتی NoSQL
بانکهای اطلاعاتی NoSQL برخلاف بانکهای اطلاعاتی رابطهای برای اعمال Read بهینه سازی میشوند و نه برای Write. در چند دهه قبل که بانکهای اطلاعاتی رابطهای پدیدار شدند، یک سخت دیسک 10 مگابایتی حدود 4000 دلار قیمت داشته است. به همین جهت مباحث نرمال سازی اطلاعات و ذخیره نکردن اطلاعات تکراری تا این حد در این نوع بانکهای اطلاعاتی مهم بوده است. اما در بانکهای اطلاعاتی NoSQL امروزی، اگر قرار است فیش حقوقی شخصی ثبت شود، میتوان کل اطلاعات جاری او را یکجا داخل یک سند ثبت کرد (از اطلاعات شخص در آن تاریخ تا اطلاعات تمام اجزای فیش حقوقی در قالب یک شیء تو در توی JSON). به همین جهت بسیار سریع هستند برای اعمال Read و گزارشگیری. همچنین این نوع سیستمها برای نگهداری نگارشهای مختلف یک سند بهینه سازی شدهاند و جزو ساختار توکار آنها است. بنابراین در این نوع سیستمها اگر نیاز است از یک سند خاصی گزارش بگیریم، دقیقا اطلاعات همان تاریخ خاص را دارا است و اگر اطلاعات پایه سیستم را به روز کنیم، از امروز به بعد در سندهای جدید ثبت خواهد شد. این نوع سیستمها رابطهای نیستند و بسیاری از مباحث نرمال سازی اطلاعات در آنها ضرورتی ندارد. قرار است یک فیش حقوقی شخص را نمایش دهیم؟ خوب، چرا تمام اطلاعات مورد نیاز او را در قالب یک شیء JSON تو در توی حاضر و آماده نداشته باشیم؟
پس از معرفی ابتدایی VSCode و نصب افزونهی #C در قسمت قبل، در ادامه میخواهیم اولین پروژهی ASP.NET Core خود را در آن ایجاد کنیم.
نصب ASP.NET Core بر روی سیستم عاملهای مختلف
برای نصب پیشنیازهای کار با ASP.NET Core به آدرس https://www.microsoft.com/net/download/core مراجعه کرده و NET Core SDK. را دریافت و نصب کنید. پس از نصب آن جهت اطمینان از صحت انجام عملیات، دستور dotnet --version را در خط فرمان صادر کنید:
در اینجا SDK نصب شده، شامل هر دو نگارش 1.0 و 1,1 است. همچنین در همین صفحهی دریافت فایلها، علاوه بر نگارش ویندوز، نگارشهای Mac و لینوکس آن نیز موجود هستند. بر روی هر کدام که کلیک کنید، ریز مراحل نصب هم به همراه آنها وجود دارد. برای مثال نصب NET Core. بر روی Mac شامل نصب OpenSSL به صورت جداگانه است و یا نصب آن بر روی لینوکس به همراه چند دستور مختص به توزیع مورد استفاده میباشد که به خوبی مستند شدهاند و نیازی به تکرار آنها نیست و همواره آخرین نگارش آنها بر روی سایت dot.net موجود است.
ایجاد اولین پروژهی ASP.NET Core توسط NET Core SDK.
پس از نصب NET Core SDK.، به پیشنیاز دیگری برای شروع به کار با ASP.NET Core نیازی نیست. نه نیازی است تا آخرین نگارش ویژوال استودیوی کامل را نصب کنید و نه با به روز رسانی آن، نیاز است چندگیگابایت فایل به روز رسانی تکمیلی را دریافت کرد. همینقدر که این SDK نصب شود، میتوان بلافاصله شروع به کار با این نگارش جدید کرد.
در ادامه ابتدا پوشهی جدید پروژهی خود را ساخته (برای مثال در مسیر D:\vs-code-examples\FirstAspNetCoreProject) و سپس از طریق خط فرمان به این پوشه وارد میشویم.
یک نکته: در ویندوزهای جدید فقط کافی است در نوار آدرس بالای صفحه تایپ کنید cmd. به این صورت بلافاصله command prompt استاندارد ویندوز در پوشهی جاری در دسترس خواهد بود و دیگر نیازی نیست تا چند مرحله را جهت رسیدن به آن طی کرد.
پس از وارد شدن به پوشهی جدید از طریق خط فرمان، دستور dotnet new --help را صادر کنید:
همانطور که مشاهده میکنید، اینبار بجای انتخاب گزینههای مختلف از صفحه دیالوگ new project template داخل ویژوال استودیوی کامل، تمام این قالبها از طریق خط فرمان در اختیار ما هستند. برای مثال میتوان یک برنامه کنسول و یا یک کتابخانهی جدید را ایجاد کرد.
در ادامه دستور ذیل را صادر کنید:
به این ترتیب یک پروژهی جدید ASP.NET Core، بدون تنظیمات اعتبارسنجی و ASP.NET Core Identity، در کسری از ثانیه ایجاد خواهد شد.
سپس جهت گشودن این پروژه در VSCode تنها کافی است دستور ذیل را صادر کنیم:
در ادامه یکی از فایلهای #C آنرا گشوده و منتظر شوید تا کار دریافت خودکار بستههای مرتبط با افزونهی #C ایی که در قسمت قبل نصب کردیم به پایان برسند:
اینکار یکبار باید انجام شود و پس از آن امکانات زبان #C و همچنین دیباگر NET Core. در VS Code قابل استفاده خواهند بود.
در تصویر فوق دو اخطار را هم مشاهده میکنید. مورد اول برای فعال سازی دیباگ و ساخت پروژهی جاری است. گزینهی Yes آنرا انتخاب کنید و اخطار دوم جهت بازیابی بستههای نیوگت پروژهاست که گزینهی restore آنرا انتخاب نمائید. البته کار بازیابی بستهها از طریق کش موجود در سیستم به سرعت انجام خواهد شد.
گشودن کنسول از درون VS Code و اجرای برنامهی ASP.NET Core
روشهای متعددی برای گشودن کنسول خط فرمان در VS Code وجود دارند:
الف) فشردن دکمههای Ctrl+Shift+C
اینکار باعث میشود تا command prompt ویندوز از پوشهی جاری به صورت مجزایی اجرا شود.
ب) فشردن دکمههای Ctrl+` (و یا Ctrl+ back-tick)
به این ترتیب کنسول پاورشل درون خود VS Code باز خواهد شد. اگر علاقمند نیستید تا از پاورشل استفاده کنید، میتوانید این پیشفرض را به نحو ذیل بازنویسی کنید:
همانطور که در قسمت قبل نیز ذکر شد، از طریق منوی File->Preferences->Settings میتوان به تنظیمات VS Code دسترسی یافت. پس از گشودن آن، یک سطر ذیل را به آن اضافه کنید:
اکنون Ctrl+ back-tick را فشرده تا کنسول خط فرمان، داخل VS Code نمایان شود و سپس دستور ذیل را صادر کنید:
در اینجا دستور dotnet run سبب کامپایل و همچنین اجرای پروژه شدهاست و اکنون این برنامهی وب بر روی پورت 5000 قابل دسترسی است:
ساده سازی ساخت و اجرای یک برنامهی ASP.NET Core در VS Code
زمانیکه گزینهی افزودن امکانات ساخت و دیباگ را انتخاب میکنیم (تصویر فوق)، دو فایل جدید به پوشهی vscode. اضافه میشوند:
دراینجا فایل tasks.json، حاوی وظیفهای است جهت ساخت برنامه. یعنی بجای اینکه مدام بخواهیم به خط فرمان مراجعه کرده و دستوراتی را صادر کنیم، میتوان از وظایفی که در پشت صحنه همین فرامین را اجرا میکنند، استفاده کنیم؛ که نمونهای از آن، به صورت پیش فرض به پروژه اضافه شده است.
برای دسترسی به آن، دکمههای ctrl+shift+p را فشرده و سپس در منوی ظاهر شده، واژهی build را جستجو کنید:
با انتخاب این گزینه (که توسط Ctrl+Shift+B هم در دسترس است)، کار ساخت برنامه انجام شده و dll مرتبط با آن در پوشهی bin تشکیل میشود.
همچنین در اینجا برای ساخت و بلافاصله نمایش آن در مرورگر پیش فرض سیستم، میتوان مجددا دکمههای ctrl+shift+p را فشرد و در منوی ظاهر شده، واژهی without را جستجو کرد:
با انتخاب این گزینه (که توسط Ctrl+F5 نیز در دسترس است)، برنامه ساخته شده، اجرا و نمایش داده میشود و برای خاتمهی آن میتوانید دکمههای Ctrl+C را بفشارید تا کار وب سرور موقتی آن خاتمه یابد.
در قسمت بعد مباحث دیباگ برنامه و گردش کار متداول یک پروژهی ASP.NET Core را بررسی خواهیم کرد.
نصب ASP.NET Core بر روی سیستم عاملهای مختلف
برای نصب پیشنیازهای کار با ASP.NET Core به آدرس https://www.microsoft.com/net/download/core مراجعه کرده و NET Core SDK. را دریافت و نصب کنید. پس از نصب آن جهت اطمینان از صحت انجام عملیات، دستور dotnet --version را در خط فرمان صادر کنید:
C:\>dotnet --version 1.0.1
ایجاد اولین پروژهی ASP.NET Core توسط NET Core SDK.
پس از نصب NET Core SDK.، به پیشنیاز دیگری برای شروع به کار با ASP.NET Core نیازی نیست. نه نیازی است تا آخرین نگارش ویژوال استودیوی کامل را نصب کنید و نه با به روز رسانی آن، نیاز است چندگیگابایت فایل به روز رسانی تکمیلی را دریافت کرد. همینقدر که این SDK نصب شود، میتوان بلافاصله شروع به کار با این نگارش جدید کرد.
در ادامه ابتدا پوشهی جدید پروژهی خود را ساخته (برای مثال در مسیر D:\vs-code-examples\FirstAspNetCoreProject) و سپس از طریق خط فرمان به این پوشه وارد میشویم.
یک نکته: در ویندوزهای جدید فقط کافی است در نوار آدرس بالای صفحه تایپ کنید cmd. به این صورت بلافاصله command prompt استاندارد ویندوز در پوشهی جاری در دسترس خواهد بود و دیگر نیازی نیست تا چند مرحله را جهت رسیدن به آن طی کرد.
پس از وارد شدن به پوشهی جدید از طریق خط فرمان، دستور dotnet new --help را صادر کنید:
D:\vs-code-examples\FirstAspNetCoreProject>dotnet new --help Getting ready... Template Instantiation Commands for .NET Core CLI. Usage: dotnet new [arguments] [options] Arguments: template The template to instantiate. Options: -l|--list List templates containing the specified name. -lang|--language Specifies the language of the template to create -n|--name The name for the output being created. If no name is specified, the name of the current directory is used. -o|--output Location to place the generated output. -h|--help Displays help for this command. -all|--show-all Shows all templates Templates Short Name Language Tags ---------------------------------------------------------------------- Console Application console [C#], F# Common/Console Class library classlib [C#], F# Common/Library Unit Test Project mstest [C#], F# Test/MSTest xUnit Test Project xunit [C#], F# Test/xUnit ASP.NET Core Empty web [C#] Web/Empty ASP.NET Core Web App mvc [C#], F# Web/MVC ASP.NET Core Web API webapi [C#] Web/WebAPI Solution File sln Solution Examples: dotnet new mvc --auth None --framework netcoreapp1.1 dotnet new xunit --framework netcoreapp1.1 dotnet new --help
در ادامه دستور ذیل را صادر کنید:
D:\vs-code-examples\FirstAspNetCoreProject>dotnet new mvc --auth None
سپس جهت گشودن این پروژه در VSCode تنها کافی است دستور ذیل را صادر کنیم:
D:\vs-code-examples\FirstAspNetCoreProject>code .
اینکار یکبار باید انجام شود و پس از آن امکانات زبان #C و همچنین دیباگر NET Core. در VS Code قابل استفاده خواهند بود.
در تصویر فوق دو اخطار را هم مشاهده میکنید. مورد اول برای فعال سازی دیباگ و ساخت پروژهی جاری است. گزینهی Yes آنرا انتخاب کنید و اخطار دوم جهت بازیابی بستههای نیوگت پروژهاست که گزینهی restore آنرا انتخاب نمائید. البته کار بازیابی بستهها از طریق کش موجود در سیستم به سرعت انجام خواهد شد.
گشودن کنسول از درون VS Code و اجرای برنامهی ASP.NET Core
روشهای متعددی برای گشودن کنسول خط فرمان در VS Code وجود دارند:
الف) فشردن دکمههای Ctrl+Shift+C
اینکار باعث میشود تا command prompt ویندوز از پوشهی جاری به صورت مجزایی اجرا شود.
ب) فشردن دکمههای Ctrl+` (و یا Ctrl+ back-tick)
به این ترتیب کنسول پاورشل درون خود VS Code باز خواهد شد. اگر علاقمند نیستید تا از پاورشل استفاده کنید، میتوانید این پیشفرض را به نحو ذیل بازنویسی کنید:
همانطور که در قسمت قبل نیز ذکر شد، از طریق منوی File->Preferences->Settings میتوان به تنظیمات VS Code دسترسی یافت. پس از گشودن آن، یک سطر ذیل را به آن اضافه کنید:
"terminal.integrated.shell.windows": "cmd.exe"
D:\vs-code-examples\FirstAspNetCoreProject>dotnet run Hosting environment: Production Content root path: D:\vs-code-examples\FirstAspNetCoreProject Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.
ساده سازی ساخت و اجرای یک برنامهی ASP.NET Core در VS Code
زمانیکه گزینهی افزودن امکانات ساخت و دیباگ را انتخاب میکنیم (تصویر فوق)، دو فایل جدید به پوشهی vscode. اضافه میشوند:
دراینجا فایل tasks.json، حاوی وظیفهای است جهت ساخت برنامه. یعنی بجای اینکه مدام بخواهیم به خط فرمان مراجعه کرده و دستوراتی را صادر کنیم، میتوان از وظایفی که در پشت صحنه همین فرامین را اجرا میکنند، استفاده کنیم؛ که نمونهای از آن، به صورت پیش فرض به پروژه اضافه شده است.
برای دسترسی به آن، دکمههای ctrl+shift+p را فشرده و سپس در منوی ظاهر شده، واژهی build را جستجو کنید:
با انتخاب این گزینه (که توسط Ctrl+Shift+B هم در دسترس است)، کار ساخت برنامه انجام شده و dll مرتبط با آن در پوشهی bin تشکیل میشود.
همچنین در اینجا برای ساخت و بلافاصله نمایش آن در مرورگر پیش فرض سیستم، میتوان مجددا دکمههای ctrl+shift+p را فشرد و در منوی ظاهر شده، واژهی without را جستجو کرد:
با انتخاب این گزینه (که توسط Ctrl+F5 نیز در دسترس است)، برنامه ساخته شده، اجرا و نمایش داده میشود و برای خاتمهی آن میتوانید دکمههای Ctrl+C را بفشارید تا کار وب سرور موقتی آن خاتمه یابد.
در قسمت بعد مباحث دیباگ برنامه و گردش کار متداول یک پروژهی ASP.NET Core را بررسی خواهیم کرد.
Fixed bug where LangVersion property was not read correctly from project file, blocking C# 7.1 development.
Fixed long-standing problem with renaming files.
Added csharp.referencesCodeLens.enabled and csharp.testsCodeLens.enabled options to allow disabling/enabling for the 'references' and 'run/debug test' code lenses independently.