مطالب
سیستم‌های توزیع شده در NET. - بخش هفتم- معرفی Apache Kafka
سرچشمه Kafka از LinkedIn آغاز و سپس در سال 2011 توسط Apache بصورت open source ارائه شد. هدف آن ارائه یک بستر جریان داده‌ای توزیع شده‌است که اساس آن، Publish-Subscribe می‌باشد . سادگی اضافه کردن قابلیت‌های مقیاس پذیری افقی، تحمل خطا و افزایش کارآیی توسط این بستر باعث شده‌است که هزاران شرکت از آن بعنوان بستر ارتباطی قسمتهای مختلف سیستمها و زیرسیستمهای خود استفاده کنند.
همانطور که گفته شد وظیفه و هدف اصلی Apache Kafka، ارائه یک بستر برای مدیریت و کنترل جریان‌های اطلاعاتی با کارآیی بسیار بالا، در سیستم‌ها و زیرسیستمهای مختلف است. یعنی شما می‌توانید با ایجاد کردن یک Pipeline برای جریان اطلاعات خود، وابستگی مستقیم سیستمها و زیرسیستمها را از بین ببرید؛ آن هم بصورتی که بروز مشکلی در هر قسمت، کمترین میزان تاثیر را در سایر قسمتها داشته باشد.
فرض کنید شما تعداد زیادی سیستم و زیرسیستم مختلف را داشته باشید که هر کدام از آنها نیازمند ارتباط با برخی از قسمتهای دیگر است. در این صورت شما دو راه دارید: اول اینکه در هر قسمت سرویس‌هایی را برای ارتباط با سایر قسمت‌ها پیاده سازی کنید و هر قسمت بصورت مستقیم با سایر قسمتها در ارتباط باشد.

مشخصا کنترل و مدیریت جریان اطلاعاتی در این پیاده سازی کار بسیار دشواری است. تغییر هر قسمت، تاثیر مستقیمی بر روی سایر قسمتها دارد و در صورتی که هریک از قسمتها با مشکلی روبرو شوند، سایر قسمتهای مرتبط نیز با مشکل روبرو می‌شوند. این مشکل زمانی بسیار نمایان می‌شود که در معماری‌هایی مانند میکروسرویس، بدلیل بالا رفتن تعداد زیرسیستم‌ها و ارتباطات آنها، مدیریت این ارتباطات کار بسیار دشوار، پرهزینه و پیچیده‌ای می‌شود.
روش Apache Kafka برای رفع مشکل فوق به این صورت است که Kafka با بر عهده گرفتن مدیریت ارتباطات و جریان داده‌ای قسمتهای مختلف، به شما کمک می‌کند تا تیم پیاده سازی، تنها تمرکزشان را بر روی Businessی که می‌خواهند پیاده سازی کنند، قرار دهند. با این روش می‌توانیم به راحتی سیستمهایی را پیاده سازی کنیم که از نظر ارتباطی در حالت معمول، پیچیده یا بسیار پیچیده‌اند.

همانطور که می‌بینید دیگر نیازی نیست تا قسمتهای مختلف بصورت مستقیم با یکدیگر در ارتباط باشند؛ تمامی ارتباطات از طریق Kafka انجام می‌شود. تغییر یک قسمت، تاثیر زیادی بر روی سایر قسمتها ندارد. از دسترس خارج شدن یا بروز هر گونه مشکلی در یک قسمت، بر روی کل سیستم تاثیر زیادی ندارد. پیامهای مربوط به یک قسمت تا زمانی که پردازش نشده‌اند از بین نمی‌روند. پس سیستمها می‌توانند در حالت Offline نیز به کار خود ادامه دهند. شما می‌توانید  در این روش تمامی قسمتهای  سیستم را بصورت یک Cluster پیاده سازی کنید. بنابراین احتمال از دسترس خارج شدن هر قسمت به کمترین میزان می‌رسد. اما حتی درصورتی که یک قسمت بصورت موقت از دسترس خارج شود، پیامهای مرتبط با آن قسمت تا زمانی که دوباره به جریان پردازش بازگردد، از بین نمی‌روند. پس از اضافه شدن قسمت از دسترس خارج شده، بلافاصله تمامی پیامهای مرتبط با آن قسمت برایش ارسال می‌شوند. برای بالا رفتن میزان کارآیی و تحمل خطا، به راحتی می‌توانید خود Kafka را نیز بصورت یک Cluster پیاده سازی کنید و با بالا رفتن تعداد درخواست، در صورت نیاز می‌توانید عملیات مقیاس پذیری افقی را به راحت‌ترین روش ممکن انجام دهید.

نمایی از معماری کلی Apache Kafka: 


برای شروع به آموزش Apache Kafka بهتر است ابتدا با مفاهیم و اصطلاحات آن آشنا شویم:

Producer:
  ارسال کننده پیام. Application، سیستم یا زیرسیستمی که عملیات Publish پیام را برای Topic خاص از Kafka Server انجام می‌دهد.

Consumer:
دریافت کننده پیام. Application، سیستم یا زیرسیستمی که بر روی یک یا چند Topic خاص، Subscribe کرده‌است (همچنین هر Consumer می‌تواند روی یک یا چند Partition از یک Topic خاص نیز Subscribe کند).

Consumer Group:
 گروهی از Consumer‌ها می‌باشند که با یک group.id، مشخص شده‌اند. عموما این گروه شامل یک Replicate از یک Application است؛ مانند گروه ارسال کننده ایمیل (یک زیر سیستم ارسال کننده ایمیل که چندین بار در سرور‌های مختلف اجرا شده است). Kafka این ضمانت را به ما می‌دهد که هر پیام ذخیره شده در یک Topic، برای تمامی Consumer Group‌های مرتبط ارسال شود؛ اما در هر Consumer Group، تنها یک دریافت کننده داشته باشد. یعنی هر پیام در هر Consumer Group، تنها توسط یک Consumer دریافت می‌شود.

Broker :
 قسمتی که تمامی پیامها را  از Producer دریافت می‌کند، سپس آن‌ها را در Log مربوط به Topic مشخص شده ذخیره می‌کند و پس از آن، پیام ذخیره شده را برای تمامی Consumerهای مرتبط ارسال می‌کند.

Topic: 
یک دسته بندی برای ذخیره کردن پیامهای Publish شده می‌باشد. Topicها همانند مفهوم Tableها در SQL Server می‌باشند. همانطور که می‌دانید هر Table از قبل تعریف شده‌است. یک کاربر با ارسال یک درخواست ثبت، داده‌ها را در آن ذخیره می‌کند و سپس گروهی از کاربران از داده‌های ثبت شده استفاده می‌کنند. در مفهموم Topic نیز ابتدا ما Topic مورد نظر را با خصوصیاتی که باید داشته باشد تعریف می‌کنیم (البته می‌توان بصورت Dynamic نیز آن را تعریف کرد؛ اما این روش توصیه نمی‌شود). سپس Producer پیام مربوطه را به همراه نام Topic برای Broker ارسال می‌کند. Broker پیام را در Partition مربوطه از Topic ذخیره می‌کند و سپس پیام برای تمامی Consumer‌های مربوطه ارسال می‌شود.

Partition:
یکی از تفاوتهای بسیار مهم Kafka با سایر Message broker‌ها مانند RabitMQ که باعث بالارفتن کارآیی آن نیز شده‌است، قابلیت Partition در Topic‌ها می‌باشد. در واقع هر Topic از یک یا چندین Partition برای ذخیره داده‌ها استفاده می‌کند. تعریف درست تعداد Partition‌ها در یک Topic، تاثیر مستقیمی بر درجه همزمانی و کارآیی در آن Topic و کل سیستم دارد. در Kafka تمامی پیامها به همان ترتیبی که وارد شده‌اند، در Partition‌های یک Topic ذخیره می‌شوند و به همان ترتیب نیز برای Consumer‌ها ارسال می‌شوند.
بطور مثال فرض کنید تعداد Partition‌های یک Topic با نام DepartmentMessage یک می‌باشد (از این Topic برای ذخیره پیامهای واحدهای مختلف یک سازمان استفاده می‌شود). در این صورت تمامی پیامهای دریافتی تنها در یک Partition ذخیره می‌شوند.

هر خانه از یک Partition، توسط یک شناسه از نوع int و با نام offset در دسترس است. تمامی پیامهای جدید ارسالی توسط Producer با offset ی بزرگتر از offset موجود در این Partition ذخیره می‌شوند؛ یعنی در انتهای آن قرار می‌گیرند. در مثال فوق در صورت دریافت پیام جدید، offset آن با عدد 10 مقداردهی می‌شود. همچنین عملیات خواندن نیز از کوچکترین offsetی که هنوز  مقدار آن توسط Consumer‌ها خوانده نشده‌است، انجام می‌شود. همانطور که مشخص است، بدلیل اینکه تعداد Partitionهای این مثال عدد یک می‌باشد، تمامی درخواست‌های Producer‌ها در یک Partition قرار می‌گیرند و تمامی Consumer‌ها نیز از طریق یک Partition به پیامها دسترسی دارند؛ یعنی در صورت بالا بردن تعداد Producer‌ها یا Consumer‌ها، کارآیی بالا نمی‌رود. البته با اینکه کنترل مقدار اولیه offset برای شروع یک Consumer به دست خود Consumer و Zookeeper است، اما در اکثر موارد تمامی Consumer‌های یک Topic باید از یک نقطه، شروع به خواندن داده‌ها کنند. در این حالت تا زمانیکه پیام با offset 1، توسط Consumerی خوانده نشود، هیچ Consumerی نمی‌تواند پیام شماره 2 را بخواند. استفاده کردن از یک Partition بیشتر زمانی کاربرد دارد که بخواهید تمامی پیامهایتان، واقعا در یک صف قرار بگیرند.
حال فرض کنید در سازمان شما سه واحد اداری، مالی و آموزش وجود دارد. در این صورت بدلیل اینکه تمامی پیامها در یک Partition ذخیره می‌شوند، تا زمانی که یک واحد تمامی پیامهای مرتبط با خود را از ابتدای Partition نخوانده‌است، دیگر واحدها نمی‌توانند به پیامهای مرتبط با خود دسترسی داشته باشند. پس در این صورت ما می‌توانیم تعداد Partition‌های این Topic را عدد 3 درنظر بگیریم؛ بصورتی که پیامهای مرتبط با هر واحد در یک Partition جدا قرار بگیرد.

در این روش هر Producer زمانیکه پیامی را برای این Topic ارسال می‌کند، یک Key نیز برای آن مشخص می‌کند و این Key نشان دهنده این است که پیام جدید باید در کدام Partition ذخیره شود. یعنی بصورت همزمان می‌توانید در هر سه Partition، پیامهایتان را ذخیره کنید؛ بصورتی که بطور مثال تمامی پیامهای مربوط به واحد اداری، در Partition 0  و تمامی پیامهای مربوط به واحد مالی، در Partition 1 و واحد آموزش، در Partition 2 ذخیره شوند و همچنین عملیات خواندن از این Topic نیز می‌تواند بصورت همزمان در واحدهای مختلف انجام شود.
باید در تعریف تعداد Partition‌های یک Topic این نکته را در نظر بگیرید که این تعداد کاملا به نیازمندی شما و کارآیی که شما مد نظر دارید، بستگی دارد. تعداد این Partition‌ها حتی می‌تواند به تعداد User‌های یک سیستم نیز تعریف شود. علاوه بر آن باید بدانید که هر Partition در هر زمان تنها توسط یک Primary Broker می‌تواند در دسترس سایر قسمتها قرار بگیرد و تمامی عملیات خواندن و نوشتن در Partition توسط این Kafka Server انجام می‌شود و در صورتیکه به هر دلیلی این سرور از دسترس خارج شود، مدیریت این Partition به سرور‌های دیگر داده می‌شود.

Cluster:
مجموعه ای از Brokerها می‌باشد که بصورت یک Cluster اجرا شده‌اند. این کار باعث بالا رفتن کارآیی و تحمل خطا می‌شود.

Primary Broker:
یک Kafka Server که مسئول خواندن و نوشتن در یک Partition است. در یک Cluster هر Partition در یک زمان تنها یک Primary Broker دارد. این Primary Broker همزمان می‌تواند برای Partition‌های دیگر نقش Replicas Broker را بازی کند. انتخاب یک Primary Broker برای یک Partition توسط ZooKeeper انجام می‌شود.

Replicas Brokers :
Kafka Serverهایی که شامل یک کپی از Partition می‌باشند. عملیات خواندن و نوشتن در Partition توسط Primary انجام می‌شود. در صورتیکه Primary از دسترس خارج شود، ZooKeeper یکی از Replicas Broker‌ها را بعنوان Primary در نظر می‌گیرد. همچنین این نکته را باید در نظر بگیرید که هر Replicate همزمان می‌تواند Primary پارتیشن‌های دیگر باشد.

Replication Factor :
این خصوصیت احتمال از دست دادن داده‌های یک Topic را به حداقل می‌رساند؛ به این صورت که هر پیام از یک Topic، در چندین سرور مختلف که تعداد آنها توسط این خصوصیت مشخص می‌شود، نگهداری می‌شود.

Apache ZooKeeper :
Kafka هیچ Stateی را نگه نمی‌دارد (اصطلاحا stateless می‌باشد). برای ذخیره کردن و مدیریت تمامی Stateها از جمله اینکه در حال حاضر Primary Broker برای یک Partition چه سروری است، یا اینکه پیامهای یک Partition تا کدام offset توسط Consumer‌ها خوانده شده‌اند یا اینکه کدام Consumer در حال حاضر در یک Consumer Group مسئول یک Partition می‌باشد، توسط Apache Zookeeper انجام می‌شود.

ضمانت‌هایی که Kafka می‌دهد:
  1. تمامی پیامهای دریافتی در یک Partition از یک Topic، به همان ترتیبی که دریافت می‌شوند ذخیره می‌شوند.
  2. Consumer‌ها تمامی پیامها را در یک Partition به همان ترتیبی که ذخیره شده‌اند، دریافت می‌کنند.
  3. در یک Topic با Replication Factorی با مقدار N، درجه تحمل خطا N - 1 می‌باشد.

تا اینجا با اهداف، مفاهیم و اصطلاحات Apache Kafka آشنا شدیم. در بخش بعد به راه اندازی قسمتهای مختلف آن در Ubuntu می‌پردازیم و می‌بینیم که به چه صورت می‌توان به راحتی یک Cluster از سرورهای Kafka را ایجاد کرد.
مطالب
رویه های ذخیره شده خوب یا بد؟!

استفاده یا عدم استفاده از یک تکنولوژی یا ابزار خاص، به پارامترهای مختلفی از جمله ابعاد پروژه، مهارت و دانش اعضای تیم، ماهیت پروژه، پلتفرم اجرا، بودجه‌ی پروژه، مهلت تکمیل پروژه و تعداد نفرات تیم بستگی دارد. بنابراین واضح است پیچیدن یک نسخه‌ی خاص، برای همه‌ی سناریو‌ها امکان پذیر نیست؛ اما شرایطی وجود دارد که استفاده یا عدم استفاده از این ابزارهای تکنولوژیک منطقی‌تر مینمایند.

Stored Procedure (که از این به بعد برای ایجاز، SP نوشته خواهد شد) هم از قاعده فوق مستثنی نیست و در صورت انتخاب صحیح میتواند به ارائه‌ی محصول نهایی با کیفیت‌تری در زمان کوتاه‌تری کمک کند و در صورت انتخاب ناآگاهانه ممکن است باعث شکست یک پروژه (بخصوص در بلند مدت) شود.


تاریخچه

SQL توسط شرکت IBM در اوایل دهه 70 میلادی ایجاد شد. با اوج گرفتن زبان‌های رویه‌ای، SQL هم چندان از این قافله عقب نماند که منجر به پذیرش SP به عنوان یک استاندارد، در دهه 90 میلادی و پیاده سازی تدریجی آن توسط غول‌های سازنده دیتابیس شد (رجوع فرمایید به ^ و ^). این فاصله 20 ساله باعث غنی‌تر شدن SQL شد و وجود SP - به معنی انتقال مدل برنامه نویسی رویه‌ای به SQL - بخشی از مشکلات قبلی کار با کوئری‌های پشت سر هم و خام را حل کرد. از سال 2000 میلادی به بعد، ORM‌های قدرتمندی از جمله  Hibernate  و پیاده سازی‌های مختلفی از Active Record  و Entity Framework متولد شدند. بنابر این تقدم و تاخّرهای زمانی، بدیهی است اغلب مزایای SP نسبت به Raw SQL Query و اغلب معایب آن نسبت به ORM‌ها باشد. 

بنظر میرسد برای پاسخ به سوال اصلی این مطلب، ناگزیر به مقایسه SP با رقبای دیرینه‌اش هستیم. با برشمردن معایب و مزایای SP میتوان به نتیجه‌ی منطقی‌تری رسید. البته باید در نظر داشت صرف استفاده از SP به معنای بهره‌مند شدن از مزایای آن و صرف استفاده نکردن از آن هم بهره‌مندی از رقبای آن نیست. چگونگی استفاده یک ابزار، مهمتر از خود ابزار است.


معایب SP

- دستورات Alter Table ، Add Column و Drop Column  به این سادگی‌ها هم نیستند؛ ممکن است به یکی از جداول دیتابیس دو ستون اضافه یا از آن حذف شوند. مجبوریم تمامی SP‌ها را بخصوص Insert و Update متناظر با جدول را تغییر دهیم که این تغییرات ممکن است بصورت زنجیره‌وار به سایر SP‌ها هم سرایت کند. حال شرایطی را در نظر بگیرید که تعداد SP‌های شما به چند ده و یا حتی به چند صد عدد و بیشتر، رسیده باشد که این به معنی زحمت بیشتر و تغییرات پر هزینه‌تر است.

- احتمال کند شدن ماشین سرویس دهنده در اثر اجرای تعداد زیادی SP ؛ چناچه بخش زیادی از منطق برنامه از طریق SP اجرا شود، سرور دیتابیس موظف به اجرای آنهاست. اما در صورتیکه منطق، در کد برنامه قرار داشته باشد، امکان توزیع آن بر روی سرور‌های مجزا و یا حتی ماشین کلاینت وجود خواهد داشت. امروزه اکثر کلاینت‌ها به دیتابیس‌های سبک و سریعی مجهز شده‌اند. بنابراین در صورت امکان چرا بار پردازشی را به عهده آنها نگذاریم؟! 

- یکپارچگی کمتر؛ تقریبا همه اپلیکیشن‌ها نیازمند ارتباط با سایر سیستم‌ها هستند. اگر بخش‌های زیادی از منطق برنامه درون SP مخفی شده باشند، این نقطه تلاقی بین سیستمی، احتمالا درون خود دیتابیس قرار میگیرد و این به معنی ایجاد SP های بیشتر، افزودن پارامتر‌های بیشتر، توسعه SPهای قبلی و بطور خلاصه اعمال تغییرات بیشتر، که منتج به قابلیت نگهداری کمترخواهد شد.

- انعطاف پذیری کمتر؛ در یک شرایط ایده آل، عملکرد اپلیکیشن، مستقل از دیتابیس است. اگر نیاز به تغییر دیتابیس، مثلا از اوراکل به Microsoft SQL Server وجود داشته باشد، نیاز به بازنویسی و انتقال فانکشن‌ها و SP ها محتمل است و از آنجائیکه که با وجود استانداردها، دیتابیس‌های مختلف، معمولا در Syntax دستورات، تفاوت‌های فاحشی دارند، هر چه کد بیشتری در SP ها باشد، نیاز به انتقال و تبدیل بیشتری وجود دارد. 

- عدم وجود بازخورد مناسب؛ بسیاری از اوقات در صورت بروز اشکالی در حین اجرای یک SP، فقط با یک متن ساده بصورت Table has no rows   و یا  error مواجه میشویم. چنین خطاهایی هنگام دیباگ اصلا خوشایند نیستند. MS SQL در این بین بازخورد‌های مناسبی را ارائه میکند. اگر تجربه کار با سایر دیتابیس‌ها را داشته باشید، اهمیت بازخورد‌های مناسب، ملموس‌تر خواهد بود.

- کد نویسی سخت‌تر؛ نوشتن کد SQL  معمولا در همان IDE  اپلیکیشن انجام نمیشود. جابجایی مداوم بین دو IDE ، دیباگ و کد نویسی از طریق دو اینترفیس مجزا، اصلا ایده‌ال نیست. 

- SP  منطق را بیش از حد پنهان میکند؛ حتی با دانستن نام صحیح یک SP، باز هم تصویری از پارامتر‌های ارسالی به آن و نتیجه برگشتی نخواهیم داشت. نمیدانیم نتیجه حاصل از اجرای SP ما مقداری را برمیگرداند یا خیر؟ در صورت وجود برگشتی، یک Cursor است یا یک مقدار؟ اگر Cursor است شامل چه ستون‌هایی است؟

- SP نمیتواند یک شیء را به عنوان آرگومان بپذیرد؛ بنابراین احتمال کثیف شدن کد به مرور افزایش پیدا میکند و بدتراز آن، در صورت ارسال اشتباه یک پارامتر، یا عدم  تطابق تعداد پارامتر‌ها، مجبور به بررسی تمام آنها بصورت دستی هستیم. برای مثال دو قطعه کد زیر را با هم مقایسه کنید:

INSERT INTO User_Table(Id,Username,Password,FirstName,SureName,PhoneNumber,x,Email)
VALUES (1,'VahidN','123456','Vahid','Nasiri','09120000000','vahid_xxx@example.com')

و معادل آن در یک ORM  فرضی:

public void Insert(User user)
{
  _users.Insert(user);
  db.Save();
}

به‌وضوح قطعه کد sql، قبل از خوب یا بد بودن، زشت است. همچنین پارامتر x آن که فرضاً به تازگی اضافه شده، مقداری را دریافت نکرده و باعث بروز خطا خواهد شد.

- نبود Query Chaining؛ یکی از ویژگی‌های جذاب ORM‌‌های امروزی، امکان تشکیل یک کوئری با قابلیت خوانایی بالا و افزودن شرط‌های بیشتر از طریق  الگوی builder است. قطعه کد زیر یک SP برای جستجوی داینامیک نام و نام خانوادگی در یک جدول فرضی به اسم Users است:

public ICollection<User> GetUsers(string firstName,string lastName,Func<User, bool> orderBy)
{
    var query = _users.where(u => u.LastName.StartsWith(lastName));
    query = query.where(u => u.FirstName.StartsWith(firstName));
    query = query.OrderBy(orderBy);
    return  query.ToList();
}

در مقایسه با معادل SP آن:

CREATE PROCEDURE DynamicWhere 
    @LastName varchar(50) = null,
    @FirstName varchar(50) = null,
    @Orderby varchar(50) = null
AS
BEGIN
    DECLARE @where nvarchar(max)
    SELECT @where = '1 = 1'
 
    IF @LastName IS NOT NULL
        SELECT @Where = @Where + " AND A.LastName LIKE @LastName + '%'"
 
    IF @FirstName IS NOT NULL
        SELECT @Where = @Where + " AND A.FirstName LIKE @FirstName + '%'"
 
    DECLARE @orderBySql nvarchar(max)
    SELECT @orderBySql = CASE
        WHEN @OrderBy = "LastName" THEN "A.LastName"
        ELSE @OrderBy = "FirstName" THEN "A.FirstName"
    END
 
    DECLARE @sql nvarchar(max)
    SELECT @sql = "
    SELECT A.Id , A.AccountNoId, A.LastName, A.FirstName, A.PostingDt, 
    A.BillingAmount
    FROM Users 
    WHERE " + @where + " 
    ORDER BY " + @orderBySql
 
    exec sp_executesql @sql,  N'@LastName varchar(50), @FirstName varchar(50)
        @LastName, @FirstName
END

حاجت به گفتن نیست که قطعه کد اول چقدر خواناتر، انعطاف پذیرتر، خلاصه‌تر و قابل نگهداری‌تر است.

- نداشتن امکانات زبان‌های مدرن؛ زبان‌ها و IDE‌های مدرن، امکانات قابل توجهی را برای نگهداری بهتر، انعطاف پذیری بیشتر، مقیاس پذیری بالاتر، تست پذیری دقیق‌تر و... ارائه میکنند. به عنوان مثال:

  • شیءگرایی و امکانات آن که در SP موجود نیست و در مورد قبلی معایب، به آن مختصرا اشاره شد. در نظر بگیرید اگر SQL زبانی شیء گرا بود و مجهز به ارث بری و کپسوله سازی بود، چقدر قابلیت نگهداری آن بالاتر میرفت و حجم کد‌های نوشته شده میتوانست کمتر باشند.
  • نداشتن Lazy Loading که باعث مصرف زیاد حافظه میشود.
  • نداشتن intellisense حین فراخوانی‌ها.
  • نداشتن Navigation Property که باعث join نویسی‌های زیاد خواهد شد.
  • SQL در مقایسه با یک زبان مدرن ناقص بنظر میرسد و این نوشتن کد آن را سخت‌تر میکند.‌
  • نداشتن امکان تغییر منطقی نام جداول و ستون ها
  • مدیریت تراکنش‌ها بصورت دستی، حال آنکه با الگوی Unit Of Work  این مشکل در یک ORM قدرتمند مثل EF حل شده است.


- زمان بر بودن نوشتن SP؛ گاهی نوشتن یک تابع در یک ORM یا بعضا نوشتن یک کوئری SQL کوتاه در یک رشته متنی، ساده‌تر از نوشتن کد SP است. آیا برای هر وظیفه کوچک در دیتابیس، نوشتن یک SP ضروری است؟


مزایای SP :

- کمتر کردن Round Trips در شبکه و متعاقبا کاهش ترافیک شبکه؛ اگر از یک فراخوانی استفاده کنیم، کاهش Round Trip‌ها تاثیر چندانی نخواهد داشت. همچنین ارسال یک کوئری کامل، نسبت به ارسال فقط اسم SP و پارامتر‌های آن، پهنای باند بیشتری اِشغال میکند. البته در یک شبکه با سرعت قابل قبول، بعید است این دو مزیت محسوس باشند؛ اما به هر حال برای موارد خاص، دو مزیت محسوب میشوند. نکته دیگر آنکه بدلیل Pre-Compiled بودن SP‌ها و همچنین کَش شدن Execution Plan آنها، اندکی با سرعت بالاتری اجرا میشوند.

- امکان چک کردن سینتکس قبل از اجرای آن؛ در مقایسه با Raw Query مزیت محسوب میشود.

امکان به اشتراک گذاری کد؛ برای پروژه‌هایی که چندین اپلیکیشن با چندین زبان برنامه نویسی مختلف در حال تهیه هستند و نیازمند دسترسی مستقیم به داده‌ها با سرعت به نسبت بالاتری هستند، SP  میتواند یک راه حل ایده آل محسوب شود. بجای پیاده سازی منطق برنامه در هر اپلیکیشن بصورت جداگانه و زحمت کدنویسی هرکدام، میتوان از SP  استفاده کرد. هرچند امروزه معمولا برای حل این مشکل، API های مشترک معماری Restful  ارجحیت دارد. 

- کمک به ایجاد یک پَک؛ در یک زیر سیستم با نیازمندی مشخص که اعمال تغییرات در آن محتمل نمیباشد نیز SP میتواند یک گزینه مناسب به حساب آید. مثلا یک سیستم Membership را در نظر بگیرید که در پروژه‌های مختلف شما مورد استفاده قرار خواهد گرفت. برای مثال میشود یک سیستم Membership  سفارشی را با امکان  Hash  پسورد و  رمز کردن داده‌های حساس،  به کمک SP و Function ‌های مناسب فراهم کرد و در واقع بین Application Login  و Data Logic تمایز قائل شد. شخصا معماری Restful را به این روش هم ترجیح میدهم. 

بهرمند شدن از امکانات بومی SQL ؛ به عنوان نمونه برای ترانهاده کردن خروجی یک کوئری میتوان از فانکشن  Pivot  استفاده کرد. یا فانکشن‌های تحلیلی  Lead  و  Lag  (لینک مستندات اوراکل این دو فانکشن به ترتیب در ^ و ^ ) که بنظر نمیرسد هنوز معادل مستقیمی درORM  ها  داشته باشند. 

تسلط و کنترل بیشتر و دقیقتر بر کوئری نهایی؛ گفته میشود SP و عبارات SQL در دیتابیس، حکم assembly را در سایر زبان‌ها دارند. بنابراین با SP میتوان عبارات SQL و نحوه اجرای آن را در دیتابیس، بطور کامل تحت فرمان داشت. این در حالی است که هر یک از ORM‌ها دستورات زبان برنامه نویسی مبداء را به یک عبارت SQL ترجمه میکنند که این عبارت چندان تحت کنترل برنامه نویس نیست و بیشتر به مدل کاری ORM بستگی دارد. 

امکان join بین دو یا چند دیتابیس مجزا؛ حال آنکه امکان join بین دو Context در ORM ‌ها وجود ندارد. بعلاوه اگر دو دیتابیس مدنظر ما روی دو سرور مجزا باشند، با SP و  کانفیگ Linked Server  کماکان میشود کوئری join  دار نوشت.

برای عملیات‌های Batch مناسب‌تر است؛ در مقام مقایسه با ORM ‌ها که با تکنیک‌های مختلفی سعی در افزایش سرعت عملیات Batch، بخصوص Insert و Update را دارند، SP  با سرعت قابل قبول‌تری اجرا میشود.

عدم نیاز به یادگیری سینتکس و ابزاری جدید؛ موارد بسیاری وجود دارند که فرصت یادگیری تکنولوژی جدیدی مثل یک ORM و یا SQL Bulk و حتی کتابخانه‌های ثالث مبتنی بر این ابزارها  وجود ندارند و ممکن است مجبور شوید برای باقی ماندن در بازار رقابتی، از دانسته‌های قبلی خود استفاده کنید .

تخصصی‌تر کردن وظایف؛ برنامه نویس‌های دیتابیس به صورت تخصصی اقدام به تحلیل روابط و ایندکس‌ها میکنند، دیتابیس را ایجاد و نرمال سازی مینمایند، SP های متناسب را میسازند و به بهترین شکل Optimize و در آخر تست میکنند.

- امنیت به نسبت بالاتر؛ میتوان مجوز اجرای SP را به یک کاربر اعطا کرد، بدون آنکه مجوز دسترسی به جداول مورد استفاده در آن SP را داد. همچنین نسبت به کوئری‌های پارامتری نشده، SQL ارجیحت دارند چون احتمال آسیب پذیری در مقابل SQL Injection را کمتر میکنند.


نتیجه‌گیری

اگرچه SP ها برای پردازش داده‌ها آنقدر هم که در وبلاگ‌ها میخوانیم بد نیستند، اما سوء استفاده از آن، مشکلات عدیده‌ای را ایجاد خواهد کرد. با توجه به روند تغییرات تکنولوژی‌های دسترسی به داده‌ها و معماری‌های مدرن بنظر میرسد SP در بهترین حالت، ابزار مناسبی برای انجام عملیات CRUD است و نه بیشتر؛ مگر در مواردی خاص که به تشخیص شما نیاز به استفاده بیشتر از آن وجود داشته باشد.

مطالب
ExtJs! رویا یا کابوس؟
چندی پیش یکی از دوستان درباره فریم ورک ExtJs سوالاتی را پرسیده بود که تصمیم گرفتم جواب‌های مورد نظر را به صورت عمومی در قالب یک پست منتشر کنم.
  •  ExtJs چیست؟
  •  چه زمانی کاربرد دارد؟
  •  تفاوت آن با سایر فریم ورک‌های جاوااسکریپ در چیست؟
شاید خیلی از شما با MODX آشنایی داشته باشید یا حتی با این CMS کار کرده باشید. اگر این طور است پس حتما با پنجره‌های زیبا و کامپوننت‌های قوی و اعتبارسنجی‌های سفارشی و تعاملاتی Ajax ای آن آشنایی دارید و شاید این سوال به ذهنتان خطور کرده باشد که در طراحی این CMS که بر پایه زبان PHP است دقیقا از چه چیز استفاده شده است؟
پاسخ یک کلمه است: ExtJs. بله درست است در طراحی این CMS تنها از یک فریم ورک جاوااسکریپتی به نام ExtJs استفاده شده است. فریم ورکی که به عقیده بعضی‌ها یک رویا برای توسعه دهندگان وب است و به عقیده سایرین شاید یک کابوس. در این پست قصد دارم به عنوان کسی که با این فریم ورک آشنایی دارم این موضوع را بررسی و مزایا و معایب این فریم ورک را عنوان کنم.
ExtJs یک فریم ورک جاوااسکریپ است بر مبنای Sencha و طراحی شده برای توسعه پروژه‌های وب در مقیاس بزرگ و به صورت cross-platform . مجوز استفاده از این فریم ورک به صورت GPLv3 است.(یعنی مجاز به استفاده رایگان از فایل‌های این فریم ورک هستید به شرطی که قصد استفاده تجاری از پروژه تهیه شده را نداشته باشید! در غیر این صورت باید زحمت خرید نسخه تجاری این فریم ورک را متحمل شوید).
نسخه ای که درباره آن بحث می‌کنیم نسخه چهار این فریم ورک (ExtJs 4) که بر مبنای ExtJs 3 تولید شده است. تفاوت عمده آن با نسخه قبلی در تکمیل ابزار و کامپوننت هاست و از طرفی نسخه چهار این فریم ورک بر مبنای مدل MVC توسعه داده شده است. یعنی همانند Angular و BackBoneJs می‌توانید مفاهیم کنترلر و مدل را به راحتی پیاده سازی کنید.

رویایی به نام ExtJs

اگر بخواهیم این فریم ورک را یک رویا برای توسعه دهندگان وب بنامیم می‌توان عناوین زیر را به عنوان مزایا برشمرد:
  • در درجه اول قابلیتی که این فریم ورک را متفاوت از سایر فریم ورک‌های جاوااسکریپتی می‌کند این است که این فریم ورک انبوهی از کامپوننت‌ها و ویجیت‌های آماده را به همراه خود دارد (با کارایی و انعطاف پذیری قابل قبول) و به نوعی شما را بی نیاز از هرگونه مجموعه کامپوننت‌های دیگر خواهد کرد. 
  • این فریم ورک به خوبی از مباحت OOP پشتیبانی می‌کند و به این صورت است که یک سری مفاهیم و مدل‌های پایه در این فریم ورک تعبیه شده و به راحتی شما می‌توانید مدل‌های مورد نظر خود را بر اساس این مفاهیم و مدل‌های پایه توسعه دهید.
  • تمام مفاهیم و ابزار لازم جهت درخواست‌های Ajax ای و اعتبار سنجی سفارشی و دستکاری عناصر DOM و... به خوبی در این فریم ورک وجود دارد.
  • به دلیل وجود کامپوننت‌های یک دست و آماده به راحتی می‌توانید امکان تغییر theme را در پروزه‌های خود بدون کوچکترین زحمت قرار دهید. 
  • کنترل GridPanel،TreeView ، کنترل‌های ورود اطلاعات، کنترل Tab با قابلیت درخواست‌های لود صفحات به صورت Ajax و Async با کمترین زحمت در کد نویسی و هم چنین چارت‌های بسیار گسترده و متنوع از دیگر مزایای این فریم ورک می‌تواند باشد.
  • ارائه مکانیزمی مناسب برای کار با عملیات داده ای Json. به عنوان نمونه:
Ext.data.JsonP.request({
  url: '@url',
  params: {
  apiKey: '1234'
  },
  callbackKey: 'myCallbackFn',
  success: function(){
 },
  failure: function(){
},
scope: this
});
  • این فریم ورک ابزارهای جالب و کارآمدی برای توسعه به صورت SPA را داراست.
  • کنترل‌های داده ای این فریم ورک در هنگام کار با حجم داده بسیار زیاد، فراتر از انتظار عمل می‌کنند(برای مثال کنترل GridPanel و DataView)
  • اگر قصد تولید و توسعه بک پروژه بزرگ درون سازمانی را دارید و سرعت تولید نیز برای شما مهم است ExtJs در این زمینه کمک شایانی به شما خواهد کرد.
  • و...

حال با همه این تفاسیر آیا این فریم ورک یک رویا برای هر توسعه دهنده وب خواهد بود؟ 

به طور قطع نه. با توجه به اصل واقع بینی! همواره به خاطر داشته باشید که اگر این فریم ورک یک ابزار بی نقص و همه منظوره بود الآن مطمئنا صدها کتاب و مستندات درباره آن نوشته شده بود و شاید شهرتی بس فراتر از این داشت. 

کابوسی به نام ExtJs

  • اگر قصد ایجاد یک وب سایت کوچک و جمع و جور را دارید به طوری که مباحث مربوط به SEO نیز برای شما اهمیت دارد تجربه نشان داده است که انتخاب ExtJs می‌تواند یکی از بزرگ‌ترین اشتباهات در طول عمر کاری شما شود.
  • ExtJs هیچ گونه کمکی برای تولید و توسعه اپلیکیشن‌های موبایل یا پروژه‌های وب گرافیکی نمی‌تواند به شما کند.
  • اگر سرعت یکی از فاکتور خیلی مهم برای شماست بهتر است به این فریم ورک علاقه نشان ندهید.(کتابخانه آن چیزی در حدود 500KB است! البته با فشرده سازی به 150KB خواهد رسید که باز هم قابل قبول نیست)
  • مجوز استفاده برای پروژه‌های تجاری به صورت رایگان نیست.(^)
  • به دلیل وجود ابزار‌های متنوع و زیاد؛ زمان یادگیری برای آشنایی و کار کردن با ابزارها، نسبتا طولانی خواهد شد.
  • کد نویسی برای استفاده از ابزار‌های آن در مقایسه با Jquery و Angular بیشتر خواهد بود(البته این به نوعی مزیت هم است، به دلیل اینکه خوانایی کد‌ها بسیار بالا می‌رود)
  • در طراحی کامپوننت‌ها آن از تگ div در حد غیر قابل قبول استفاده شده است به طوری که Debug صفحات حتی با Firebug هم در بعضی مواقع سخت می‌شود.
  • و...

Ext.Net چیست؟

Ext.Net یک پیاده سازی خاص از فریم ورک ExtJs است که برای توسعه پروژه‌های Asp.Net Web Forms و Asp.Net MVC طراحی شده است. تفاوت اصلی بین این دو محصول در نوع کدنویسی برای استفاده در پروژه‌های Asp.Net است. برای مثال در هنگام کار با Ext.Net و پروژه‌های MVC از آنجا که این محصول سازگاری کامل با موتور Razor دارد به راحتی می‌توانید به صورت سینتکس Razor صفحات خود را طراحی کنید. 

مثال:

ExtJs

Ext.create('Ext.panel.Panel', {
title: 'Fit Layout',
width: 500,
height: 200,
items: {
title: 'Inner Panel',
html: 'Panel content',
bodyPadding: 10,
border: true
},
renderTo: Ext.getBody()
});
اجرای کد بالا با استفاده از ExtJs به صورت زیر خواهد بود:

Ext.Net
@(X.Panel()
        .ID("ExpandablePanel")
        .Title("Panel")
        .Width(500)
        .Height(300)
        .Collapsible(true)
        .Loader(X.ComponentLoader()
            .Url(Url.Action("RenderChild"))
            .Mode(LoadMode.Frame)
            .DisableCaching(true)
            .Params(new { containerId = "ExpandablePanel" })
            .LoadMask(lm => lm.ShowMask = true)
        )
        .Listeners(l => {
            l.Expand.Handler = "this.reload();";
            l.Collapse.Handler = "this.clearContent();";
        })
    )  
خروجی مورد نظر برای Ext.Net:

جمع بندی:
با توجه مواردی که ذکر شد می‌توان به یک نکته مهم رسید و آن هم این است که هنگام انتخاب ExtJs یا Ext.Net (البته این شامل اکثر ابزارهای توسعه دیگر نیز خواهد شد) حتما شرایط موجود و حاکم برای توسعه محصول را مد نظر داشته باشید که این شرایط شامل محیط اجرای محصول، مدت زمان لازم برای توسعه، سطح دانش نیروی‌های توسعه دهنده و ... نیز می‌باشد.
مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 1 - NET Core. چیست؟
NET Core. چیست؟

برای اغلب توسعه دهنده‌های دات نت (برنامه‌های وب و دسکتاپ) تنها یک دات نت فریم ورک شناخته شده وجود دارد: The `Full` .NET Framework
که تنها بر روی ویندوز قابل اجرا است و آخرین نگارش پایدار آن در زمان نگارش این مطلب، 4.6.1 است. این فریم ورک بزرگ، از اجزایی تشکیل شده‌است که در تصویر ذیل قابل مشاهده‌اند:


مهم‌ترین قسمت‌های این فریم ورک «بزرگ» شامل مواردی مانند CLR که کار تبدیل کدهای IL را به کدهای ماشین انجام می‌دهد، BCL که کلاس‌های پایه‌ای را جهت کار با  IO، Text و غیره، فراهم می‌کنند، هستند؛ به علاوه کتابخانه‌هایی مانند Windows Forms، WPF و ASP.NET که برفراز BCL و CLR کار می‌کنند.
هرچند تعدادی از توسعه دهنده‌های دات نت تنها با Full framework کار می‌کنند، اما در طی سال‌های اخیر انشعابات بسیار دیگری از آن به وجود آمده‌اند؛ مانند دات نت‌های ویژه‌ی ویندوزهای 8 و Universal Windows Platform، دات نت مخصوص ویندوز فون 8 و ویندوز فون مبتنی بر پلتفرم سیلورلایت، به علاوه دات نت پلتفرم زامارین برای توسعه‌ی برنامه‌های iOS و Android نیز هم اکنون وجود دارند (البته در اینجا Mono، دات نت میکرو و غیره را هم باید ذکر کرد). این فریم ورک‌ها و انشعابات، به همراه پیاده سازی یک سری موارد مشترک و مواردی کاملا اختصاصی هستند که به سایر پلتفرم‌های دیگر قابل انتقال نیستند.

با زیاد شدن تعداد انشعابات دات نت «بزرگ»، نوشتن کدی که قابل اجرای بر روی تمام پلتفرم‌های یاد شده باشد، مشکل شد. اینجا بود که مفهومی را به نام PCL یا Portable class libraries معرفی کردند:


هدف از PCLها، ساده سازی کامپایل و به اشتراک گذاری کد بین پلتفرم‌های مختلف بود و پشتیبانی قابل توجهی هم از آن در VS.NET وجود دارد. هرچند این روش نسبتا موفق بود اما مشکلاتی را هم به همراه داشت. برای مثال با ارائه‌ی یک انشعاب و پلتفرم دیگری از دات نت «بزرگ»، کتابخانه‌ی PCL موجود، باید برای این انشعاب جدید مجددا کامپایل شود. به علاوه در اینجا تنها محدود به انتخاب امکانات مشترک بین پلتفرم‌های مختلف هستید.

برای رفع این مشکلات در پایان سال 2014، یک «دات نت فریم ورک جدید» به نام NET Core. معرفی شد که سورس باز است و همچنین چندسکویی (از ویندوز، لینوکس و OSX پشتیبانی می‌کند).


هرچند پیشتر Windows Store و ASP.NET Core app به صورت پلتفرم‌هایی مجزا ارائه شده بودند، اما اکنون از یک BCL مشترک به نام CoreFX استفاده می‌کنند و نحوه‌ی توزیع آن‌ها صرفا از طریق نیوگت است. به عبارتی اینبار بجای دریافت یک فریم ورک «بزرگ»، تنها اجزایی را دریافت می‌کنید که از طریق نیوگت سفارش داده‌اید.
به این ترتیب نه تنها کار توزیع برنامه‌های مبتنی بر NET Core. با سهولت بیشتری انجام خواهد شد، بلکه به روز رسانی اجزای یک برنامه، تاثیری بر روی سایر برنامه‌ها نخواهد داشت و مشکلات جانبی را به وجود نمی‌آورد. به علاوه دیگر نیازی نیست تا منتظر یک نگارش «بزرگ» دیگر باشید تا بتوانید آخرین به روز رسانی‌ها را دریافت کنید. اینبار به روز رسانی بسته‌های نیوگت برنامه معادل هستند با به روز رسانی کل فریم ورک در نگارش‌های قبلی «بزرگ» آن. در اینجا حتی CoreCLR و NET Native runtime. که مربوط به Windows runtime است هم از طریق نیوگت به روز رسانی می‌شود.

البته NET Core. انتهای مسیر نیست و هم اکنون NETStandard نیز جهت رفع مشکلات کامپایل مجدد PCLها در حال توسعه است و پس از ارائه‌ی آن، PCLها منسوخ شده درنظر گرفته می‌شوند. در این حالت با انتخاب target platform ایی به نام NETStandard (بجای مثلا انتخاب دات نت 4.5 و ویندوز فون 8)، اینبار دات نت 4.5 و ویندوز فون 8 و تمام پلتفرم‌های دیگر، به صورت یکجا انتخاب می‌شوند و اگر پلتفرم جدیدی برای مثال از NETStandard نگارش 1.1 پشتیبانی کند، به این معنا است که کتابخانه‌ی شما هم اکنون با آن سازگار است و دیگر نیازی به کامپایل مجدد آن نخواهد بود.
به علاوه هر برنامه‌ای که بر اساس NETStandard تهیه شود، قابلیت اجرای بر روی NET Core. را نیز خواهد داشت. به عبارتی برنامه‌های NETStandard همان برنامه‌های مبتنی بر NET Core. هستند.


ASP.NET Core چیست؟

در زمان نگارش این مطلب، دو گزینه‌ی برنامه‌های وب ASP.NET Core 1.0 و همچنین Windows Store apps (مبتنی بر NET Native Runtime.) قابلیت استفاده‌ی از این پلتفرم جدید NET Core. دارند.
ASP.NET Core 1.0، که پیشتر با نام ASP.NET 5 معرفی شده بود، بازنویسی کامل ASP.NET است که با ایده‌ی کاملا ماژولار بودن، تهیه شده‌است و از طریق آن، قابلیت به روز رسانی منظم و توزیع آسان از طریق نیوگت، میسر خواهد شد. به علاوه در آن، بسیاری از الگوهای برنامه نویسی شیء‌گرا مانند تزریق وابستگی‌ها، به صورت توکار و از ابتدا پشتیبانی می‌شوند.
ASP.NET Core 1.0 از WebForms ، VB ، WebPages و SignalR پشتیبانی نمی‌کند. البته در این بین عدم پشتیبانی از «وب فرم‌ها» قطعی است؛ اما افزودن سه مورد دیگر یاد شده، جزو لیست کارهای پس از ارائه‌ی نگارش 1 این فریم ورک قرار دارند و به زودی ارائه خواهند شد.


اکنون وضعیت  ASP.NET MVC 5 و ASP.NET Web API 2 چگونه است؟

ASP.NET Core 1.0 مدل برنامه نویسی ASP.NET MVC و Web API را به صورت یکپارچه ارائه می‌دهد و دیگر خبری از ارائه‌ی مجزای این‌ها نخواهد بود و دقیقا بر مبنای مفاهیم برنامه نویسی این دو بنا شده‌است. به صورت خلاصه MVC + Web API + Web Pages = Core MVC 1.0
پیشتر فضای نام System.Web.MVC مخصوص ASP.NET MVC بود و فضای نام مجزای دیگری به نام System.Web.Http مخصوص ASP.NET Web API. اما اکنون تنها یک فضای نام مشترک و یکپارچه به نام Microsoft.AspNet.Mvc هر دوی این‌ها را پوشش می‌دهد.

در این نگارش جدید وابستگی از system.web مبتنی بر IIS حذف شده‌است و با استفاده از هاست جدید چندسکویی به نام Kesterl، به سرعتی 5 برابر سرعت NodeJS دست یافته‌اند.


آخرین تاریخ به روز رسانی ASP.NET MVC 5.x دوشنبه، 20 بهمن 1393 است (با ارائه نگارش 5.2.3 که آخرین نگارش رسمی و پایدار آن است) و آخرین تاریخ به روز رسانی ASP.NET Web API 2.x نیز همان روز است.
هرچند مایکروسافت عادت به اعلام رسمی پایان پشتیبانی از بسیاری از محصولات خود را ندارد اما تمام فناوری‌های «قدیمی» خودش را بر روی CodePlex نگهداری می‌کند و تمام فناوری‌های «جدید» را به GitHub منتقل کرده‌است. بنابراین اگر در مورد فناوری خاصی به Codeplex رسیدید، یعنی «دیگر ادامه‌ی رسمی نخواهد یافت» و حداکثر در حد رفع یک سری باگ‌ها و مشکلات گزارش شده باقی می‌مانند.
مثال 1: هم اکنون نگارش دوم ASP.NET Identity را بر روی Codeplex می‌توانید مشاهده کنید. نگارش سوم آن به GitHub منتقل شد‌ه‌است که این نگارش صرفا با ASP.NET Core 1.0 سازگار است. در مورد ASP.NET MVC و Web API نیز چنین حالتی رخ داده‌است. نگارش‌های 5 و 2 آن‌ها بر روی Codeplex موجود هستند و نگارش ششم که به ASP.NET Core 1.0 تغییر نام یافت و ترکیبی است از MVC و Web API، در GitHub توسعه می‌یابد.
مثال 2: WCF به علت پیچیدگی بیش از حد و مدرن نبودن طراحی آن، رقابت را به ASP.NET Web API 2.x واگذار کرد و مدل برنامه نویسی ASP.NET Web API 2.x نیز هم اکنون جزئی از ASP.NET Core 1.0 است. بنابراین اگر قصد ایجاد پروژه‌ی جدیدی را بر این مبنا دارید، بهتر است با APS.NET Core 1.0 کار را شروع کنید.


اما هنوز تعداد زیادی از کتابخانه‌های Full framework به NET Core. انتقال پیدا نکرده‌اند

برای نمونه هنوز EF Core 1.0 که پیشتر نام EF 7.x به آن داده شده بود، به مرحله‌ی نهایی تکمیل قابلیت‌های آن نرسیده‌است. اما باید دانست که ASP.NET Core 1.0 صرفا بر فراز NET Core. قابل اجرا نیست؛ بلکه قابلیت اجرای بر فراز NET 4.6. و یا همان دات نت «بزرگ و کامل» را نیز دارد. بنابراین به سادگی قابلیت اجرای EF 6.x و یا NHibernate را نیز دارا است. تنها مزیتی را که در اینجا از دست خواهید، قابلیت چندسکویی بودن ASP.NET Core 1.0 است؛ زیرا EF 6.x با چنین دیدی طراحی نشده‌است.



همانطور که ملاحظه می‌کنید، ASP.NET Core 1.0 قابلیت اجرای بر روی هر دوی NET Core 1.0. و NET 4.6. را دارا است. اما یکی، چندسکویی است و دیگری صرفا مختص به ویندوز.


فناورهای منسوخ شده‌ی در NET Core.

یکسری از فناوری‌ها و کتابخانه‌ها احتمالا هیچگاه قابلیت انتقال به NET Core. را نخواهند یافت و یا حداقل باید تا چندنگارش بعدی آن صبر کنند. فناوری‌های خاتمه یافته‌ی با NET Core. به شرح زیر هستند:
- Reflection: همانطور که عنوان شد، NET Core. بر فراز CoreCLR و همچنین NET Native runtime. اجرا می‌شود و تولید برنامه‌های native و static linking آن‌ها مانند برنامه‌های ++C، نیاز به دانستن اجزایی دارد که به صورت پویا فراخوانی نمی‌شوند و بلافاصله و در زمان کامپایل، توسط کامپایلر قابل تشخیص هستند. همین محدودیت سبب شده‌است که استفاده‌ی از Reflection در NET Core. به حداقل ممکن آن برسد. برای مثال در System.Object متد GetType آن تنها نام نوع را باز می‌گرداند و نه اطلاعات بیشتری را مانند  GetMembers سابق.
- App Domains: هرچند CoreCLR از App Domains پشتیبانی می‌کند اما NET Native runtime. خیر. به همین جهت برای ایزوله سازی برنامه‌ها توصیه شده‌است که از containerهایی مانند docker استفاده شود.
- Remoting: پیش از WCF جهت برقراری ارتباط بین برنامه‌ها مطرح شده بود و هم اکنون در دات نت کامل هم آنچنان استفاده‌ای از آن نمی‌شود.
- binary serialization: البته کتابخانه‌هایی مانند JSON.NET و امثال آن، نگارش NET Core. هم دارند؛ اما چون binary serialization نیاز به اطلاعات reflection قابل توجهی دارد دیگر پشتیبانی نخواهد شد.


فناور‌هایی که به زودی به NET Core. منتقل می‌شوند

یکسری از فناوری‌ها مانند XAML هنوز معادل NET Core. ندارند و لیست زیر قرار است از طرف مایکروسافت سورس باز شده و همچنین به NET Core. منتقل شود:
System.Data
System.DirectoryServices
System.Drawing
System.Transactions
System.Xml.Xsl and System.Xml.Schema
System.Net.Mail
System.IO.Ports
System.Workflow
System.Xaml


مراحل نصب ASP.NET Core 1.0

پیش از نصب نگارش 1.0 RTM باید به این نکته دقت داشت که نصاب آن، نگارش‌های آزمایشی قبلی را حذف و یا بازنویسی نمی‌کند و همین مساله ممکن است سبب بروز تداخل‌هایی و یا حتی از کار افتادن VS.NET شما شود. بنابراین اگر نگارش‌های RC یا بتا را پیشتر نصب کرده‌اید، به Add remove programs ویندوز مراجعه کرده و سه مورد ذیل را حتما حذف کنید (خیلی مهم):
- Preview Tooling (all versions)
- NET Core Runtime SDK (all versions).
- NET Core Runtime (all Versions).
پس از حذف بسته‌های قدیمی، برای نصب نگارش 1.0 RTM، ابتدا نیاز است Visual Studio 2015 Update 3 را نصب کنید و پس از آن با استفاده از NET Core for Visual Studio Official MSI Installer. کار نصب اجزای مورد نیاز آن انجام خواهد شد.


بررسی شماره نگارش 1.0 RTM

پس از نصب اجزای عنوان شده، خط فرمان را گشوده و دستور ذیل را صادر کنید:
 C:\Users\Vahid>dotnet --version
1.0.0-preview2-003121
همانطور که مشاهده می‌کنید، نگارش ذکر شده هنوز در مرحله‌ی preview است و صرفا مرتبط است به tooling و یا ابزارهای مرتبط با آن.
اگر یک پروژه‌ی خالی ASP.NET Core Web Application را نیز شروع کنید (با طی مراحل زیر جهت ایجاد یک پروژه‌ی جدید):
 .NET Core -> ASP.NET Core Web Application (.NET Core) -> Select `Empty` Template


در اینجا فایل جدیدی را به نام global.json مشاهده می‌کنید که محتوایات آن شامل دقیقا همین شماره نگارش است؛ به همراه معرفی پوشه‌های اصلی پروژه:
{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview2-003121"
  }
}
نظرات مطالب
معماری میکروسرویس‌ها
اگر تجزیه و تحلیل، طراحی و پیاده‌سازی هر معماری و روشی به درستی انجام بشه میزان اشکالات یا چالش‌ها به حداقل میرسن. به عنوان مثال، کندی در بستر شبکه به دلیل خود این معماری نیست، بلکه این سیستم نیاز به یک شبکه سالم و نرمال داره، نه شبکه‌ای که قطعی زیاد و مسدودسازی‌های اشتباه داره. شبکه مریض تاثیر مخرب بر روی هر دو معماری داره و از اونجایی که این معماری آمده تا مشکلات کندی Monolithic رو با توزیع پذیری بیشتر رفع کنه با کارایی پایین مواجه میشه.
نیاز به پیاده‌سازی صحیح و بستر مناسب رو میشه برای باقی چالش‌های احتمالی که با آنها چندان موافق نبودید هم در نظر گرفت. 
اشتراک‌ها
18 روش خلاقانه استفاده از Docker در کارهای روزانه
18 Innovative Ways to Use Docker Daily

- Running GUI Applications in Docker Containers
- How to Run a Web Browser Inside Docker
- Using Obsidian Note-Taking App via Docker
- LibreOffice in Docker: Open-Source Office Suite Containerized
- Contribute to Science: Folding@Home with Docker
- Effortless Docker Management with Docker Desktop and Portainer
- Secure Document Handling Using Dangerzone and Docker
- Containerizing CLI Tools for a Clean System
- Enhance Docker Security with Docker Scout
- Set Up an Isolated Hacking Lab with Docker and Kali Linux
- Master Docker Networks for Container Isolation
- Automate Your Docker Workflows with Docker Compose
- Explore New Operating Systems Using Docker Containers
- Running macOS in a Docker Container (Educational Purposes)
- How to Run Raspberry Pi OS via Docker
- Access a Suite of IT Tools Inside a Docker Container
- Using Docker to Containerize AI Tools like Fabric
- Safely Test Applications with Docker Containers
- Building Custom Docker Images from Scratch
- Unconventional Docker Use Cases You Need to Know
- Daily Docker Tips and Tricks for Enhanced Productivity
- Beginner's Guide to Advanced Docker Techniques
- Boost Your IT Workflow with These Docker Hacks
- Docker for Everyday Tasks: Beyond Development
18 روش خلاقانه استفاده از Docker در کارهای روزانه