اشتراک‌ها
خلاصه تجربیات یک نویسنده‌ی فنی پس از 8 سال

- شما عالم به مطلب خود هستید، بنابراین سطح آن‌را باید برای خواننده‌ی غیرمطلع تنظیم کنید.
- قبل از شروع کردن به کد نویسی و ارائه‌ی راه حلی، کمی توضیح دهید که چرا دارید اینکار را انجام می‌دهید. ابتدا باید نیازی را خلق کنید.
- اگر زمان مطالعه‌ی مطلب شما به بیش از 4 دقیقه برسد، شانس خوانده شدن آن زیر 40 درصد خواهد بود.
- ارائه تصاویر مرتبط با بحث را فراموش نکنید. یک تصویر بهتر است از هزاران کلمه.

خلاصه تجربیات یک نویسنده‌ی فنی پس از 8 سال
اشتراک‌ها
مشکلات زبان Go
  • Go is a language stuck in the 70’s.
  • Go ignores 40 years of programming language research.
  • Go is a language for blue collar (mediocre) developers.
  • Gophers are ok with working in Java 1.0. 
مشکلات زبان Go
مطالب
قراردادهای کوئری نویسی در OData و WCF Data Service - قسمت دوم
در مطلب قبلی قراردادهای کوئری نویسی در OData و WCF Data Service - قسمت اول با قراردادهای کوئری نویسی آشنا شدید در این مطلب به جزئیات بیشتر این قراردادها می‌پردازیم.

عمگرهای منطقی
در OData نه عملگر منطقی داریم که امکان مقایسه منطقی در عبارات‌های شرطی را در اختیارمان قرار می‌دهد.
  1. eq عملگر برابری
  2. ne عملگر مخالف
  3. lt عملگر کوچکتری
  4. le عملگر کوچکتر یا مساوی
  5. gt عملگر بزرگنری
  6. ge عملگر بزرگتر یا مساوی
  7. and
  8. or
  9. not
عملگرهای ریاضی
پنج عمگر ریاضی وجود دارد که امکان انجام عملیات ریاضی در کوئری را میسر می‌سازد.
  1. add جمع دو عملوند
  2. sub تفریق دو عملوند
  3. mul ضرب دو عملوند
  4. div تقیسم دو عملوند
  5. mod باقیمانده تقسیم دو عملوند
در آخر () برای گروه بنده و اولویت دهی عبارات کاربرد دارد.
توابع عبارت‌های کوئری نویسی
در OData چهار دسته توابع داریم
  1. String Functions در جدول زیر این توابع با توضیح آن آورده شده است:
    آیا رشته p0 شامل رشته p1 هست؟
    مثال:http://services.odata.org//Northwind.svc/Customers?$filter=substringof('Alfreds', CompanyName) eq true
    شرح: مشتریانی که نام شرکت آنها شامل رشته Alfreds باشد
    bool substringof(string p0, string p1)
    آیا رشته p0 با رشته p1 پایان می‌یابد؟
    مثال:http://services.odata.org/Northwind/Northwind.svc/Customers?$filter=endswith(CompanyName, 'Futterkiste')
    شرح: مشتریانی که نام شرکت آنها با رشته FutterKiste پایان می‌یابد
    bool endswith(string p0, string p1)
    آیا رشته p0 با رشته p1 آغاز می‌شود؟
    مثال:http://services.odata.org/Northwind.svc/Customers?$filter=startswith(CompanyName, 'Alfr')
    شرح: مشتریانی که نام شرکت آنها با رشته Alfer آغاز می‌یابد
    boolstartswith(string p0, string p1)
    محاسبه طول رشته دریافتی.
    مثال:http://services.odata.org/Northwind/Northwind.svc/Customers?$filter=length(CompanyName) eq 19
    شرح: مشتریانی که طول نام شرکت آنها برابر 19 باشد
    int length(string p0)
    برگشت اندیس رشته وروری
    مثال:http://services.odata.org/Northwind.svc/Customers?$filter=indexof(CompanyName, 'lfreds') eq 1
    شرح: مشتریانی که نام شرکت آنها با رشته lfreds که از کارکتر دوم شروع می‌یابد
    int indexof(string arg)
    جایگزینی یک رشته در رشته دیگر
    مثال:http://services.odata.org/Northwind.svc/Customers?$filter=replace(CompanyName, ' ', '') eq 'AlfredsFutterkiste'
    شرح: مشتریانی که نام شرکت آنها بدون فاصله برابر AlfredsFutterkiste باشد با پرکردن فاصله با جای خالی
    string replace(string p0, string find, string replace)
    برگرداندن رشته ای از رشته دیگر از شماره اندیس ورودی یا از شماره اندیس تا طول رشته ورودی
    مثال:http://services.odata.org/Northwind.svc/Customers?$filter=substring(CompanyName, 1) eq 'lfreds Futterkiste
    شرح: مشتریانی که نام شرکت آنها از کاراکتر دوم برابر lfreds Futterkiste باشد
    'http://services.odata.org/Northwind.svc/Customers?$filter=substring(CompanyName, 1,2) eq 'lf
    string substring(string p0, int pos)
    string substring(string p0, int pos, int length)
    برگرداندن رشته ورودی با کارکتر بزرگ
    برگرداندن رشته ورودی با کاراکتر کوچک
    string tolower(string p0)
    string toupper(string p0)
    حذف کارکتر‌های Whitespace از دو طرف رشته string trim(string p0)
    الحاق رشته به هم string concat(string p0, string p1)

  2. Date Functions
    برگرداندن سال تاریخ ورودی
    مثال:http://services.odata.org/Northwind.svc/Employees?$filter=year(BirthDate) eq 1971 ن
    int year(DateTimep0)
    برگرداندن ماه تاریخ ورودی
    مثال:http://services.odata.org/Northwind/Northwind.svc/Employees?$filter=month(BirthDate) eq 5
    int month(DateTimep0)
    برگرداندن روز تاریخ ورودی
    برگرداندن تعداد روز فاصله زمانی
    مثال: http://services.odata.org/Northwind.svc/Employees?$filter=day(BirthDate) eq 8
    int days(DateTimep0)
    int day(DateTimep0)
    برگرداندن ساعت تاریخ ورودی
    مثال:http://services.odata.org/Northwind.svc/Employees?$filter=hour(BirthDate) eq 4
    int hour(DateTimep0)
    برگرداندن دقیقه تاریخ ورودی
    مثال:http://services.odata.org/Northwind.svc/Employees?$filter=minute(BirthDate) eq 40
    int minute(DateTimep0)
    int minutes(DateTimep0)
    برگرداندن ثانبه تاریخ ورودی
    مثال:http://services.odata.org/Northwind.svc/Employees?$filter=second(BirthDate) eq 40
    int second(DateTimep0)

  3. Math Functions
    برگرداندن سقف عدد ورودی
    مثال:http://services.odata.org/Northwind.svc/Orders?$filter=ceiling(Freight) eq 32
    double ceiling(double p0)
    decimal ceiling(decimal p0)
    برگرداندن کف عدد ورودی
    مثال:http://services.odata.org/Northwind.svc/Orders?$filter=floor(Freight) eq 32
    double floor(double p0)
    decimal floor(decimal p0)

    گردن کردن عدد ورودی
    مثال:ttp://services.odata.org/Northwind.svc/Orders?$filter=round(Freight) eq 32

    double round(double p0)
    decimal round(decimal p0)

  4. Type Functions
    برگرداندن نوع داده وروری
    مثالhttp://services.odata.org/Northwind.svc/Orders?$filter=isof(Customer, NorthwindModel.MVPCustomer)
    شرح: سفارشاتی که نوع مشتری آنها برابر MVPCustomer باشد
    boolisof(type p0)
    boolisof(expression p0, type p1)
    تبدیل نوع داده ورودی
    <p0> cast(type p0)
    < p1> cast(expression p0, type p1
در آخر چند نکته
  1. برای استفاده از رشته‌ها در عبارات از ' تک کوتشن استفاده نمایید 
  2. برای دستیابی به مقادیر پروپرتی‌ها از value$ استفاده نمایید 
  3. برای دستیابی به آدرس روابط‌های یک موجودیت از links$  استفاده نمایید
    مثال:http://services.odata.org/OData/OData.svc/Categories(1)/$links/Products
  4. select$ برای محدود کردن پروپرتی‌های یک موجودیت استفاده می‌شود
    مثال:http://services.odata.org/OData/OData.svc/Products?$select=Price,Name
  5. از ستاره برای دستیابی به همه پروپرتی‌های یک موجودیت می‌توان استفاده نمود
    مثال:http://services.odata.org/OData/OData.svc/Products?$select=*
ادامه دارد...
 
مطالب
توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework - قسمت چهارم
تا قسمت سوم توانستیم Xamarin را نصب و پروژه‌ی اولیه آن را بیلد کنیم. سپس کد مشترک بین سه پلتفرم را بر روی Windows اجرا و Edit & continue آن را هم تست کردیم که هم برای UI ای که با Xaml نوشته می‌شود و هم برای منطقی که با CSharp نوشته می‌شود، کار می‌کند.
همانطور که گفتیم، کد UI و Logic برای هر سه پلتفرم مشترک است؛ منتهی به علت امکانات دیباگ فوق العاده و سرعت بیشتر ویندوز، ابتدا آن را بر روی ویندوز تست کردیم و بعد برای تکمیل UI، آن را بر روی Android اجرا می‌کنیم. این بار می‌توانید دو پروژه UWP و iOS را Unload کنید و سپس پروژه Android ای را در صورت Unload بودن Load کنید. (با راست کلیک نمودن روی پروژه). این کار باعث می‌شود Visual Studio بیهوده کند نشود؛ مخصوصا اگر سیستم شما ضعیف است.
ابتدا با موبایل یا تبلت اندرویدی شروع می‌کنیم. اگر چه Xamarin از نسخه‌ی 4.0.3 اندروید به بالا را پشتیبانی می‌کند، ولی توصیه می‌کنم وقتتان را بر روی گوشی‌های اندرویدی کمتر از 4.4 تلف نکنید. دستگاه را می‌توانید، هم به صورت USB و هم به صورت Wifi استفاده کنید. ابتدا باید دستگاه اندرویدی خود را آماده‌ی برای دیباگ کنید. برای این منظور مقاله‌های فارسی و انگلیسی زیادی وجود دارند که می‌توانید از آن‌ها استفاده کنید. من عبارت "اندروید debug" را جستجو کردم و به این مقاله رسیدم. همچنین Android SDK شما باید USB debugging اش نصب شده باشد که البته حجم زیادی ندارد. برای بررسی این مورد ابتدا از وجود فولدر extras\google\usb\_driver درAndroid SDK خود مطمئن شوید. حال سؤال این است که ویژوال استودیو، Android SDK را کجا نصب کرده‌است که خیلی ساده در این لینک توضیح داده شده‌است.
اگر فولدر extras\google\usb\_driver وجود نداشت، باید آن را نصب کنید که خیلی ساده توسط Android SDK Manager امکان پذیر است؛ ولی نه! امکان پذیر نیست!
دلیل: در Xamarin شما همیشه بر روی آخرین SDK‌ها حرکت می‌کنید. این شامل Windows SDK 17134 و Android SDK 27 و iOS SDK 11 است. وقتی از نسخه‌ی فعلی ویژوال استودیو، یعنی 15.8 به نسخه‌ی بعدی ویژوال استودیو که الان Preview است بروید، یعنی 15.9، عملا به این معنا است که به Windows SDK 17763 و Android SDK 28 و iOS SDK 12 می‌روید. این بزرگترین مزیت Xamarin است و این یعنی شما همیشه به صد در صد امکانات هر پلتفرم در زبان CSharp دسترسی دارید و همیشه آخرین SDK هر سیستم عامل در اختیار شماست و اگر دوستی از طریق Swift توانست مثالی از ARKit 2.0 را در iOS 12 پیاده سازی کند، قطعا شما هم می‌توانید. همچنین تیم Xamarin نه تنها این امکانات را بلکه Documentation لازم را نیز در اختیار شما قرار می‌دهد. چون در همین مثال، مستندات Apple به زبان Swift / Objective-C بوده و مستندات Xamarin به زبان CSharp.
حال اگر سری به فولدر Android SDK نصب شده‌ی توسط Visual Studio بزنید، مشاهده می‌کنید که خبری از Android SDK Manager نیست! به صورت رسمی، مدتی است که گوگل در نسخه‌های اخیر Android SDK، دیگر Android SDK Manager را ارائه نمی‌کند و همانطور که گفتم شما الان بر روی آخرین نسخه‌ی Android SDK هستید. هر چند ترفندهایی وجود دارد که این Manager را باز می‌گردانند، ولی لزومی به انجام این کار در Xamarin نیست و شما می‌توانید از Android SDK Manager ای که تیم Xamarin ارائه داده‌است، استفاده کنید. همین مسئله در مورد Android Virtual Device Manager که برای مدیریت Emulator‌ها بود نیز صدق می‌کند.
برای استفاده از این دو، ضمن استفاده از ابزارهای دور زدن تحریم، در ویژوال استودیو، در منوی Tools، به قسمت Android رفته و Android SDK Manager را باز کنید. Android Emulator Manager نیز جایگزین Android Virtual Device Manager ای است که قبلا توسط گوگل ارائه می‌شد. حال بعد از باز کردن Android SDK Manager ارائه شده توسط Xamarin، به برگه‌ی Tools آن بروید و از  قسمت extras مطمئن شوید که Google USB driver تیک خورده باشد.
حال پس از وصل کردن گوشی یا تبلت اندرویدی به سیستم توسط کابل USB و Set as startup project نمودن پروژه‌ی XamApp.Android که در قسمت قبل آن را Clone کرده بودید، می‌توانید پروژه را بر روی گوشی خود اجرا کنید. اگر نام گوشی خود را در کنار دکمه‌ی سبز اجرای پروژه (F5) نمی‌بینید، بستن و باز کردن Visual Studio را امتحان کنید. 

پروژه را که اجرا کنید، اولین بیلد کمی طول می‌کشد (اولین بار دو برنامه بر روی گوشی شما نصب می‌شوند که برای کار دیباگ در Xamarin لازم هستند) و اساسا بیلد یک پروژه‌ی اندرویدی کند است. خوشبختانه به واسطه وجود Xaml edit and continue احتیاجی به Stop - Start کردن پروژه و بیلد کردن برای اعمال تغییرات UI نیست و به محض تغییر Xaml، می‌توانید تاثیر آن را در گوشی خود ببینید. ولی برای هر تغییر CSharp باید Stop - Start و Build کنید که زمان بر است و به همین علت تست بر روی پروژه ویندوزی را برای پیاده سازی منطق برنامه پیشنهاد می‌کنیم. البته در نسخه‌ی 15.9 ویژوال استودیو، سرعت بیلد تا 40% بهبود یافته است.
ممکن است شما گوشی اندرویدی یا تبلت نداشته باشید که بخواهید بر روی آن تست کنید و یا مثلا گوشی شما Android 7 هست و می‌خواهید بر روی Android 8 تست بگیرید. در این جا شما احتیاج به استفاده از Emulator را خواهید داشت.
توجه داشته باشید که Emulator شما ترجیحا نباید ARM باشد و بهتر است یا X86 یا X64 باشد، وگرنه ممکن است خیلی کند شود. همچنین بهتر است Google Play Services داشته باشد. همچنین ترجیحا دنبال گزینه‌ی اجرا کردن Emulator نروید؛ اگر خود ویندوز شما درون یک Virtual Machine در حال اجراست.

ابتدا ضمن جستجو کردن "فعال سازی intel virtualization"، اقدام به فعال سازی این امکان در سیستم خود کنید. این آموزش را مناسب دیدم.
گزینه‌های مطرح: [Google Android Emulator] - [Genymotion] - [Microsoft Hyper-V Android Emulator] که فقط یکی از آنها را لازم دارید.

Google Android Emulator توسط خود Google ارائه می‌شود و دارای Google Play Services نیز هست. بر اساس این آموزش به صفحه Workloads در Visual Studio Installer بروید و از قسمت Xamarin دو مورد "Google Android Emulator API Level 27" و "Intel Hardware Accelerated Execution Manager (HAXM) global install" را نصب کنید. توجه داشته باشید که بدین منظور احتیاج به ابزارهای دور زدن تحریم دارید؛ زیرا نیاز به دسترسی به سرورهای گوگل هست. این Emulator آماده برای دیباگ هست و نیازی به اقدام خاصی نیست.

Genymotion حجم کمتری دارد و برای دانلود احتیاج به ابزارهای دور زدن تحریم را ندارد و اساسا نسبت به بقیه بر روی سیستم‌های ضعیف‌تر، بهتر کار می‌کند. فقط Emulator ای که با آن می‌سازید، به صورت پیش فرض Google Play Services را ندارد که در آخرین نسخه‌های آن گزینه Open  GApps به toolbar اضافه شده که Google Play Services را اضافه می‌کند. (از انجام هر گونه عملیات پیچیده بر اساس آموزش‌هایی که برای نسخه‌های قدیمی‌تر Genymotion هستند، پرهیز کنید). مطابق با ابتدای همین آموزش برای دستگاه‌های اندرویدی، Emulator خود را آماده برای دیباگ کنید.

Microsoft Hyper-V android emulators. مایکروسافت قبلا اقدام به ارائه یک Android Emulator کرده بود که برای نسخه 4 و 5 اندروید بودند و بزرگ‌ترین ضعف آنها عدم پشتیبانی از Google Play Services بود که ادامه داده نشدند. ولی سری جدید ارائه شده توسط مایکروسافت چنین مشکلی را ندارد. اگر CPU شما AMD بوده و روش‌های قبلی برای شما کند هستند یا اساسا کار نمی‌کنند، یا در حال حاضر در حال استفاده از Docker for Windows هستید که از Hyper-V استفاده می‌کنید و قصد استفاده مجدد از منابع موجود را دارید، این نیز گزینه خوبی است که جزئیات آن را می‌توانید در  اینجا  دنبال کنید. این Emulator آماده برای دیباگ هست و نیازی به اقدام خاصی نیست. 

پس از اینکه Emulator خود را ساختید، آن را اجرا کنید. سپس برنامه را از درون ویژوال استدیو اجرا کنید. مطابق نسخه ویندوزی، دوباره یک دکمه دارید و یک Label، عدد بر روی Label، با هر بار کلیک کردن بر روی دکمه، افزایش می‌یابد.
سرعت اجرای این برنامه در Emulator یا گوشی شما برای دیباگ است و در حالت Release، سرعت چندین برابر بهتر خواهد شد و به هیچ وجه تست‌های Performance را بر روی Debug mode انجام ندهید.

حال نوبت به پابلیش پروژه می‌رسد. در این قسمت باید توجه کنید که حجم Apk شما برای پروژه‌ی XamApp مثال ما به 7 مگ می‌رسد که برای یک فرم ساده خیلی زیاد به نظر می‌رسد. ولی اگر شما بجای یک فرم ساده، صد فرم پیچیده نیز داشته باشید، باز هم این حجم به 8 مگ نخواهد رسید. حجم Apk خیلی متاثر از کدهای شما نیست، بلکه شامل موارد زیر است:
1- NET. که خود شامل CLR  & BCL است. (BCL (Base Class Library  مثل کلاس‌های string - Stream - List - File و (CLR (Common language runtime که شامل موارد لازم برای اجرای کدها است. این پیاده سازی بر اساس NET Standard 2.0. بوده که عملا اجازه استفاده از تعداد خیلی زیادی از کتابخانه‌های موجود را می‌دهد، حتی Entity framework core! البته هر کتابخانه حجم DLL‌های خودش را اضافه می‌کند.
2- Android Support libraries که به شما اجازه می‌دهد از تعداد زیادی (و البته نه همه) امکانات نسخه‌های جدید اندروید در پروژه‌تان استفاده کنید که بر روی نسخ قدیمی‌تر Android نیز کار کنند. همچنین با یکپارچگی با Google Play Services عملا خیلی از کارها ساده‌تر و با Performance بهتری انجام می‌شود، مانند گرفتن موقعیت کاربر جاری.
3-  Xamarin essentials . اگر چه در CSharp شما به صد در صد امکانات هر سیستم عامل دسترسی دارید و می‌توانید مثلا مقدار درصد شارژ باطری را بخوانید، ولی اینکار مستلزم نوشتن سه کد CSharp ای برای Android - iOS - Windows است که طبیعتا کار را سخت می‌کند. اما Xamarin Essentials به شما اجازه می‌دهد با یک کد CSharp واحد برای هر سه پلتفرم، با باطری، کلیپ‌بورد، قطب نما و خیلی موارد دیگر کار کنید.
4- Xamarin.Forms. اگر Button و Label ای که در مثال برنامه داشتیم، با یکبار نوشتن بر روی هر سه پلتفرم دارند کار می‌کنند، در حالی که هر پلتفرم، Button مخصوص به خود را دارد؛ این را Xamarin Forms مدیریت می‌کند. علاوه بر این، Binding نیز به عهده‌ی Xamarin Forms است.
5- Prism Autofac Bit Framework: درک آن‌ها نیاز به دنبال کردن آموزش‌های این دوره را دارد؛ ولی به صورت کلی معماری پروژه شما بسیار کارآمد و حرفه‌ای خواهد شد و به کدی با قابلیت نگهداری بالا خواهید رسید. 
6-  Rg Plugins Popup  و  Xamanimation  نیز دو کتابخانه‌ی UI بسیار کاربردی و جالب هستند که در طول این آموزش از آنها استفاده خواهد شد.
حجم 7 مگ برای این تعداد کتابخانه و امکان، خیلی زیاد نیست و شما عملا تعداد زیادی از پروژه‌های خود را می‌توانید با همین حجم ببندید و اگر مثلا به پروژه‌ی Humanizer خیلی علاقه داشته باشید (که در این صورت حق هم دارید!) می‌توانید با اضافه شدن چند کیلوبایت (!) به پروژه آن را داشته باشید. اکثر کتابخانه‌های NET. ای سبک هستند. همچنین موقع قرار گرفتن در پروژه، فشرده سازی نیز می‌شوند و قسمت‌های استفاده نشده‌ی آن‌ها نیز توسط Linker حذف می‌شوند.
علاوه بر این، اجرای برنامه بر روی گوشی‌های ضعیف و قدیمی کمی طول می‌کشد. این مربوط به اجرای برنامه است؛ نه باز شدن فرم مثال ما که دارای Button و Label بود و اگر مثال ما دو فرم داشته باشد (که در آموزش‌های بعدی به آن می‌رسیم) می‌بینید که چرخش بین فرم‌ها بسیار سریع است.

مواردی مهم در زمینه‌ی بهبود عملکرد پروژه‌های Xamarin در Android
در ابتدا باید بدانید Apk شما شامل دو قسمت است؛ یکی کدهای CSharp ای شما که DotNet ای بوده و در کنار کدهای کتابخانه‌هایی چون Json.NET بر روی DotNet اجرا می‌شوند. دیگری کتابخانه‌ای است که مثلا با Java نوشته شده و بعد برای استفاده در CSharp بر روی آن یک Wrapper یا پوشاننده توسعه داده شده‌است. عموما توسعه دهندگان چنین پروژه‌هایی، ابتدا پروژه را به Java می‌نویسند و بعد برای JavaScript - CSharp و ... Wrapper ارائه می‌دهند.
برای بهبود اینها ابزارهایی چون AOT-NDK-LLVM-ProGurad-Linker و ... وجود دارند که سعی می‌کنم به صورت ساده آنها را توضیح دهم.

وظیفه ProGurad این است که از قسمتی از پروژه‌ی شما که بخاطر کتابخانه‌های Java ای، عملا DotNet ای نیست، کدهای اضافه و استفاده نشده را حذف کند.
ممکن است استفاده از ProGurad باعث شود کلاسی که داینامیک استفاده شده است، به اشتباه حذف شود. پروژه XamApp دارای یک ProGuard configuration file است که جلوی چنین اشتباهاتی را حتی الامکان می‌گیرد.
همچنین ProGurad که در داخل Android SDK قرار دارد، به Space در طول مسیر حساس است (!) و با توجه به اینکه مسیر پیش فرض Android SDK نصب شده‌ی توسط ویژوال استودیو دارای Space است (C:\Program Files (x86)\Android\android-sdk)  شما در همان ابتدا دچار مشکل می‌شوید! برای حل این مشکل ابدا فولدر Android SDK را جا به جا نکنید؛ بلکه از امکانی در ویندوز به نام Junction folder یا فولدر جانشین استفاده کنید. بدین منظور دستور زیر را وارد کنید:
mklink /j C:\android-sdk "C:\Program Files (x86)\Android\android-sdk"
این مورد باعث می‌شود که مسیر C:\android-sdk نیز به همان مسیر پیش فرض اشاره کند و این دو مسیر در واقع یکی هستند. امیدوارم این امکان را با قابلیت Shortcut سازی در ویندوز اشتباه نگیرید! حال از منوی Tools > Options > Xamarin > Android Settings مسیر Android SDK را به C:\android-sdk تغییر دهید که فاقد Space است و ویژوال استودیو را ببندید و باز کنید.

NDK که در ادامه SDK برای Android قرار می‌گیرد، Native Development Kit است و باعث می‌شود هم DLL‌های DotNet ای و هم Jar‌های Java ای به فایل‌های so تبدیل شوند. so همان DLL ویندوز است، البته برای Linux و همانطور که احتمالا می‌دانید، پایه Android بر روی Linux است. طبیعتا کامپایل شدن کدها به so، بر روی بهبود سرعت برنامه تاثیر گذار است.

Linker نیز مشابه با ProGuard کمک می‌کند، ولی اینبار حجم DLL‌های DotNet ای مانند Json.NET را کم می‌کند. بالاخره شما از صد در صد کلاس‌های یک DLL استفاده نمی‌کنید و موارد اضافی نیز باید حذف شوند. البته این وسط، امکان حذف اشتباه کلاس‌هایی که به صورت داینامیک فراخوانی شده باشند وجود دارد که LinkerConfig موجود در پروژه XamApp حتی الامکان جلوی این مشکل را می‌گیرد.

Release mode  مثل هر پروژه CSharp ای دیگری، بهتر است پروژه در حالت Release mode پابلیش شود. در پروژه XamApp در حالت Release mode، موارد بالا یعنی Linker-NDK-ProGuard نیز درخواست می‌شوند.

جزئیات این موارد در مستندات Xamarin وجود دارد و در پایان این دوره یک Project Builder سورس باز نیز به شما ارائه می‌شود که ساختار اولیه پروژه‌ها را بر اساس نیازهای شما و با بهترین تنظیمات ممکن می‌سازد.

در پروژه XamApp علاوه بر موارد فوق، دو مورد دیگر نیز آماده به استفاده هستند، ولی غیر فعال شده اند؛ AOT و LLVM. اگر به تازگی برنامه نویس شده‌اید، موارد زیر ممکن است خیلی برایتان پیچیده باشند، از آن‌ها عبور کنید و به عنوان "نحوه انجام دادن پابلیش" بروید.

کدهای‌های DotNet ای به سه شکل می‌توانند اجرا شوند:
JIT - AOT - Interpreter
یک برنامه DotNet ای برای اجرا می‌تواند از ترکیب اینها استفاده کند. حالت Interpreter که خیلی جدید معرفی شده و الآن موضوع بحث نیست؛ می‌ماند JIT و AOT
کد CSharp در هنگام کامپایل به IL تبدیل و سپس در زمان اجرا توسط Just in time compiler به زبان ماشین تبدیل می‌شود. اگر قبلا پروژه‌ی ASP.NET یا ASP.NET Core نوشته باشید، چنین رفتاری را در پشت صحنه خواهد داشت. خود JIT که در هر بار اجرای برنامه انجام می‌شود، عملا زمان بر هست. ولی کد زبان ماشین حاصل از آن خیلی Optimize شده برای دقیقا همان ماشین هست؛ با در نظر گرفتن خیلی فاکتورها. در پروژه‌های سمت سرور مثل ASP.NET که پروژه وقتی یک بار اجرا می‌شود، مثلا روی IIS، ممکن است صدها هزار دستور را اجرا کند، در طول چندین روز یا ماه، این عمل JIT خیلی مفید هست. البته همان سربار اولیه‌ی JIT هم توسط چیزی به عنوان Tiered JIT می‌تواند کمتر شود.
اما در پروژه‌ی موبایل که برنامه ممکن است بعد از باز شدن، مثلا ده دقیقه باز باشد و بعد بسته شود، انجام شدن JIT با هر بار باز شدن برنامه خیلی مفید به فایده نیست. بنا به برخی مسائل که واقعا سطح این آموزش را خیلی پیچیده می‌کند، نتیجه کار JIT قابلیت Cache شدن آن چنانی ندارد و عملا باید هر بار اجرا شود.
در پروژه‌های موبایل، گزینه دیگری بر روی میز هست به نام Ahead of time یا AOT که کار تبدیل IL به زبان ماشین را در زمان کامپایل و پابلیش پروژه انجام دهد. طبیعتا این باعث می‌شود سرعت برنامه موبایل در عمل خیلی بالاتر رود، چون سربار JIT در هر بار اجرای برنامه حذف می‌شود. همچنین روال AOT می‌تواند از LLVM یا Low level virtual machine استفاده کند که منجر به تبدیل شدن کد زبان ماشینی می‌شود که بر روی LLVM کار می‌کند. LLVM خودش یک Runtime با سرعت خیلی بالاست که بر روی تمامی سیستم عامل‌ها کار می‌کند.
بر روی Android - iOS - Windows می‌شود از AOT استفاده کرد. در iOS و ویندوز، استفاده‌ی از AOT منجر به افزایش سایز برنامه نمی‌شود، چون قبلا برنامه یک سری کد IL بوده که زمان اجرا توسط JIT به کد ماشین تبدیل می‌شده و الان بجای آن IL، یک سری کد زبان ماشین مبتنی بر LLVM هست. اما بر روی Android، پیاده سازی AOT ناقص هست و البته که با فعال کردن‌اش، سرعت برنامه بسیار بیشتر می‌شود، ولی کماکان نیاز به JIT و IL هم برای برخی از سناریوها هست. این مورد یعنی اینکه فعال سازی AOT+LLVM بر روی اندروید تا مادامی که AOT در Android به صورت آزمایشی هست، باعث افزایش حجم Apk ما از 7 به 13 مگ می‌شود. البته این مورد در نسخه‌های بعدی رفع خواهد شد و رفتار Android مشابه با iOS-Windows خواهد بود؛ یعنی حجم نسبتا کم و سرعت خیلی بالا.
برای فعال سازی AOT+LLVM در csproj پروژه اندرویدی، دو مقدار AotAssemblies و EnableLLVM را از false به true تغییر دهید:
 <AotAssemblies>true</AotAssemblies> 
 <EnableLLVM>true</EnableLLVM>
با این تنظیمات، بیلد شما طولانی‌تر و در عوض سرعت اجرای برنامه بیشتر خواهد شد.

نحوه انجام دادن پابلیش 
برای انجام دادن پابلیش، بر روی پروژه XamApp.Android در هنگامیکه بر روی Release mode هستید، راست کلیک کنید و Archive را بزنید. سپس فایل Archive شده را انتخاب و Distribute را بزنید که به شما Apk مناسب برای انتشار توسط خودتان یا Google Play می‌دهد.
نکات مهم:
1- فایل Apk حاصل از Archive را بدون Distribute کردن، در اختیار کسی قرار ندهید. فقط پیام Corrupt و خراب بودن فایل، حاصل کارتان خواهد بود!
2- اولین باری که Distribute می‌کنید، Wizard مربوطه کمک می‌کند تا یک فایل Certificate را برای Apk اتان بسازید. آن فایل را گم نکنید! در پابلیش‌های بعدی دیگر نباید Certificate جدیدی بسازید؛ بلکه فایل قبلی را باید به آن معرفی کنید و فقط رمز آن Certificate را دوباره بزنید.
3- به برنامه آیکون بدهید. برای آن Splash Screen خوبی بگذارید. در هر بار پابلیش، ورژن برنامه را افزایش دهید. اینها همگی توضیحات اش بر روی بستر وب موجود است. سؤالی بود، همینجا هم می‌توانید بپرسید.
فایل‌های Apk این مثال را می‌توانید از اینجا دانلود کنید.

در قسمت بعدی آموزش، دیباگ و پابلیش گرفتن پروژه بر روی iOS را خواهیم داشت که البته مقداری از مطالب اش با مطالب این آموزش مشترک هست. بعد دست به کد شده و آموزش CSharp و Xaml را خواهیم داشت تا پروژه‌ای با کیفیت، کارآمد و عالی از هر جهت بنویسید.
همچنین تعدادی از نکات مربوط به Performance که مربوط به ظاهر برنامه و نحوه چیدمان صفحات و کنترل‌ها هستند و بر روی Performance هر سه پلتفرم تاثیر گذار هستند (و نه فقط Android‌) نیز در ادامه بحث خواهند شد.
نظرات مطالب
اعمال تزریق وابستگی‌ها به مثال رسمی ASP.NET Identity
این نکته‌ای را که عنوان کردید با استفاده از DNTProfiler بررسی کردم و اصلا چنین چیزی (28 بار فراخوانی) نیست. در پشت صحنه از نسخه‌ی Async متد Find استفاده می‌شود (در stack trace موجود هست) و حذف آن با متد ساده‌ای که نوشته شده، یک سری از سازوکارهای داخلی ASP.NET Identity را حذف می‌کند و به صلاح نیست.
نظرات مطالب
استفاده از Froala WYSIWYG Editor در ASP.NET
سلام
ممنون برای این مطلب
فکر کنم این ادیتور با کروم یک مشکل داره:
برای مثال کلمه «تست» رو در اون تایپ کنید، سپس بعد از «س» یک حرف جدید مثل «ن» وارد کنید: نتیجه باید بشود «تسنت» اما میشود «تسن‌ت».
البته من در کروم 34 تست کردم. با IE 10 و Firefox 28 مشکلی نداشت. 
نظرات مطالب
EF Code First #1
اشکالش پیدا کردم توی کتاب برای شی patient  چون خصوصیت FirstVisit مقداردهی نشده و نباید تهی باشد بنابراین زمان اجرا نمی‌تواند تاریخ پیش فرض را تبدیل کند. با اضافه کردن خط زیر

....

BirthDate = new DateTime(2008, 1, 28),
<<< FirstVisit = new DateTime(2008,1,12), >>>
AnimalType = dog,

.....

مشکل حل شد.
مطالب
PersianDatePicker یک DatePicker شمسی به زبان JavaScript که از تاریخ سرور استفاده می‌کند
PersianDatePicker  یک DatePicker شمسی برای نمایش تاریخ شمسی در صفحات وب است.

مهمترین ویژگیها :
  • از تاریخ سرور برای نمایش روز جاری استفاده می‌کند.
  • به زبان جاوااسکریپت است و نیازی به سایر فریمورک‌ها مانند jQuery ندارد.
  • سبک و کم حجم است (3.5 کیلوبایت)
  • روزها به صورت عمودی لیست شده‌اند مانند برنامه هفتگی مدرسه که کاربران فارسی‌زبان با آن راحت‌ترند.

طرز استفاده :

PersianDatePicker.Show(textBox, today)
textBox : کنترلی است که DatePicker برای آن نمایش داده می‌شود.
today : تاریخ روز جاری است.

برای مثال :
<html>
<head>
    <script type="text/javascript" src="Scripts/PersianDatePicker.min.js"></script>
    <link type="text/css" rel="stylesheet" href="Content/PersianDatePicker.min.css" />
</head>
<body>
    <input type="text" onclick="PersianDatePicker.Show(this, '1392/03/22');" />
</body>
</html>

در ASP.NET Web Forms :
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication4.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/PersianDatePicker.min.js"></script>
    <link href="Content/PersianDatePicker.min.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label runat="server" Text="Label" AssociatedControlID="TextBox1">تاریخ : </asp:Label>
            <asp:TextBox  runat="server" ID="TextBox1"></asp:TextBox>
        </div>
    </form>
</body>
</html>

public partial class WebForm1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var now = PersianDateTime.Now;
        var today = now.ToString(PersianDateTimeFormat.Date);

        TextBox1.Attributes["onclick"] = "PersianDatePicker.Show(this,'" + today + "');";
    }
}

در مثال بالا برای گرفتن تاریخ روز جاری از PersianDateTime استفاده شده است. 

در ASP.NET MVC یا PHP یا هر زبان دیگری کافیست onclick کنترل متنی مورد نظر در سمت سرور مانند مثال بالا مقدار داده شود. یا می‌توان image کوچکی کنار textbox مورد نظر قرار داد و onclick آن تنظیم شود.

برای استفاده از PersianDatePicker می‌توانید آنرا از NuGet دریافت کنید :
PM> Install-Package PersianDatePicker

همچنین یک مثال کامل ASP.NET MVC آن‌را می‌توانید از اینجا دریافت کنید:
MvcAppPersianDatePicker.zip   
اشتراک‌ها
15 کتاب الکترونیکی برای طراحان و توسعه دهندگان
1.Pocket Guide to Writing SVG
2.Speaking JavaScript
3.Adaptive Web Design
4. 27 Page Type Classification eBook
5. 11 Things to Do with Every New WordPress Install
6. Building Web Apps with Go
7. Go Mobile With WordPress
8. HTML Canvas Deep Dive 
9. 10 Keys to Great Landing Pages
10. Book of Speed
11. A Practical Guide to Designing for the Web
12. PHP: The Right Way
13. Essential Career Advice for Developers
14. So You Want To Be A Freelancer?
15. Magic of CSS
15 کتاب الکترونیکی برای طراحان و توسعه دهندگان