مطالب
استفاده از LocalDb در IIS، قسمت اول: پروفایل کاربر
این مقاله قسمت اول یک سری دو قسمتی است، که در آن به نحوه استفاده از LocalDB در IIS می‌پردازیم.

LocalDb دیتابیس توصیه شده برای ویژوال استودیو است و برای انواع پروژه‌ها مانند اپلیکیشن‌های وب می‌تواند استفاده شود. هنگام استفاده از این دیتابیس در IIS Express یا Cassini همه چیز طبق انتظار کار میکند. اما به محض آنکه بخواهید از آن در Full IIS استفاده کنید با خطاهایی مواجه می‌شوید. مقصود از Full IIS همان نسخه ای است که بهمراه ویندوز عرضه می‌شود و در قالب یک Windows Service اجرا می‌گردد.

هنگام استفاده از Full IIS دو خاصیت از LocalDb باعث بروز مشکل می‌شوند:

  • LocalDb نیاز دارد پروفایل کاربر بارگذاری شده باشد
  • بصورت پیش فرض، وهله LocalDb متعلق به یک کاربر بوده و خصوصی است

در ادامه این مقاله روی بارگذاری پروفایل کاربر تمرکز می‌کنیم، و در قسمت بعدی به مالکیت وهله LocalDb می‌پردازیم.


بارگذاری پروفایل کاربر

بگذارید دوباره به خطای موجود نگاهی بیاندازیم:

System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 0 - [x89C50120]) 

این پیغام خطا زیاد مفید نیست، اما LocalDb اطلاعات بیشتری در Event Log ویندوز ذخیره می‌کند. اگر Windows Logs را باز کنید و به قسمت Application بروید پیغام زیر را مشاهده خواهید کرد.

Windows API call SHGetKnownFolderPath returned error code: 5. Windows system error message is: Access is denied
Reported at line: 400

بعلاوه این پیام خطا:

Cannot get a local application data path. Most probably a user profile is not loaded. If LocalDB is executed under IIS, make sure that profile loading is enabled for the current user. 


به احتمال زیاد تعداد بیشتری از این دو خطا در تاریخچه وقایع وجود خواهد داشت، چرا که منطق کانکشن ADO.NET چند بار سعی می‌کند در بازه‌های مختلف به دیتابیس وصل شود.

پیغام خطای دوم واضح است، نیاز است پروفایل کاربر را بارگذاری کنیم. انجام اینکار زیاد مشکل نیست، هر Application Pool در IIS تنظیماتی برای بارگذاری پروفایل کاربر دارد که از قسمت Advanced Settings قابل دسترسی است. متاسفانه پس از انتشار سرویس پک 1 برای Windows 7 مسائل کمی پیچیده‌تر شد. در حال حاظر فعال کردن loadUserProfile برای بارگذاری کامل پروفایل کاربر به تنهایی کافی نیست، و باید setProfileEnvironment را هم فعال کنیم. برای اطلاعات بیشتر در این باره به مستندات KB 2547655 مراجعه کنید. بدین منظور باید فایل applicationHost.config را ویرایش کنید. فایل مذکور در مسیر C:\Windows\System32\inetsrv\config قرار دارد. همانطور که در مستندات KB 2547655 توضیح داده شده، باید پرچم هر دو تنظیمات را برای ASP.NET 4.0 فعال کنیم:

 <add name="ASP.NET v4.0" autoStart="true" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated">
    <processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</add>
پس از بروز رسانی این تنظیمات، Application Pool را Restart کنید و اپلیکیشن را مجددا اجرا نمایید. اگر همه چیز طبق انتظار پیش برود، با خطای جدیدی مواجه خواهیم شد:

جای هیچ نگرانی نیست، چرا که این پیغام خطا انتظار می‌رود. همانطور که در ابتدا گفته شد، دو خاصیت LocalDb باعث بروز این خطاها می‌شوند و ما هنوز به خاصیت دوم نپرداخته ایم. بصورت پیش فرض وهله‌های LocalDb خصوصی (private) هستند و در Windows account جاری اجرا می‌شوند. بنابراین ApplicationPoolIdentity در IIS به وهله‌های دیتابیس دسترسی نخواهد داشت. در قسمت دوم این مقاله، راه‌های مختلفی را برای رفع این مشکل بررسی می‌کنیم.

نظرات مطالب
یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017
روش دیگری بجای استفاده از فایل‌های bat

در انتهای بحث یک سری فایل bat معرفی شدند که کار اجرای دستورات مرتبط را ساده‌تر می‌کنند. روش دوم اجرای این نوع دستورات، استفاده از همان فایل package.json است. قسمت scripts آن‌را به صورت ذیل تکمیل کنید:
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "_0-prerestore": "npm install",
    "_0-restore": "dotnet restore",
    "_1-ng-build-dev": "ng build --watch",
    "_1-ng-build-prod": "ng build --prod --watch",
    "_2-dotnet-run": "dotnet watch run",
    "_2-ng-serve-proxy": "ng serve --proxy-config proxy.config.json -o"
  },
سپس افزونه‌ی NPM Task Runner را نیز نصب کنید.
اکنون اگر بر روی فایل package.json، در ویژوال استودیو کلیک راست کنید، گزینه‌ی Task Runner Explorer اضافه شده‌است. با انتخاب آن امکانات ذیل ظاهر می‌شوند:


در اینجا با کلیک راست بر روی هر گزینه، امکان اجرای آن وجود خواهد داشت.
مطالب
آموزش (jQuery) جی کوئری 7#
پس از انواع روش‌های انتخاب عناصر در jQuery اکنون زمان آشنایی با متدها و توابعی جهت پردازش مجموعه انتخاب شده رسیده است.
٢-٣- مدیریت مجموعه انتخاب شده
هز زمان که مجموعه ای از عناصر انتخاب انتخاب می‌شوند، خواه این عناصر از طریق انتخاب کننده‌ها انتخاب شده باشند و یا تابع ()$ در صدد ایجاد آن باشد، مجموعه ای در اختیار داریم که آماده دستکاری و اعمال تغییر با استفاده از متدهای jQuery می‌باشد. این متدها را در پست‌های آتی بررسی خواهیم کرد. اما اکنون به این نکته می‌پردازیم که اگر بخواهیم از همین مجموعه انتخاب شده زیر مجموعه ای ایجاد کنیم و یا حتی آن را گسترش دهیم، چه باید کرد؟ به طور کلی در این پست پیرامون این مورد بحث خواهد شد که چگونه می‌توانیم مجموعه انتخاب شده را به آن صورت که می‌خواهیم بهیود دهیم.
برای درک مطالبی که قصد توضیح آنها را در این قسمت داریم، یک صفحه کارگاهی دیگر نیز در فایل قابل دانلود این کتاب موجود می‌باشد که با نام chapter2/lab.wrapped.set.html قابل دسترسی می‌باشد. نکته مهم در مورد این صفحه کارگاهی آن است که می‌بایست عبارات و دستورهای کامل را با ساختار صحیح وارد کنیم در غیر این اینصورت این صفحه کاربردی نخواهد داشت.


٢-٣-١-تعیین اندازه یک مجموعه عناصر
قبلا اشاره کردیم که مجموعه عناصر jQuery شباهت هایی با آرایه دارد. یکی از این شباهت‌ها داشتن ویژگی length می‌باشد که مانند آراه در جاوااسکریپت ، تعداد عناصر موجود در مجموعه را شامل می‌شود.
افزون بر این ویژگی، jQueryیک متد را نیز معرفی کرده است که دقیقا شبیه به length عمل می‌کند. این متد ()size می‌باشد که استفاده از آن را در مثال زیر مشاهده می‌کنید.
$('#someDiv')
       .html('There are '+$('a').size()+' link(s) on this page.');
این مثال تمام لینک‌های موجود در صفحه را شناسایی می‌کند و سپس بااستفاده از متد ()size تعداد آنها را بر می‌گرداند. در واقع یک رشته ایجاد می‌شود و در یک عنصر با شناسه someDiv قرار داده می‌شود. متد html در پست‌های آتی بررسی می‌شود. فرم کلی متد ()size را در زیر مشاهده می‌کنید.
()size
تعداد عناصر موجود در مجموعه را محاسبه می‌کند
پارامترها
بدون پارامتر
خروجی
تعداد عناصر مجموعه
اکنون که تعداد عناصر مجموعه را می‌دانیم چگونه می‌توانیم به هریک از آنها دسترسی مستقیم داشته باشیم؟

٢-٣-٢-بکارگیری عنصرهای مجموعه
به طور معمول پس از انتخاب یک مجموعه با استفاده از متدهای jQuery، عملی را بروی آن عناصر انتخاب شده انجام می‌دهیم، مانند مخفی کردن آنها با متد ()hide، اما گاهی اوقات می‌خواهیم بروی یک یا چند مورد خاص از عناصر انتخاب شده عملی را اعمال کنیم. jQuery چند روش مختلف را به منظور اینکار ارایه می‌دهد.

از آنجا که مجموعه عناصر انتخاب شده در jQuery مانند آرایه در جاوااسکریپت می‌باشد، بنابراین به سادگی می‌توانیم از اندیس برای دستیابی به عناصر مختلف مجموعه استفاده کنیم. برای مثال به منظور دسترسی به اولین عکس از مجموعه عکس‌های انتخاب شده که دارای صفت alt می‌باشند از دستور زیر استفاده می‌کنیم:
$('img[alt]')[0]
اما اگر ترجیح می‌دهید به جای اندیس از یک متد استفاده کنید، jQuery متد ()get را در نظر گرفته است:
(get(index
برای واکشی یک یا تمام عناصر موجود در مجموعه استفاده می‌شود. اگر برای این متد پارامتری ارسال نشود، تمام عناصر را در قالب یک آرایه جاوااسکریپت بر می‌گرداند، اما در صورت ارسال یک پارامتر، تنها آن عنصر را بر می‌گرداند.
پارامتر
شماره اندیس یک عنصر که می‌بایست یک مقدار عددی باشد.
خروجی
یک یا آرایه ای از عناصر
دستور زیر مانند دستور قبلی عمل می‌کند:
$('img[alt]').get(0)
متد ()get می‌تواند برای بدست آوردن یک ارایه از عناصر پیچیده نیز استفاده شود. مثلا:
var allLabeledButtons = $('label+button').get();
خروجی دستور بالا لیست تمام button‌های موجود در صفحه است که بعد از عنصر label قرار گرفته اند، در نهایت این آرایه در متغیری به نام allLabeledButtons قرار خواهد گرفت.

در متد ()get دیدیم که با دریافت شماره اندیس یک عنصر، آن عنصر را برای ما برمی گرداند، عکس این عمل نیز امکان پذیر می‌باشد. فرض کنید می‌خواهیم از میان تمام عناصر عکس، شماره اندیس عکسی با شناسه findMe را بدست آوریم. برای این منظور می‌توانیم از کد زیر بهره ببریم:

var n = $('img').index($('img#findMe')[0]);
فرم کلی متد ()index به صورت زیر است:
(index(element
عنصر ارسالی را در مجموعه عناصر پیدا می‌کند، سپس شماره اندیس ان را بر می‌گرداند. اگر چنین عنصری در مجموعه یافت نشد خروجی 1- خواهد بود.
پارامتر
پارامتر این متد می‌تواند یک عنصر و یا یک انتخاب کننده باشد که خروجی انتخاب کننده نیز در نهایت یک عنصر خواهد بود.
خروجی
شماره اندیس عنصر در مجموعه

٢-٣-٣-برش و کوچک کردن مجموعه ها
ممکن است شرایطی پیش آید که پس از بدست آوردن یک مجموعه عناصر انتخاب شده نیاز باشد که عنصری به آن مجموعه اضافه و یا حتی عنصری را از آن حذف کنیم تا در نهایت مجموعه ای باب میل ما بدست آید. برای انجام چنین تغییرهایی در یک مجموعه jQuery کلکسیون بزرگی از متدها را برای ما به همراه دارد. اولین موردی که به آن می‌پردازیم، افزودن یک عنصر به مجموعه می‌باشد.

اضافه کردن عناصر بیشتر به یک مجموعه عنصر انتخاب شده
همواره ممکن است شرایطی پیش آید که پس از ایجاد یک مجموعه عناصر انتخاب شده، بخواهیم عنصری را به آن اضافه کنیم. یکی از دلایلی که باعث می‌شود این امر در jQuery بیشتر مورد نیاز باشد توانایی استفاده از متدهای زنجیره ای در jQuery است.
ابتدا یک مثال ساده را بررسی می‌کنیم. فرض کنید می‌خواهیم تمام عناصر عکس که دارای یکی از دو خصوصیت alt و یا title می‌باشند را انتخاب کنیم، با استفاده از انتخاب کننده‌های قدرتمند jQuery دستوری مانند زیر خواهیم نوشت:
$('img[alt],img[title]')
اما برای آنکه با متد ()add که به منظور افزودن عنصر به مجموعه عناصر می‌باشد آشنا شوید این مثال را به صورت زیر می‌نویسیم:
$('img[alt]').add('img[title]')
استفاده از متد ()add به این شکل موجب می‌شود تا بتوانیم مجموعه‌های مختلف را به یکدیگر متصل کنیم و یک مجموعه کلی‌تر از عناصر انتخاب شده ایجاد کنیم. متد ()add در این حالت مانند متد ()end عمل می‌کند که در قسمت ٢-٣-٦شرح داده خواهد شد.
ساختار کلی متد ()add به صورت زیر است:
َ(add(expression
ابتدا یک کپی از مجموعه انتخاب شده ایجاد می‌کند، سپس با افزودن محتویات پارامتر expression به آن نمونه، یک مجموعه جدید تشکیل می‌دهد. پارامتر expression می‌تواند حاوی یک انتخاب کننده، قطعه کد HTML، یک عنصر و یا آرایه ای از عناصر باشد.
پارامتر
در این پارامتر مواردی (مانند رشته، آرایه، المان) که می‌خواهیم به مجموعه عناصر انتخاب شده اضافه شوند قرار می‌گیرد. که می‌تواند انتخاب کننده، قطعه کد HTML، یک عنصر و یا ارایه ای از عناصر باشد.
خروجی
یک کپی از مجموعه اصلی به علاوه موارد اضافه شده.
اصلاح عناصر یک مجموعه عنصر انتخاب شده
در قسمت قبل دیدیم که چگونه با استفاده از متد ()add و با بکار گیری آن در توابع زنجیره ای، توانستیم عناصری جدید به مجموعه انتخاب شده اضافه کنیم. عکس این عمل را نیز می‌توان با ستفاده از متد ()not در توابع زنجیره ای انجام داد. این متد عملکرید شبیه به فیلتر not: دارد، اما با این تفاوت که بکار گیری آن مانند متد ()add می‌باشد و می‌توان در هر جایی از زنجیره از آن استفاده کرد تا عناصر مورد نظر را از مجموعه انتخاب شده حذف کنیم.
فرض کنید می‌خواهیم تمامی عناصر عکسی را که دارای خصوصیت title می‌باشند به استثنای آن موردی که واژه puppy در مقدار مربوط به این صفت استفاده کرده اند را انتخاب کنیم. این کار به سادگی و با استفاده از دستوری مانند([ "img[title]:not([title*="puppy می‌توان انجام داد. اما برای آن که مثالی از چگونگی کار متد ()not ببینید، این کار را به شکل زیر انجام می‌دهیم:
$('img[title]').not('[title*=puppy]')
این دستور تمام عکس‌های دارای خصوصیت title را به استثنا titleهایی که مقدار puppy در آنها وجود دارد را انتخاب می‌کند.
شکل کلی متد ()not مانند زیر است:
(not(expression
ابتدا یک کپی از مجموعه انتخاب شده ایجاد می‌کند، سپس از آن کپی عناصری را که expression مشخص می‌کند را حذف می‌نماید.
پارامتر
این پارامتر تعیین کننده عناصر در نظر گرفته شده برای حذف می‌باشد. این پارامتر می‌تواند یک عنصر، ارایه ای از عناصر، انتخاب کننده و یا یک تابع باشد.
اگر این پارامتر تابع باشد، تک تک عناصر مجموعه به آن ارسال می‌شوند و هر یک که خروجی تابع را برابر با مقدار true کند، حذف می‌شود.
خروجی
یک کپی از مجموعه اصلی بدون موارد حذف شده. 
این شیوه برای ایجاد مجموعه هایی که انتخاب کننده‌ها قادر به ساخت آن‌ها نمی‌باشند، کاربرد بسیار مناسبی دارد، زیرا از تکنیک‌های برنامه نویسی استفاده می‌کند و دست ما را برای اعمال انتخاب‌های گوناگون باز می‌کند.
اگر در شرایطی خاص با حالتی روبرو شدید که احساس کردید عکس این انتخاب برای شما کارایی دارد، باز می‌توانید از یکی دیگر از متدهای jQuery استفاده کنید، متد ()filter عملکردی مشابه با متد ()not دارد با این تفاوت که عناصری از مجموعه حذف می‌شوند که خروجی تابع را false کنند.
فرض کنید می‌خواهیم تمام عناصر td که دارای یک عنصر عددی می‌باشند را انتخاب کنیم. با وجود قدرت فوق العاده انتخاب کننده‌های jQuery به ما ارایه می‌دهند، انجام چنین کاری با استفاده از انتخاب کننده‌ها غیر ممکن است. در این حالت از متد ()filter را به شکل زیر استفاده می‌کنیم:
$('td').filter(function(){return this.innerHTML.match(/^\d+$/)})
دستور فوق یک مجموعه از تمام عناصر td انتخاب می‌کند، سپس تک تک عناصر مجموعه انتخاب شده را به تابعی که پارامتر متد ()filter می‌باشد، ارسال می‌کند. این تابع با استفاده از عبارت منظم مقدار عنصر کنونی را می‌سنجد. اگر این مقدار یک یا زنجیره ای از ارقام بود، خروجی تابع true خواهد بود، و ان عنصر از مجموعه حذف نمی‌شود، اما اگر این مقدار عددی نبود، خروجی تابع false بوده و عنصر از مجموعه کنار گذاشته می‌شود.
شکل کلی متد ()filter به شکل زیر است.
(filter(expression
ابتدا یک کپی از مجموعه انتخاب شده ایجاد می‌کند، سپس از آن کپی عناصری را که expression مشخص می‌کند را حذف می‌نماید.
پارامتر
این پارامتر تعیین کننده عناصر در نظر گرفته شده برای حذف می‌باشد. این پارامتر می‌تواند یک عنصر، ارایه ای از عناصر، انتخاب کننده و یا یک تابع باشد.
اگر این پارامتر تابع باشد، تک تک عناصر مجموعه به آن ارسال می‌شوند و هر یک که خروجی تابع را برابر با مقدار false کند، حذف می‌شود.
خروجی
یک کپی از مجموعه اصلی بدون عناصر حذف شده.  

ایجاد یک زیر مجموعه از مجموعه عناصر انتخاب شده
گاهی اوقات داشتن یک زیر مجموعه از عناصر یک مجموعه، چیزی است که دنبال آن هستیم. برای این منظور jQuery متد ()slice را ارایه می‌کند که عناصر را بر اساس جایگاه آن‌ها به زیر مجموعه هایی کوچکتر تقسیم می‌کند. نتیجه استفاده از این متد یک مجموعه جدید برگرفته از تعدادی عناصر پشت سر هم،از یک مجموعه انتخاب شده خواهد بود:
شکل کلی متد ()slice مانند زیر است:
(slice(begin, end
ایجاد و برگرداندن یک مجموعه جدید از بخشی از عناصر پشت سر هم در یک مجموعه اصلی.
پارامتر
begin: پارامتر begin که یک پارامتر عددی می‌باشد و مقدار اولیه آن از صفر آغاز می‌شود، نشان دهنده اولین عنصری است که می‌خواهیم در مجموعه جدید حضور داشته باشد.
end: پارامتر دوم که آن هم یک پارامتر عددی می‌باشد و از صفر آغاز می‌شود، در این متد اختیاری است. این پارامتر اولین عنصری است که نمی‌خواهیم از آن به بعد در مجموعه جدید حضور داشته باشد را مشخص می‌کند. اگر مقداری برای این پارامتر ننویسیم، به صورت پیش فرض تا انتهای مجموعه انتخاب می‌شود.
خروجی
یک مجموعه عنصر جدید.
 اگر بخواهیم از یک مجموعه کلی، تنها یک عنصر را در قالب یک مجموعه انتخاب کنیم می‌توانیم از متد ()slice استفاده کنیم و مکان آن عنصر در مجموعه را به آن ارسال کنیم. دستور زیر مثالی از این حالت می‌باشد:
$('*').slice(2,3);
این مثال ابتدا تمام عناصر موجود در صفحه را انتخاب می‌کند، سپس سومین عنصر از آن مجموعه را در یک مجموعه جدید باز می‌گرداند. دقت کنید که دستور فوق با دستور (2)get.('*')$ کاملا متفاوت است، چرا که خروجی این دستور تنها یک عنصر است، در حالی که خروجی دستور فوق یک مجموعه است.
از همین رو دستور زیر باعث ایجاد یک مجموعه که شامل چهار عنصر اولیه صفحه می‌باشد، می‌شود.
$('*').slice(0,4);
برای ایجاد یک مجموعه از عناصر انتهایی موجود در صفحه نیز می‌توان از دستوری مانند زیر استفاده کرد:
$('*').slice(4);
این دستور تمام عناصر موجود در صفحه را انتخاب می‌کند، سپس مجموعه ای جدید می‌سازد که تمام عناصر به استثنای چهار عنصر اول را در خود جای می‌دهد.


٢-٣-٤-ایجاد مجموعه بر اساس روابط
jQuery به ما این توانایی را داده است تا مجموعه هایی را انتخاب کنیم، که اساس انتخاب عناصر، رابطه سلسله مراتبی آنها با عناصر HTML صفحه باشد. اکثر این متدها یک پارامتر اختیاری از نوع انتخاب کننده دریافت می‌کنند که می‌تواند برای انتخاب عناصر مجموعه استفاده شود. در صورتی که چنین پارامتری ارسال نگردد، تمام عناصر واجد شرایط متد در مجموعه انتخاب می‌شوند.


جدول ٢-٤-متدهای موجود برای ایجاد مجموعه‌های جدید بر اساس روابط
 توضیح متد
 مجموعه ای را برمی گرداند که شامل تمام فرزندان بدون تکرار از عناصر مجموعه می‌باشد.
() children
 مجموعه ای شامل محتویات تمام عناصر برمی گرداند. (از این متد معمولا برای عناصر iframe استفاده می‌شود)
() contents
 مجموعه ای شامل فرزندان پدرش که بعد از خود این عنصر می‌باشند را برمی گرداند. این مجموعه عنصر تکراری ندارد.
() next
 مجموعه ای شامل تمام فرزندان پدرش که بعد از خود این عنصر می‌باشند را بر می‌گرداند.
() nextAll
 مجموعه ای شامل نزدیک‌ترین پدر اولین عنصر مجموعه را بر می‌گرداند.
() parent
 مجموعه ای شامل تمام پدران مستقیم عناصر مجموعه را بر می‌گرداند. این مجموعه عنصر تکراری ندارد.
() parents
 مجموعه ای شامل فرزندان پدرش که قبل از خود این عنصر می‌باشند را برمی گرداند. این مجموعه عنصر تکراری ندارد. () prev
  مجموعه ای شامل تمام فرزندان پدرش که قبل از خود این عنصر می‌باشند را بر می‌گرداند. () prevAll
 مجموعه ای بدون عنصر تکراری را بر می‌گرداند که شامل تمام فرزندان پدر خود عنصر خواهد بود.
() siblings
تمامی جدول بالا غیر از متد ()contents پارامتری از نوع رشته که انتخاب کننده برای متد می‌باشند، استفاده می‌کند.

٢-٣-٥-استفاده از مجموعه‌های انتخاب شده برای انتخاب عناصر
با وجود اینکه تاکنون با شمار زیادی از توانایی‌های انتخاب و انتخاب کننده‌ها در jQuery آشنا شده اید، هنوز چند مورد دیگر نیز برای افزایش قدرت انتخاب باقی مانده است.
متد ()find بروی یک مجموعه عناصر انتخاب شده به کار گرفته می‌شود و یک پارامتر ورودی نیز دارد. این پارامتر که یک انتخاب کننده است تنها بروی فرزندان این مجموعه اعمال می‌شود. برای مثال فرض کنید یک مجموعه از عناصر انتخاب و در متغیر wrapperSet قرار گرفته است. با دستور زیر می‌توانیم تمام عناصر (تگ) cite را که درون یک تگ p قرار گرفته اند را انتخاب کنیم، به شرطی که آن‌ها فرزندان عناصر مجموعه wrapperSet باشند:
wrappedSet.find('p cite')
البته می‌توانیم این تکه کد را به صورت زیر هم بنویسیم:
$('p cite', wrapperSet)
مانند سایر متدهای معرفی شده قدرت اصلی این متد نیز هنگام استفاده در متدهای زنجیره ای مشخص می‌شود.
شکل کلی متد ()findمانند زیر است:
(find(selector
یک مجموعه عنصر جدید ایجاد می‌کند که شامل فرزندان عناصر مجموعه قبل می‌شود.
پارامتر
یک انتخاب کننده است که در قالب یک رشته به این متد ارسال می‌شود.
خروجی
یک مجموعه عنصر جدید
جهت پیدا کردن عناصری که داخل یک wrapperSet می‌توانیم از متد دیگری به نام ()contains نیز استفاده کنیم. این متد مجموعه ای را بر می‌گرداند که شامل تمام عناصری است که در انتخاب کننده پارامتر ورودی است. مثلا
$('p').contains('Lorem ipsum')
این دستور تمامی عناصر p را که شامل Lorem ipsum است را بر می‌گرداند. قالب کلی متد مانند زیر است:
(contains(text
مجموعه ای از عناصر که شامل متن ورودی می‌باشند را بر می‌گرداند.
پارامتر
رشته ورودی که می‌خواهیم در عنصر فراخوان متد جستجو شود.
خروجی
مجموعه ای از عناصر از نوع فراخوان متد را بر می‌گرداند که شامل متن ورودی باشد.
آخرین متدی که به بررسی آن می‌پردازیم متد ()is می‌باشد. با استفاده از این متد می‌توانیم اطمینان حاصل کنیم که دست کم یک عنصر از مجموعه عناصر، شرایط مشخص شده توسط ما را دارا باشد. یک انتخاب کننده به این متد ارسال می‌شود، اگر عنصری از مجموعه عناصر انتخاب شد، خروجی متد true می‌شود و در غیر این صورت مقدار false بر گردانده خواهد شد. برای مثال:
var hasImage = $('*').is('img');
در صورت وجود دست کم یک عنصر عکس در کل عناصر صفحه، دستور بالا مقدار متغیر hasImage را برابر true قرار می‌دهد.
قالب کلی متد ()is مانند زیر است:
(is(selector
بررسی می‌کند که آیا عنصری در مجموعه وجود دارد که انتخاب کننده ارسالی آن را انتخاب کند؟
پارامتر
یک انتخاب کننده است که در قالب یک رشته به این متد ارسال می‌شود.
خروجی
مقدار true در صورت وجود دست کم یک عنصر و false در صورت عدم وجود توسط تابع برگردانده می‌شود.

٢-٣-٦-مدیریت زنجیره‌های jQuery
تاکنون در مورد استفاده از متدها و توابع زنجیره ای زیاد بحث کرده ایم و انجام چندین عمل در یک دستور را به عنوان یک قابلیت بزرگ معرفی کرده ایم و البته از آن هم استفاده کردیم و در ادامه نیز استفاده خواهیم کرد. به کار گیری متدها به صورت زنجیره ای نه تنها موجب نوشتن کدهای قدرتمند و قوی به صورت مختصر و خلاصه می‌شود، بلکه از لحاظ کارایی نیز نکته مثبتی محسوب می‌شود، زیرا برای اعمال هر متد نیازی به محاسبه و انتخاب مجدد مجموعه نخواهد بود.
بنابراین متدهای مختلفی که در زنجیره استفاده می‌کنیم، برخی از آنها ممکن است مجموعه‌های جدیدی تولید کنند. برای مثال استفاده از متد ()clone موجب می‌شود تا مجموعه ای جدید از کپی عناصر در مجموعه اول ایجاد شود. زمانی که یکی از متدهای زنجیره یک مجموعه جدید را تولید می‌کند، دیگر راهی برای استفاده از مجموعه پیشین در زنجیره نخواهیم داشت و این نکته زنجیره ما را به خطر می‌اندازد. عبارت زیر را در نظر بگیرید:
$('img').clone().appendTo('#somewhere');
این مثال دو مجموعه ایجاد می‌کندو نخست مجموعه ای شامل تمام عناصر عکس صفحه ایجاد می‌شود و مجموعه دوم کپی مجموعه اول است که به انتهای عنصری با شناسه somewhere اضافه می‌شود. حال اگر بخواهیم پس از اعمال کپی بروی مجموعه اصلی عملی مانند افزودن یک کلاس را بروی آن انجام دهیم چه باید بکنیم؟ همچنین نمی‌توانیم مجموعه اصلی را به انتهای زنجیره انتقال دهیم، چون بروی قسمتی دیگر اثر خواهد گذاشت.
برای مرتفع کردن چنین نیازی، jQuery متد ()end را معرفی کرده است. زمانی از این متد استفاده می‌شود،  یک نسخه پشتیبان از مجموعه کنونی ایجاد می‌شود . همان مجموعه برگردانده می‌شود. بنابراین اگر متدی پس از آن ظاهر شودف اثرش بروی مجموعه اولیه خواهد بود. مثال زیر را در نظر بگیرید:
$('img').clone().appendTo('#somewhere').end().addClass('beenCloned');
این مثال دو مجموعه ایجاد می‌کندو نخست مجموعه ای شامل تمام عناصر عکس صفحه ایجاد می‌شود و مجموعه دوم کپی مجموعه اول است که به انتهای عنصری با شناسه somewhere اضافه می‌شود. اما با استفاده از متد ()end  همان مجموعه اولیه در ادامه زنجیره قرار خواهد گرفت و سپس متد ()addClass بروی تمامی عناصر عکس اعمال می‌شود، نه تنها عکس‌های موجود در مجموعه اول، اگر از متد ()end  استفاده نشود متد ()addClass برویعناصر مجموعه دوم اعمال خواهد شد.
قالب کلی متد ()end به شکل زیر است:
()end
در متدهای زنجیره ای استفاده می‌شود و از مجموعه کنونی یک پشتیبان می‌گیرد تا همان مجموعه در زنجیره جریان داشته باشد.
پارامتر
ندارد
خروجی
مجموعه عنصر قبلی
شاید در نظر گرفتن مجموعه‌ها در متدهای زنجیره ای به شکل یک پشته به درک بهتر از متد ()end  کمک کند. هر زمان که یک مجموعه جدید در زنجیره ایجاد می‌شود، آن مجموعه به بالای پشته افزوده می‌شود، اما با فراخوانی متد ()end، بالاترین مجموعه از این پشته برداشته می‌شود و مجدادا مجموعه پیشین در زنجیره قرار می‌گیرد.
متد دیگری که توانایی ایجاد تغییر در این پشته خیالی را دارد، متد ()andSelf می‌باشد. این متد دو مجموعه بالای پشته را با یکدیگر ادغام می‌کند و آن‌ها را به یک مجموعه تبدیل می‌کند.
شکل کلی متد ()andSelf به صورت زیر است:
()andSelf
دو مجموعه پیشین در یک زنجیره را با یکدیگر ادغام می‌کند.
پارامتر
ندارد
خروجی
مجموعه عنصری ادغام شده
در مباحث بعدی کار با صفت‌ها و ویژگی‌های عناصر بحث خواهد شد.

موفق و موید باشید
مطالب
Blazor 5x - قسمت 34 - توزیع برنامه‌های Blazor بر روی IIS
زمانیکه صحبت از توزیع برنامه‌های Blazor بر روی IIS است، عموما تنظیمات مرتبط با برنامه‌های Blazor Server و یا Hosted Blazor Apps که همان ترکیب WASM+Web API هستند، مطرح است؛ در غیراینصورت اگر برنامه‌ای صرفا از فایل‌های Blazor WASM تشکیل شده باشد، توزیع آن حتی بر روی صفحات static مربوط به GitHub هم میسر است و وابستگی خاصی به سروری ندارند. بنابراین در اینجا بیشتر هدف تنظیمات IIS مرتبط با قسمت ASP.NET Core این برنامه‌ها است و این مورد را پیشتر در مطلب «ارتقاء به ASP.NET Core 1.0 - قسمت 22 - توزیع برنامه توسط IIS» بررسی کرده‌ایم و نکته‌ی اضافه‌تری را به همراه ندارد.


مروری بر نحوه‌ی توزیع برنامه‌های Blazor بر روی IIS

1- پیش از هر کاری باید مطابق نگارش ASP.NET Core در حال استفاده (که به عنوان هاست Blazor Server و یا ارائه دهنده‌ی قسمت Web API برنامه‌ی سمت کلاینت WASM مطرح است)، بسته‌ی NET Core hosting bundle. را نصب کرد که عموما تحت عنوان «Hosting Bundle Installer» قابل دریافت است.
نکته‌ی مهم: همانند تمام نگارش‌های دات نت، در اینجا نیز باید Hosting Bundle را پس از نصب IIS، بر روی سیستم نصب کرد. اگر این ترتیب تغییر کند، یکبار دیگر نصاب آن‌را اجرا کرده و گزینه‌ی ترمیم نصب را انتخاب کنید تا یکپارچگی آن با IIS صورت گیرد.

2- نیاز است برنامه‌ی خود را اصطلاحا publish کرد تا به همراه فایل‌های نهایی قابل کپی باشد که در پوشه‌ای توسط IIS هاست خواهند شد. برای اینکار اگر از نگارش کامل ویژوال استودیو استفاده می‌کنید، فقط کافی است بر روی پروژه‌ی مدنظر کلیک راست کرده و از منوی باز شده، گزینه‌ی publish را انتخاب کنید و مراحل آن‌را طی نمائید و یا این مراحل را می‌توان توسط دستور خط فرمان زیر نیز خلاصه کرد که وابستگی خاصی، به IDE ویژه‌ای ندارد و چند سکویی است:
dotnet publish -o "c:\dir1\dir2" -c Release
این دستور، کار Build و توزیع پروژه را در پوشه‌ای که مشخص شده انجام می‌دهد. همچنین برای حالت build، نوع release را انتخاب می‌کند که به همراه بهینه سازی‌های بسیاری به همراه کاهش حجم نهایی فایل‌ها نیز هست.
و یا اگر فقط دستور dotnet publish -c Release را در ریشه‌ی پروژه اجرا کنیم، خروجی نهایی را در پوشه‌ی bin\Release\net5.0\publish می‌توان مشاهده کرد که به همراه یک web.config مخصوص برنامه‌های blazor هم هست و در آن mime typeهای متناظری، به همراه URL rewriting مناسب برنامه‌های تک صفحه‌ای وب از پیش تنظیم شده‌است. بنابراین در اینجا نصب ماژول URL rewrite بر روی IIS نیز الزامی است.

3- در اینجا نیز همانند تنظیمات برنامه‌های ASP.NET Core، باید application pool منتسب به برنامه را ویرایش کرده و NET Clr Version. آن‌را بر روی No Managed Code قرار داد.


روش فعالسازی توزیع مبتنی بر فشرده سازی Brotli در IIS

در حین عملیات publish استاندارد، به صورت پیش‌فرض از تمام فایل‌ها، سه نسخه‌ی اصلی، gz شده (gzip) و یا br شده (فشرده سازی Brotli که فایل‌های کم حجم‌تری را نسبت به gz ارائه می‌دهد) نیز تهیه می‌شوند که بسته به نوع مرورگر و پشتیبانی آن از روش‌های مختلف فشرده سازی، یکی از آن‌ها در اختیار کلاینت قرار خواهد گرفت که به این صورت کاربران، تجربه‌ی دریافت کم حجم‌تر و سریعتری را خواهند داشت.


باید دقت داشت Web.config ای که به همراه دستور dotnet publish ایجاد می‌شود، روش توزیع پیش‌فرض فایل‌های br. تولیدی را ندارد. برای اینکار نیاز است تنظیمات این فایل web.config توصیه شده‌ی توسط تیم Blazor را به web.config خود اضافه کرد تا در نهایت حجم دریافتی از سرور به شدت کاهش یابد.

یک نکته: اگر می‌خواهید فایل web.config سفارشی خودتان را داشته باشید، نمونه‌ای از آن‌را در ریشه‌ی پروژه قرار داده و سپس فایل csproj را به نحو زیر ویرایش کنید تا از آن در حین publish استفاده کند:
<PropertyGroup>
    <PublishIISAssets>true</PublishIISAssets>
</PropertyGroup>


در حین publish برنامه‌های Blazor WASM کار IL trimming نیز انجام می‌شود

برای کاهش حجم نهایی برنامه‌های Blazor WASM، در حین publish در حالت release، کار IL Trimming نیز به صورت خودکار انجام می‌شود تا کدهای IL ای که در برنامه نقش نداشته‌اند و مستقیما در جائی استفاده نشده‌اند، به صورت خودکار حذف شوند و به این ترتیب حجم ارائه‌ی نهایی به شدت کاهش یابد.
فقط باید دقت داشت که در این حالت اگر عملیات پویایی مانند reflection در کدهای شما صورت می‌گیرد، به علت نداشتن ارجاع استاتیکی به منابع مورد استفاده، در زمان اجرا با مشکل مواجه خواهد شد. اگر می‌خواهید اخطارهایی را در این زمینه مشاهده کنید، گزینه‌ی زیر را به فایل csproj اضافه نمائید:
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>


حذف مباحث بومی سازی در صورت عدم نیاز


اگر در برنامه‌ی خود از مباحث time-zones استفاده نمی‌کنید، می‌توانید با غیرفعال کردن آن در فایل csproj، حداقل 100 کیلوبایت از حجم برنامه‌ی نهایی را کاهش دهید:
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
و یا اگر نمی‌خواهید خروجی‌های تاریخ و یا مقادیر، بر اساس فرهنگ بومی کاربر تطابق پیدا کنند، می‌توانید invariant culture را فعال کنید:
<InvariantGlobalization>true</InvariantGlobalization>
مطالب
شروع کار با Dart - قسمت 1

Dart کتابخانه ای است که توسط شرکت گوگل ارائه شده است و گفته می‌شود، قرار است جایگزین جاوا اسکریپت گردد و از آدرس https://www.dartlang.org قابل دسترسی می‌باشد. این کتابخانه، دارای انعطاف پذیری فوق العاده بالایی است و کد نویسی Java Script را راحت‌تر می‌کند. در حال حاضر هیچ مرورگری به غیر از Chromium از این تکنولوژی پشتیبانی نمی‌کند و جهت تسهیل در کدنویسی، باید از ویرایشگر Dart Editor استفاده کنید. این ویرایشگر کدهای نوشته شده را به دو صورت Native و JavaScript Compiled در اختیار مرورگر قرار می‌دهد. در ادامه با نحوه‌ی کار و راه اندازی Dart آشنا خواهید شد.

ابتدا Dart و ویرایشگر مربوط به آن را توسط لینک‌های زیر دانلود کنید:

دانلود نسخه 64 بیتی دارت + ویرایشگر

دانلود نسخه 32 بیتی دارت + ویرایشگر

بعد از اینکه فایلهای فوق را از حالت فشرده خارج کردید، پوشه ای با نام dart ایجاد می‌نماید. وارد پوشه dart شده و DartEditor را اجرا کنید.

توجه: جهت اجرای dart به JDK 6.0 یا بالاتر نیاز دارید

در مرحله بعد نمونه کدهای Dart را از لینک زیر دانلود نمایید و از حالت فشرده خارج کنید. پوشه ای با نام one-hour-codelab ایجاد می‌گردد.

دانلود نمونه کدهای دارت

از منوی File > Open Existing Folder… پوشه one-hour-codelab را باز کنید .

توضیحات

- پوشه packages و همچنین فایلهای pubspec.yaml و pubspec.lock شامل پیش نیازها و Package هایی هستند که جهت اجرای برنامه‌های تحت Dart مورد نیاز هستند. Dart Editor این نیازمندی‌ها را به صورت خودکار نصب و تنظیم می‌کند.

توجه: اگر پوشه Packages را مشاهده نکردید و یا در سمت چپ فایلها علامت X قرمز رنگ وجود داشت، بدین معنی است که package ‌ها به درستی نصب نشده اند. برای این منظور بر روی pubspec.yaml کلیک راست نموده و گزینه Get Pub را انتخاب کنید. توجه داشته باید که بدلیل تحریم ایران توسط گوگل باید از ابزارهای عبور از تحریم استفاده کنید.

- 6 پوشه را نیز در تصویر فوق مشاهده می‌کنید که نمونه کد piratebadge را بصورت مرحله به مرحله انجام داده و به پایان می‌رساند.

- Dart SDK شامل سورس کد مربوط به تمامی توابع، متغیرها و کلاس هایی است که توسط کیت توسعه نرم افزاری Dart ارائه شده است.

- Installed Packages شامل سورس کد مربوط به تمامی توابع، متغیرها و کلاس‌های کتابخانه‌های اضافه‌تری است که Application به آنها وابسته است.


گام اول: اجرای یک برنامه کوچک

در این مرحله سورس کدهای آماده را مشاهده می‌کنید و با ساختار کدهای Dart و HTML آشنا می‌شوید و برنامه کوچکی را اجرا می‌نمایید.

در Dart Editor پوشه 1-blankbadge را باز کنید و فایلهای piratebadge.html و piratebadge.dart را مشاهده نمایید.

کد موجود در فایل piratebadge.html

<html>
  <head>
    <meta charset="utf-8">
    <title>Pirate badge</title>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="piratebadge.css">
  </head>
  <body>
    <h1>Pirate badge</h1>
    
    <div>
      TO DO: Put the UI widgets here.
    </div>
    <div>
      <div>
        Arrr! Me name is
      </div>
      <div>
        <span id="badgeName"> </span>
      </div>
    </div>

    <script type="application/dart" src="piratebadge.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

توضیحات

- در کد HTML ، اولین تگ <script> ، فایل piratebadge.dart را جهت پیاده سازی دستورات dart به صفحه ضمیمه می‌نماید

- Dart Virtual Machine (Dart VM) کدهای Dart را بصورت Native یا بومی ماشین اجرا می‌کند. Dart VM کدهای خود را در Dartium که یک ویرایش ویژه از مرورگر Chromium می‌باشد اجرا می‌کند که می‌تواند برنامه‌های تحت Dart را بصورت Native اجرا کند.

- فایل packages/browser/dart.js پشتیبانی مرورگر از کد Native دارت را بررسی می‌کند و در صورت پشتیبانی، Dart VM را راه اندازی می‌کند و در غیر این صورت JavaScript کامپایل شده را بارگزاری می‌نماید.


کد موجود در piratebadge.dart

void main() {
  // Your app starts here.
}

- این فایل شامل تابع main می‌باشد که تنها نقطه ورود به application است. تگ <script> موجود در piratebadge.html برنامه را با فراخوانی این تابع راه اندازی می‌کند.

- تابع main() یک تابع سطح بالا یا top-level می‌باشد.

- متغیرها و توابع top-level عناصری هستند که خارج از ساختار تعریف کلاس ایجاد می‌شوند.

جهت اجرای برنامه در Dart Editor بر روی piratebadge.html کلیک راست نمایید و گزینه Run in Dartium را اجرا کنید. این فایل توسط Dartium اجرا می‌شود و تابع main() را فراخوانی می‌کند و صفحه ای همانند شکل زیر را نمایش می‌دهد.


گام دوم: افزودن فیلد input

توجه داشته باشید که در این مرحله یا می‌توانید تغییرات مورد نظر خود را در طی آموزش بر روی پوشه‌ی 1-blankbadge اعمال کنید و یا به پوشه‌های تهیه شده در نمونه کد موجود در همین پروژه مراجعه نمایید.

در این مرحله یک تگ <input> به تگ <div class=”widgets”> اضافه کنید.

...
<div>
  <div>
    <input type="text" id="inputName" maxlength="15">
  </div>
</div>
...

سپس کتابخانه dart:html را به ابتدای فایل piratebadge.dart اضافه کنید.

import 'dart:html';

توضیحات

- دستور فوق کلاس‌ها و Resource ‌های موجود در کتابخانه dart:html را اضافه می‌کند.

- از حجیم شدن کدهای خود نگران نباشید، زیرا فرایند کامپایل کدهای اضافی را حذف خواهد کرد.

- کتابخانه dart:html شامل کلاسهایی جهت کار با عناصر DOM و توابعی جهت دسترسی به این عناصر می‌باشد.

- در مباحث بعدی یاد می‌گیرید که با استفاده از کلمه کلیدی show فقط کلاسهایی را import کنید که به آن نیاز دارید.

- اگر کتابخانه ای در هیچ بخش کد استفاده نشود، خود Dart Editor به صورت warning اخطار می‌دهد و می‌توانید آن را حذف کنید.


دستور زیر را در تابع main بنویسید تا رویداد مربوط به ورود اطلاعات  در فیلد input را مدیریت نمایید.

void main() {
  querySelector('#inputName').onInput.listen(updateBadge);
}

توضیحات

- تابع querySelector() در کتابخانه dart:html تعریف شده است و یک المنت DOM را جستجو می‌نماید. پارامتر ورودی آن یک selector می‌باشد که در اینجا فیلد input را توسط #inputName جستجو نمودیم که یک ID Selector می‌باشد.

- نوع خروجی این متد یک شی از نوع DOM می‌باشد.

- تابع onInput.Listen() رویدادی را برای پاسخگویی به ورود اطلاعات در فیلد input تعریف می‌کند. زمانی که کاربر اطلاعاتی را وارد نماید، تابع updateBadge فراخوانی می‌گردد.

- رویداد input زمانی رخ می‌دهد که کاربر کلیدی را از صفحه کلید فشار دهد.

- رشته‌ها همانند جاوا اسکریپت می‌توانند در " یا '  قرار بگیرند.


تابع زیر را به صورت top-level یعنی خارج از تابع main تعریف کنید.

...

void updateBadge(Event e) { 
  querySelector('#badgeName').text = e.target.value;
}

توضیحات

- این تابع محتوای المنت badgeName را به محتوای وارد شده در فیلد input تغییر می‌دهد.

- پارامتر ورودی این تابع شی e از نوع Event می‌باشد و به همین دلیل می‌توانیم این تابع را یک Event Handler بنامیم.

- e.target به شی ای اشاره می‌کند که موجب رخداد رویداد شده است و در اینجا همان فیلد input می‌باشد

- با نوشتن کد فوق یک warning را مشاهده می‌کنید که بیان می‌کند ممکن است خصوصیت value برای e.target وجود نداشته باشد. برای حل این مسئله کد را بصورت زیر تغییر دهید.

...

void updateBadge(Event e) { 
  querySelector('#badgeName').text = (e.target as InputElement).value;
}

توضیحات

- کلمه کلیدی as به منظور تبدیل نوع استفاده می‌شود که e.target را به یک InputElement تبدیل می‌کند.

همانند گام اول برنامه را اجرا کنید و نتیجه را مشاهده نمایید. با تایپ کردن در فیلد input به صورت همزمان در کادر قرمز رنگ نیز نتیجه تایپ را مشاهده می‌نمایید. 

مطالب
چگونه نرم افزارهای تحت وب سریعتری داشته باشیم؟ قسمت سوم
قسمت دوم 

8.ORM Lazy Load
در هنگام استفاده از ORM‌ها دقت کنید کجا از Lazy Load استفاده می‌کنید. Lazy Load باعث می‌شود وقتی شما اطلاعات مرتبط را از بانک اطلاعات واکشی می‌کنید، این واکشی اطلاعات در چند query از بانک انجام شود. درعوض عدم استفاده از Lazy Load باعث می‌شود تمامی اطلاعات مورد نیاز شما در یک query از بانک اطلاعاتی دریافت شود. این موضوع یعنی سربار کمتر در شبکه، در بانک اطلاعاتی، در منابع حافظه و منابع پر ازرش cpu در سرورها. البته استفاده از include در حالت فعال بودن یا نبودن lazy هم داستان مجزایی دارد که اگر عمری باقی باشد راجع به آن مقاله ای خواهم نوشت.
 به این نمونه دقت کنید:
List<Customer> customers = context.Customers.ToList();
foreach (Customer cust in context.Customers){
   Console.WriteLine("Customer {0}, Account {1}", cust.Person.LastName.Trim() + ", " + cust.Person.FirstName, cust.AccountNumber); 
}
همچین کدی (در صورت فعال بودن Lazy Load در ORM) در صورتی که جدول Customers دارای 1000 رکورد باشد، باعث می‌شود برنامه 1001 دستور sql تولید و در بانک اجرا گردد.
برای اطلاع بیشتر می‌توانید به این مقاله مراجعه نمایید.

9.استفاده از MiniProfiler
سعی کنید از MiniProfiler در تمامی پروژه‌ها استفاده کنید. البته وقتی نرم افزار را در اختیار مصرف کننده قرار می‌دهید، آن را غیر فعال کنید. می‌توانید از متغیرهای compiler برای مجزا کردن build‌های متفاوت در برنامه خود استفاده کنید:
#if DEBUG then
// فعال سازی MiniProfiler
#endif
ایده دیگری هم وجود دارد. شما می‌توانید MiniProfiler را برای کاربر Admin یا کاربر Debugger فعال و برای بقیه غیر فعال کنید. در باب MiniProfiler مسائل زیادی وجود دارد که چند نمونه از آن در همین سایت در این مقاله و این مقاله در دسترس است. البته می‌توانید از ابزارهای دیگری مانند Glimpse که در این زمینه وجود دارد نیز استفاده کنید. لب کلام این نکته استفاده از profiler برای نرم افزار خود می‌باشد.

10. Data Paging در بانک اطلاعاتی
هنگامیکه از کامپوننت‌های شرکت‌های دیگر (Third party) استفاده می‌کنید، اطمینان حاصل کنید که صفحه بندی اطلاعات در بانک اطلاعاتی انجام می‌شود. برای نمونه کاپوننت گرید شرکت Telerik چند نوع صفحه بندی را پشتیبانی می‌کند. صفحه بندی سمت کاربر (توسط JavaScript)، صفحه بندی سمت سرور توسط کامپوننت و صفحه بندی مجازی. صفحه بندی سمت کاربر یعنی تمامی اطلاعات از سرور به کاربر فرستاده شده و در سمت کاربر عمل صفحه بندی انجام می‌شود. این یعنی واکشی تمامی اطلاعات از بانک و در مورد نرم افزارهای پرکاربر با حجم اطلاعات زیاد یعنی فاجعه. صفحه بندی سمت سرور ASP.NET هم یعنی واکشی اطلاعات از سرور بانک به سرور برنامه و سپس صفحه بندی توسط برنامه. این موضوع هم ممکن است مشکلات زیادی را ایجاد نماید چون باید حداقل تمامی رکوردها از اولین رکورد تا آخرین رکورد صفحه جاری از بانک واکشی شود که این عمل علاوه بر ایجاد سربار شبکه، سربار IO در بانک اطلاعاتی و سربار cpu در سرور ASP.NET ایجاد می‌کند. استفاده از صفحه بندی مجازی، شما را قادر می‌کند بتوانیم اطلاعات را در بانک صفحه بندی کرده و فقط صفحه مورد نظر خود را از بانک واکشی کنیم.
این حالت مجازی در اکثر component‌ها که توسط شرکت‌های مختلف ایجاد شده وجود دارد ولی ممکن است نام‌های متفاوتی داشته باشد. برای این موضوع باید به راهنمای component خریداری شده مراجعه کنید و یا به فروم‌ها و... مراجعه نمایید.

11. بررسی تعداد کوئری‌های صادر شده در یک صفحه و تعداد رکوردهای بازگشت داده شده توسط آن‌ها
این به این معنا نیست که برای هر query یک context مجزا ایجاد کنید، منظور این است که به بهانه اینکه اطلاعات مختلفی از جداول مختلف مورد نیاز است، query خود را آن قدر پیچیده یا گسترده ننویسیم که یا process آن در بانک زمان و سربار زیادی ایجاد کند و یا حجم اطلاعات بلا استفاده ای را از بانک به سرور برنامه لود نماید. به جای این موضوع می‌توانید در یک یا چند context دستورات مجزای واکشی اطلاعات صادر کنید تا تنها اطلاعات مورد نیاز خود را واکشی نمایید. البته این موضوع باعث نشود که تعداد query‌ها مثلا به 1000 عدد برسد! یعنی باید فیمابین query‌های پیچیده و query‌های ساده ولی با تعداد یکی را که مناسبتر با پروژه است انتخاب کنید که این موضوع با تجربه و تست حاصل می‌شود.
نظرات مطالب
نکات استفاده از افزونه‌ی Web Essentials جهت پردازش LESS
در قسمت روش‌های استفاده از less جای کامپایل با دستور زیر در CMD :
lessc style.less > style.css
و کامپایل توسط جاوا اسکریپت که به نظر من بهترین راه برای مشاهده تغییرات جزیی در فایل less پروژه قبل از کامپایل نهایی است خالی مانده .
برای کامپایل با جاوا اسکریپت :
        <link rel="stylesheet/less" type="text/css" href="content/style.less" />
        <script src="Script/less.min.js"></script>

در خط اول مقدار خاصیت href برابر آدرس فایل less و src خط دوم شامل آدرس فایل کامپایلر جاوا اسکریپت بهینه شده است .
لینک دانلود کامپایلر جاوا اسکریپت: less.min.js  
مطالب
4# آموزش سیستم مدیریت کد Git : نصب و پیکر‌‏بندی
برای نصب Git ابتدا به msysgit رفته و مطابق شکل زیر بر روی گزینه دانلود کلیک کنید. سپس در صفحه باز شده آخرین نسخه Git را دانلود نموده و فایل مربوطه را اجرا کنید:

شروع نصب:

--------------  

در این مرحله بخش Windows Explorer Integration اهمیت دارد. در صورت انتخاب این بخش، بعد از نصب، Git Bash و Git GUI به منوی راست کلیک شما اضافه می‏‌شود. به این ترتیب با سرعت بیشتری می‏توانید به Git در یک  پوشه خاص دسترسی داشته باشید.

--------------
در این مرحله از شما خواسته می‏‌شود تعیین کنید که آیا فقط می‏‌خواهید از طریق Git Bash با Git کار کنید یا با اضافه کردن فایل اجرایی Git به متغیر‏های محلی ویندوز از طریق Command Prompt  ویندوز نیز می‏خواهید به Git دسترسی داشته باشید. گزینه سوم هم Git و هم برخی از ابزار‏های یونیکسی را به متغیر‏های محلی اضافه می‏‌کند که سبب می‏‌شود شما یک خط فرمان قدرتمند‏تر در ویندوز داشته باشید. اما این کار ممکن است در برخی از برنامه‏‌های پیش فرض اختلال ایجاد کند بنابراین در انتخاب این گزینه احتیاط کنید.

--------------
در این مرحله کاراکتری را که نشان دهنده انتهای خط است تعیین می‏‌کنید. این کاراکتر در ویندوز و یونیکس متفاوت است. بنابراین Git از شما می‏‌خواهد که برای حفظ سازگاری در محیط‏ هایی که چند سیستمی هستند، آن‏را تعیین کنید.
گزینه اول به صورت فرمت یونیکس ذخیره و به شکل ویندوز بازیابی می‏‌شود (مناسب برای محیط ویندوز).
گزینه دوم ذخیره به فرمت یونیکسی است و مناسب محیط‌های یونیکس است.
و آخرین گزینه فایل را بدون تغییر ذخیره و بازیابی می‏کند (از این گزینه نیز می‏توان هم برای Unix و هم windows استفاده کرد).
بعد از این مرحله نصب آغاز می‏شود.


نکته: شما می‏‌توانید جهت دسترسی به یک محیط گرافیکی قوی از gitextensions   استفاده کنید. با دانلود این فایل، هم خود Git و هم GUI ‏هایی برای کار‏های مختلف، نظیر مشاهده تفاوت‏های دو فایل یا نمایش گرافیکی شاخه‏‌ها به سیستم شما اضافه می‏‌شود.

پیکربندی Git:
برای پیکربندی Git شما باید یک فایل config ایجاد کنید و با استفاده از دستوراتی که در ادامه می‏‌آید این تنظیمات را انجام دهید. البته پیکربندی Git از طریق ابزار‏های گرافیکی که در محله قبل نصب کردید نیز امکان‏پذیر است.
Git دارای سه نوع دسترسی برای پیکره‌بندی است:
سیستمی: این تنظیمات بر روی کل سیستمی که git برای روی آن نصب شده اعمال می‏‌شود. فایل  gitconfig در مسیر program files/Git/etc/gitconfig قرار دارد و برای تغییر آن باید از سوئیچ system-- استفاده نمود.
در سطح کاربر: فایل  config.در مسیر [users/[username/ برای این منظور است و تغییر این تنظیمات تنها بر روی همین کاربر اعمال می‏شود برای درسترسی به این فایل باید از سوئیچ global-- استفاده کرد.
در سطح Repository: برای هر پوشه repository  این فایل موجود است و اگر از دستور config بدون هیچ سوئیچی استفاده کنیم تغییرات بر روی این فایل اعمال می‏شود.

نکته: معمولا فایل پیکربندی git در سطح سیستم را تغییر نمی‏‌دهند.

دستورات پیکربندی:
همان‏طور که گقته شد هر Commit حاوی اطلاعات فردی است که آن‏را انجام داده است. این اطلاعات را می‏‌توان به صورت زیر تنظیم کرد:
نام کاربر:
git config --global user.name "Hessam"
ایمیل کاربر:
git config --global user.email "hessam@localhost.com"
با استفاده از دستور زیر می‏‌توان تنظیماتی را که تا کنون انجام شده ببینیم:
git config --global --list
همچنین می‏‌توان ویرایشگر متن پیش فرضی برای git تعیین کرد. از این ویرایشگر می‏‌توان به عنوان مثال بعد از فرخوانی دستور commit استفاده نمود تا دلیل commit مشخص شود. در صورت تعیین این ویرایشگر، git  آن‏را خودکار باز می‏کند:
git config --global core.editor notepad
من در اینجا notepad را انتخاب کردم توجه کنید که مسیر ویرایشگر باید در متغیر‌های محلی ویندوز باشد.
و در نهایت جهت نمایش بهتر پیام‏های git می‏توانیم تنظیم کنیم که آن‏ها را با رنگ‏های متفاوتی نمایش دهد:
git config --global color.ui auto
 البته تنظیمات بیشتری را می‏‌توان در اینجا انجام داد، مانند تعیین برنامه پیش فرض برای نمایش اختلاف فایل‏ها و یا برنامه پیش فرض برای حل کردن مشکل conflict و غیره که این تنظیمات در همان بخش‏‌ها گفته خواهد شد.
در قسمت بعد دستورات اولیه کار با git به صورت محلی گفته خواهد شد.
نظرات مطالب
Gulp #2
تشکر بابت این مقاله. فقط یک نکته رو بیان کنم که فرمان touch  برای پلتفرم ویندوز نیست . اگر دستور :

touch gulpfile.js

رو صادر کنیم با خطای زیر رو به رو میشیم :
'touch' is not recognized as an internal or external command, operable program or batch file.
برای ایجاد فایل خالی در ویندوز باید اینکارو بکنیم :

echo $null >> gulpfile.js
این دستور همانند دستور touch هستش. با این دستور فایل gulpfile.js در مسیر پروژه ساخته میشه.
مطالب دوره‌ها
تزریق خودکار وابستگی‌ها در برنامه‌های ASP.NET MVC
هدف از این قسمت، ارائه راه حلی برای حالت تزریق وابستگی‌ها در سازنده‌های کنترلرهای ASP.NET MVC به صورت خودکار است.
به صورت پیش فرض، ASP.NET MVC به کنترلرهایی نیاز دارد که سازنده آن‌ها فاقد پارامتر باشند. از این جهت که بتواند به صورت خودکار آن‌ها را وهله سازی کرده و مورد استفاده قرار دهد. بنابراین به نظر می‌رسد که در اینجا نیز به همان روش معروف استفاده از الگوی Service locator و تکرار مدام کدهایی مانند ObjectFactory.GetInstance در سراسر برنامه خواهیم رسید که آنچنان مطلوب نیست.
اما ... در ASP.NET MVC می‌توان وهله ساز پیش فرض کنترلر‌ها را با پیاده سازی کلاس DefaultControllerFactory به طور کامل تعویض کرد. یعنی اگر در اینجا بجای وهله ساز پیش فرض، از وهله سازی انجام شده توسط IoC Container خود بتوانیم استفاده کنیم، آنگاه کار تزریق وابستگی‌ها در سازنده‌های کنترلرها نیز خودکار خواهد گردید.
    public class StructureMapControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                throw new InvalidOperationException(string.Format("Page not found: {0}", requestContext.HttpContext.Request.Url.AbsoluteUri.ToString(CultureInfo.InvariantCulture)));
            return ObjectFactory.GetInstance(controllerType) as Controller;
        }
    }
در کدهای فوق نمونه‌ای از این پیاده سازی را با استفاده از امکانات StructureMap ملاحظه می‌کنید. به این ترتیب در زمان وهله سازی خودکار یک کنترلر، اینبار StructureMap وارد عمل شده و وابستگی‌های برنامه را مطابق تعاریف ObjectFactory.Initialize ذکر شده، به سازنده کلاس کنترلر تزریق می‌کند.
برای استفاده از این ControllerFactory جدید تنها کافی است بنویسیم:
   protected void Application_Start()
  {
     //Set current Controller factory as StructureMapControllerFactory  
     ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
  }
و ... همین!
اکنون نوشتن یک چنین کنترلرهایی که سازند‌ه آن‌ها دارای پارامتر است، مجاز خواهد بود و تزریق وابستگی‌ها در سازنده‌ها به صورت خودکار توسط IoC Container مورد استفاده انجام می‌شود.
public partial class LoginController : Controller
{
    readonly IUsersService _usersService;
    public LoginController(IUsersService usersService)
    {
       _usersService = usersService;
    }
بدیهی است سایر مسایل مانند تنظیمات اولیه IoC Container، تهیه لایه سرویس و غیره مانند قبل است و تفاوتی نمی‌کند.


روش دوم تزریق خودکار وابستگی‌ها در برنامه‌های ASP.NET MVC

روش پیاده سازی و تعویض DefaultControllerFactory پیش فرض، متداول‌ترین روش خودکار سازی تزریق وابستگی‌ها در ASP.NET MVC است. روش دیگری نیز بر اساس پیاده سازی اینترفیس توکار IDependencyResolver معرفی شده در ASP.NET MVC 3.0 به بعد، وجود دارد. این روش علاوه بر ASP.NET MVC در کنترلرهای مخصوص Web API نیز کاربرد دارد. حتی SignalR نیز دارای کلاس پایه‌ای به نام DefaultDependencyResolver با امضای مشابه IDependencyResolver است.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;

namespace Prog
{
    public class StructureMapDependencyResolver : IDependencyResolver
    {
        public object GetService(Type serviceType)
        {
            if (serviceType.IsAbstract || serviceType.IsInterface || !serviceType.IsClass)
                return ObjectFactory.TryGetInstance(serviceType);
            return ObjectFactory.GetInstance(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return ObjectFactory.GetAllInstances(serviceType).Cast<object>();
        }
    }
}
یک نمونه از پیاده سازی آن‌را به کمک StructureMap در اینجا ملاحظه می‌کنید. برای ثبت آن در برنامه خواهیم داشت:
protected void Application_Start()
{
   DependencyResolver.SetResolver(new StructureMapDependencyResolver());
}
در Web API باید GlobalConfiguration.Configuration.DependencyResolver تنظیم شود. البته IDependencyResolver آن در فضای نام دیگری به نام System.Web.Http.Dependencies قرار گرفته است؛ اما کلیات آن تفاوتی نمی‌کند. نمونه‌ی نهایی و تکمیل شده‌ی آن‌را در اینجا می‌توانید مطالعه کنید: «تزریق خودکار وابستگی‌ها در ASP.NET Web API به همراه رها سازی خودکار منابع IDisposable »   

دریافت مثال کامل بحث جاری:
DI06.zip