مطالب
یکی کردن اسمبلی‌ها با استفاده از Eazfuscator

نسخه جدید برنامه Eazfuscator به همراه دو قابلیت جالب یکی کردن و همچنین مدفون نمودن اسمبلی‌ها ارائه شده است:

یکی کردن چند اسمبلی با هم
Eazfuscator برای یکی کردن اسمبلی‌ها از برنامه معروف ILmerge استفاده می‌کند با این تفاوت که دیگر نیازی نیست تا پارامترهای آن‌را تنظیم کرد و بسیاری از مسایل را به صورت خودکار مدیریت می‌کند.
جهت فعال کردن این قابلیت، یکی از روش‌های کار به صورت زیر است:
فایلی به نام ObfuscationSettings.cs را به پروژه خود اضافه کرده، سپس محتویات آن‌را حذف نموده و با چند سطر زیر جایگزین و کامپایل کنید:
using System;
using System.Reflection;

[assembly: Obfuscation(Feature = "merge with file1.dll", Exclude = false)]
[assembly: Obfuscation(Feature = "merge with file2.dll", Exclude = false)]
[assembly: Obfuscation(Feature = "merge with file3.dll", Exclude = false)]

همانطور که ملاحظه می‌کنید این چند سطر حاوی نام اسمبلی‌هایی می‌باشند که قرار است با اسمبلی جاری یکی شوند.
سپس اسمبلی جاری را (می‌خواهد فایل exe باشد یا یک dll ، فرقی نمی‌کند) بر روی Eazfuscator کشیده و رها کنید. پس از چند لحظه اسمبلی نهایی تولید شده شامل تمام کلاس‌ها و منابع اسمبلی‌هایی خواهد بود که در فایل ObfuscationSettings.cs ذکر شده‌اند؛ به همراه Obfuscation خودکار آن‌ها.

مدفون کردن اسمبلی‌ها در یک اسمبلی
قابلیت دیگر این برنامه دفن (embedding) چند اسمبلی در اسمبلی نهایی است. برای فعال سازی آن روش کار همانند قبل است با این تفاوت که بجای merge with باید نوشت embed . برای مثال:
[assembly: Obfuscation(Feature = "embed Common.dll", Exclude = false)]

به این ترتیب اسمبلی‌های ذکر شده پس از رمزنگاری و فشرده شدن به صورت منابع اسمبلی جاری ذخیره خواهند شد. مدیریت استفاده از آن‌ها هم خودکار است و نیازی نیست تا کاری در این مورد صورت گیرد.
برای نمونه برنامه معروف LINQPad از همین روش استفاده می‌کند و لازم به ذکر است که ... هنوز که هنوز است هیچ ک.ر.ک. کارسازی برای فعال سازی قسمت intellisense آن که رایگان نیست ارائه نشده و تمام وصله‌های جدید ارائه شده کار نمی‌کنند ...

تفاوت مدفون کردن با یکی کردن چیست؟
در حالت یکی کردن اسمبلی‌ها، سربار اولیه بارگذاری برنامه همانند روش مدفون سازی وجود ندارد. اما این سربار آنقدر ناچیز است که کسی آن‌را احساس نخواهد کرد. مورد دیگر، عدم پشتیبانی از روش مدفون سازی در سایر سکوهای کاری مانند ویندوز فون، Compact Framework و غیره است. اما باید درنظر داشت که برای مثال ILMerge روی اسمبلی‌های دارای XAML کار نمی‌کند (مطابق مستندات رسمی آن). بنابراین همیشه نمی‌توان از روش یکی سازی استفاده کرد و محدودیت‌های خاص خودش را دارد.
در کل روش مدفون سازی به دلیل Obfuscation ، فشرده سازی و رمزنگاری همزمان، امنیت بیشتری را نسبت به حالت Obfuscation تنها ارائه می‌دهد (حداقل شخص "علاقمند" به مطالعه این نوع اسمبلی‌ها باید از چند لایه رد شود و تجربه برنامه LINQPad ثابت کرده که این روش در مقیاس کلان (در انظار عمومی هزاران علاقمند) بسیار موفق بوده است).

مسیرراه‌ها
توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
لطفا علاوه بر مطالب، نظرات نیز مطالعه شوند.

قسمت اول چرا Xamarin Forms؟
قسمت دوم نصب و راه اندازی
قسمت سوم اجرا و دیباگ پروژه مثال روی UWP و راه اندازی Simulator و Edit & Continue برای C# - XAML
قسمت چهارم اجرا و دیباگ پروژه مثال روی Android + راه اندازی Emulator و Device + نکات بهبود Performance در Android
قسمت پنجم اجرا و دیباگ پروژه مثال روی iOS + راه اندازی Virtual Mac OS + تست بر روی Emulator و Device
قسمت ششم بررسی کلیات پروژه مثال و بررسی ساختار Page - Layout - Control
قسمت هفتم بررسی جزئیات Layout شامل Unit - Padding -Margin و ...
قسمت هشتم بررسی نقش View Model در MVVM و طرز کار Navigation
قسمت نهم Binding & Commanding & x:DataType
قسمت دهم Triggers & Value Converters
قسمت یازدهم List View & Syncfusion Controls
قسمت دوازدهم چند زبانه سازی و Right To Left
قسمت سیزدهم بهبود Performance با Compressed Layout و FF Image Loading
قسمت چهاردهم مدیریت خطاها و استفاده از App Center برای لاگ کردن آنها
قسمت پانزدهم زدن کدهای Platform Specific و Custom Renderers
قسمت هجدهم ارتباط با Rest Api
قسمت نوزدهم نوشتن Component و Partial View
قسمت بیستم Entity Framework Core & Sqlite
قسمت بیست و یکم آشنایی با پروژه ToDoStand
قسمت بیست و دوم ارتباط با پروژه ای که سمت سرور آن با Bit توسعه داده شده است و مزیت‌های کار با Bit در سمت سرور
قسمت بیست و سوم آشنایی با پروژه ToDoLine
مطالب
طراحی گزارش در Stimulsoft Reports.Net – بخش 1

برای طراحی گزارش شما میتوانید به سه روش این کار را انجام دهید.

1- طراحی در برنامه طراح گزارش

2- طراحی از داخل ویژوال استودیو

3- طراحی گزارش در زمان اجرا

برای شروع شما میتوانید نسخه آزمایشی این گزارش‌ساز را دریافت کنید. تنها محدودیت این نسخه نمایش عبارت Demo در چاپ میباشد.

برنامه Designer  را اجرا کنید. در صورتی که برای اولین بار است این برنامه را اجرا میکنید ابتدا باید رابط کاربری خود را انتخاب نمایید. نوار ابزار سمت چپ تمامی ابزارهای پر‌کاربرد طراحی گزارش را در اختیارتان قرار میدهد. ابزارهایی که در این بخش درباره آنها توضیح داده خواهد شد عبارتند از:

Header, Footer, Data, Page Header, Page Footer, Report Title, Report Summery

*به ابزارهای بالا Band گفته میشود.

Header , Footer :

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

Data :

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

Page Header , Page Footer :

این دو بند با توجه به نامشان جهت نمایش در بالا و پایین هر صفحه از گزارش میباشد. البته باز هم یادآور میشوم که با تغییر در خصوصیات‌شان میتوانید رفتار و نحوه نمایش آنها را تغییر دهید.

Report Title :

این بند فقط در ابتدای گزارش نمایش داده خواهد شد.

Report Summery :

این بند بلافاصله بعد از اتمام گزارش نمایش داده خواهد شد.

مثال :

برای شروع در Designer یک گزارش جدید از نوع Blank Report ایجاد نمایید. سپس در پنل Dictionary بر روی New Item کلیک کرده و گزینه XML Data را انتخاب نمایید. با توجه به محل نصب گزارش‌ساز وارد مسیر …\Bin\Data شده و فایلهای Demo.xsd و Demo.xml را برای قسمتهای مربوطه انتخاب نمایید. یک بار دیگر بر رو New Item کلیک کرده و گزینه New Data Source را انتخاب نمایید، از لیست ظاهر شده کانکشنی را که ایجاد کرده‌اید را انتخاب نمایید؛ نتیجه کار تا اینجا باید به صورت زبر باشد.

جدول Product را دراگ کرده و بر روی صفحه طراحی گزارش رها کنید. فرم Data ظاهر میشود این فرم را مطابق تصویر زیر تنظیم نمایید.

حال بر روی صفحه طراحی گزارش بندهای Header, Data, Footer مشاهده میشود؛ حال شما میتوانید با کلیک بر روی سربرگ Preview خروجی گزارش را ببینید.

توابع :

این گزارش‌ساز دارای توابع بسیاری است که اکثر نیازهای شما را برطرف می‌کند به عنوان مثال تابع تبدیل عدد به حروف به زبان فارسی. همچنین شما میتوانید توابع خاص خود را ساخته و به صورت رفرنس به گزارش اضافه نمایید.

در این بخش ما از توابع موجود در گزارش استفاده خواهیم کرد. برای شروع بر روی کامپوننت Text در بند Footer  زیر ستون UnitPrice دابل کلیک کرده تا فرم TextEditor ظاهر شود. سربرگ Summery را انتخاب نمایید. مطابق اطلاعات زیر بخشها را تنظیم نمایید.

Summery Function: Sum

Data Band: DataProducts

Data Column: Products.UnitPrice

حال بر روی سربرگ Preview کلیک نمایید تا خروجی گزارش را ببینید. جمع ستون UnitPrice فقط در صفحه آخر نمایش داده خواهد شد. اگر بخواهید جمع ستون در پایین هر صفحه نمایش داده شود ابتدا باید خصوصیت Print on All Pages بند Footer به True ست شود. سپس بر روی کامپوننت Text در بند Footer، دابل کلیک نمایید و در فرم TextEditor سربرگ Summery تیک Running Total را به حالت انتخاب شده در بیاورید، حال خروجی گزارش را ببینید، جمع در انتهای هر صفحه ظاهر میشود.

متغیرها :

در این گزارش ساز دو نوع متغیر وجود دارد؛ نرمال و سیستمی. نوع سیستمی شامل متغیرهایی میشود که کاربرد مشخصی در تهیه گزارش دارند، مثل شماره صفحه، شماره ردیف، عنوان گزارش و ...

برای مثال شما میتوانید متغیر سیستمی Line را برای روی صفحه طراحی دراگ کنید. دو کامپوننت Text بر روی صفحه ایجاد میشود. اولی با محتوای Line و دومی با محتوای {Line}. اولی را به بند Header و دومی را به بند Data منتقل کنید و سپس خروجی گزارش را مشاهده نمایید، حال گزارش شما دارای شماره ردیف است.

متغیرهای نرمال تقریبا همانند متغیرهایی هستند که همه روزه شما در برنامه‌های خود از آنها استفاده می‌کنید. با کلیک بر روی New Item گزینه New Variable را انتخاب نمایید و نوع متغیر را Decimal انتخاب نمایید، سپس متغیر ایجاد شده را دراگ کرده و بروی صفحه طراحی قرار دهید و مشابه متغیر Line عمل کرده و کامپوننتهای Text را در بندهای مناسب قرار دهید. سپس بند Data بر روی صفحه طراحی را انتخاب نمایید، در پنل Properties بر روی Eventes کلیک کرده سپس در رویداد Rendering کد زیر را وارد نمایید.

Variable1 += Products.UnitPrice

حال در خروجی گزارش میتوانید مقادیر محاسبه شده را ببینید. توجه داشته باشید که شما میتوانید در رویدادهای این گزارش‌ساز به زبان VB و C# برنامه نویسی کنید و محدود به یک خط کد نمی‌باشید.

شما میتوانید گزارش ساخته شده را به صورتهای مختلف ذخیره کنید از جمله کد C# و یا یک اپلیکیشن قابل اجرا. 

Report.mrt 

نظرات مطالب
Blazor 5x - قسمت 27 - برنامه‌ی Blazor WASM - کار با سرویس‌های Web API
من از روش اول استفاده می‌کنم. تنظیم visual studio  برای جرای همزمان دو پروژه. یک نکته مهم رو که گفتید وقتی پورت کلاینت رو مساوی sslport سمت web api قرار می‌دم یعنی در launchSetting مربوط به کلاینت "http://localhost:44349"  را تغییر دادم و 44349 رو برابر sslport سمت سرور قرار دادم.در این حالت کلا iis express v رو نمی‌تونه بالا بیاره و فقط قسمت سرور میاد بالا . بنابراین این کارو انجام نمی‌دم و در اون صورت an unhandles error می‌گیرم در خطی که getfromjsonasync اجرا میشه خطا می‌گیرم . an unhandled error.
از روش دوم هم که استفاده می‌کنم باز همین طور است. یو آر ال https://localhost:5002/api/hotelroom?checkInDate=2021-06-25&checkOutDate=2021-06-26  درست می‌شود و an unhandled error بر می‌گرداند.   
مطالب
استفاده از اسمبلی‌های دات نت 2 در یک پروژه دات نت 4

تنظیمات برنامه BloggerToChm را به دات نت 4 تغییر دادم و بدون مشکل کامپایل شد. اما حین اجرا بلافاصله با خطای زیر برنامه اجرا نمی‌شد:

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
مشکل هم از اسمبلی‌های مرتبط با SQLite است که هنوز برای دات نت 4 کامپایل نشده‌اند. برای رفع این مشکل باید تغییر زیر را (تنظیم گزینه useLegacyV2RuntimeActivationPolicy) به فایل app.config برنامه اضافه کرد:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
</configuration>
برای برنامه‌های ASP.NET نیز به همین صورت است. در آنجا این تغییرات باید به Web.Config اضافه شوند.

مطالب
معرفی قالب پروژه Web API مبتنی‌بر ASP.NET Core Web API و زیرساخت DNTFrameworkCore
بعد از انتشار نسخه اولیه زیرساخت DNTFrameworkCore، در این مطلب قصد دارم قالب تهیه شده برپایه زیرساخت مذکور را معرفی کنم. در این قالب سیستم اعتبارسنجی کاربران مبتنی‌برJWT نیز تدارک دیده شده است.
‌‌‌

نصب قالب پروژه از طریق نیوگت


ابتدا برای نصب قالب تهیه شده از طریق نیوگت، دستور زیر را اجرا کنید:
dotnet new --install DNTFrameworkCoreTemplateAPI::*‌‌
‌‌
حال برای ایجاد اولین پروژه، دستور زیر را اجرا کنید:
dotnet new dntcore-api
‌‌
بعد از اجرای دستور بالا، ساختاری مشابه شکل زیر در اختیار شما می‌باشد:


بررسی قسمت‌های مختلف قالب پروژه

1- پروژه Domain دربرگیرنده Domain Model سیستم می‌باشد؛ تفاوتی ندارد Rich Domain Model یا Anemic Domain Model باشد. به عنوان مثال، به صورت پیش‌فرض موجودیت‎‌های مرتبط سیستم احراز هویت و کنترل دسترسی در این قالب طراحی شده‌اند.


2- پروژه Infrastructure دربرگیرنده DbContext، مهاجرت‌ها و کلاس‌های تنظیمات نگاشت موجودیت‌ها به جداول بانک اطلاعاتی پروژه می‌باشد. به عنوان مثال، به صورت پیش‌فرض تنظیمات نگاشت موجودیت‌های کاربر و گروه‌کاربری و موجودیت‌های وابسته آنها در این قالب پیاده‌سازی شده‌اند. همچنین دو مهاجرت CreateInitialSchema و CreateIdentitySchema ایجاده شده‌اند.



3- پروژه Application دربرگیرنده مدل‌ها/DTOها‎‌، اعتبارسنج‌های مدل‌ها، سرویس‌ها و همچنین Eventهای سفارشی و Handlerهای رویدادهای متناظر با موجودیت‌های سیستم، می‌باشد. همانطور که شکل زیر ملاحظه می‌کنید، برای موجودیت‌های کاربر و گروه‌کاربری طراحی و پیاده‌سازی پیش‌فرضی از قسمت‌های مذکور ارائه شده است.


4- پروژه Resouces دربرگیرنده فایل‌های منبع resx می‌باشد و همچنین به صورت پیش‌فرض بحث انتقال منابع به یک اسمبلی جداگانه نیز اعمال شده است.


5- از پروژه Common نیز می‌توان به عنوان دربرگیرنده کلاس‌های کمکی مورد استفاده در سایر قسمت‌ها، بهره برد.

6- پروژه UnitTests دربرگیرده آزمون‌های واحد پروژه می‌باشد. به عنوان مثال، به صورت پیش‌فرض آزمون‌های واحد مرتبط با UserValidator و RoleValidator به صورت کامل در این قالب تدارک دیده شده است.

7- پروژه IntegrationTests دربرگیرنده آزمون‌های جامعیت مرتبط با پروژه می‌باشد. به عنوان مثال، آزمون‌های جامعیت متناظر با سرویس‌های کاربر و گروه‌کاربری نیز در این قالب تدارک دیده شده است.

نکته: بدلیل اینکه مکانیزم اعتبارسنجی خودکار ورودی‌ها به عنوان یک Aspect برروی این سرویس‌ها اعمال شده است و بدین ترتیب در فرآیند تست سرویس‌ها نیز دخالت دارند، به صورت ناخواسته به سمت آزمون جامعیت سوق پیدا کرده‌ایم. با این حال اگر برای لایه بالاتر/خارجی پروژه خود یا همان API در قالب، قصد تهیه آزمون جامعیت داشته باشید، می‌توانید این تنظیمات ValidationInterceptor را از فایل ApplicationRegistry در پروژه Application حذف کرده و آزمون‌های سرویس‌ها را در قالب آزمون واحد انجام دهید. با این حال باید توجه کنید که برای برخی از سناریوها که امکانات هیچ کدام از مهیاکننده‌های InMemory و SQLite درون حافظه، جوابگوی نیاز شما نباشد، نیاز خواهید داشت تا از بانک اطلاعاتی واقعی از جمله LocalDb استفاده کنید؛ در این صورت آزمون‌های شما نیز در ردیف آزمون‌های جامعیت قرار خواهند داشت. 


8- پروژه API دربرگیرنده کنترلرها، هاب‌های SignalR،  زیرساخت Authentication مبتنی‌بر JWT و سایر تنظیمات آغازین پروژه، می‌باشد. CRUD API متناظر با موجودیت‌های کاربر و گروه‌کاربری نیز در این قالب تدارک دیده شده است.


کدهای کامل این قسمت را می‌توانید از اینجا دریافت کنید. 

مطالب
انتخاب layoutهای متفاوت در برنامه‌های Angular
شاید برای شما هم پیش آمده باشد که در یک برنامه‌ی Angular بخواهید layoutهای مختلفی داشته باشید؛ مثلا هنگام لاگین، طبق عرف کار باید هدر و فوتر صفحه از بین بروند و فقط فرم لاگین نمایش داده شود و یا بخواهید هنگام لاگین، یک layout مخصوص پنل مدیریتی داشته باشید و یا …

قبل از شروع، فرض را بر آن می‌گیریم که حداقل نیاز‌های یک پروژه‌ی Angular را آماده کرده اید. سپس یک پوشه‌ی جدید را به نام layout می‌سازیم و layout‌های مربوطه را در آن ایجاد میکنیم. با دستور زیر یک کامپوننت جدید را که layout ما خواهد شد، با نام دلخواهی ایجاد می‌کنیم:
ng g c Loginlayout
 و همچنین یک کامپوننت دیگر را برای صفحه‌ی اصلی به نام homelayout می‌سازیم:
ng g c homelayout

در ادامه Loginlayout را باز کرده و تنظیمات زیر را لحاظ کنید:
<div style="width: 100%;height: 250px;background-color: aquamarine">
   <h1>Header</h1>
</div>

<router-outlet></router-outlet>

<div style="width: 100%;height: 250px;background-color: brown">
  <h1>Foother</h1>
</div>
در اینجا یک هدر و یک فوتر را ساخته و <router-outlet></router-outlet> را در آن قرار می‌دهیم که قسمت پویای ما خواهد شد.

اکنون وارد کامپوننت home layout شوید و دقیقا مانند قبل، تنظیمات دلخواه خود را انجام داده و همچنین <router-outlet></router-outlet> راهم درون جائیکه می‌خواهید به صورت پویا باشد بگذارید.
تا اینجا ما فقط layoutها را طراحی کردیم. در ادامه در ریشه‌ی پروژه، سه کامپوننت را به نام‌های Home , Login, About میسازیم. Home و About دارای یک قالب و Login هم داری قالب مخصوص به خود میباشد.

سپس وارد کامپوننت آغازین برنامه (app.component.html) شوید و در آن <router-outlet></router-outlet> را وارد کنید. در اینجا دیگر نیازی به نوشتن تگ‌های خاص دیگری نیست.

در ادامه به اصلی‌ترین قسمت، یعنی مسیریابی می‌رسیم. وارد app.module.ts شوید و آن را به صورت زیر تنظیم کنید:
export const routes: Routes = [    
           { 
                path: 'Loginlayout', 
                component: LoginlayoutComponent ,
                children: [
                  { path: 'Login', component: LoginComponent, pathMatch: 'full'}                 
                ]
            },
            { 
                path: 'Homelayout', 
                component: HomelayoutComponent,
                children: [
                  { path: 'About', component: AbouComponent, pathMatch: 'full'},
                  { path: 'Home', component: HomeComponent, pathMatch: 'full'}
                ]
            }          
];
همانطورکه ملاحظه می‌کنید، مسیریابی بالا شامل مسیریابی‌های تو در تویی است. در اینجا کامپوننت‌های Home و About درون HomelayoutComponent بارگذاری می‌شوند و خود HomelayoutComponent  نیز درون app.component.
همچنین برای اینکه مشخص شود کدام کامپوننت به عنوان کامپوننت پیشفرض نمایش داده شود، به صورت زیر عمل میکنیم:
path: '', 
component: HomelayoutComponent,
children: [
  { path: '', component:HomeComponent, pathMatch: 'full'}         
]
به  این روش میتوانید هر تعداد layout ایی را که میخواهید، ایجاد کنید.

کدهای کامل این مطلب را می‌توانید از اینجا دریافت و یا به صورت آنی آزمایش کنید.
نظرات مطالب
BloggerToCHM
سلام،
برنامه زمانیکه فایل chm رو درست کرد سعی میکنه اون رو نمایش بده. این فایل chm داخل یک فولدر کنار فایل exe درست میشه. لطفا بررسی کنید آیا فایل موجود است و درست شده و همچنین این مسیر به چه صورتی است؟
مثلا فاصله دارد یا از حروف فارسی درست شده یا ...؟
مطالب
ساختن code snippet ( قطعه کد ) در ویژوال استودیو 2010
ویژوال استودیو به توسعه دهندگان این امکان را می‌دهد تا کدهایی را که تکراری بوده و به  دفعات در متن برنامه مورد استفاده هستند به شکل یک قطعه کد آماده (در صورت نیاز با مقادیر پیش فرض ) ذخیره کنند ، سپس در مواقع نیاز بدون اینکه مجبور باشند آن را دوباره و دوباره بنویسند ، تنها با تایپ کردن نام قطعه کد ذخیره شده  و دو بار فشردن  کلید Tab ، کد  تعریف شده توسط ویژوال استودیو  در محل تعیین شده اضافه می‌گردد. به این  قطعه کدهای آماده code snippet گفته می‌شود .
خود ویژوال استودیو تعدادی code snippet آماده  دارد که آشنایی با آنها می‌تواند سرعت کدنویسی را افزایش دهد . برای دیدن لیست کامل و مدیریت آنها به مسیر

Tools -> Code Snippets Manager (Ctrl+K,Ctrl+B)
بروید .

در ویژوال استودیو 2010 دو نوع snippet وجود دارد :

 1- Expansion snippets : که در محل کرسر (Cursor) اضافه می‌شوند . مثل cw و enum که به ترتیب دستور writeLine و ساختار یک enum را ایجاد می‌کنند .

 2- SurroundsWith snippets : که  می‌توانند یک تکه کد انتخاب شده را در بر بگیرند مثل for و یا do که کد انتخاب شده را در یک حلقه for و do-while محصور می‌کنند  .

نکته ای که باید توجه داشت این است که یک snippet می‌تواند از هر دو نوع باشد . برای مثال  for و do و یا if ، در صورتی که  کدی انتخاب شده باشد آن را محصور می‌کنند و گرنه  ساختار خالی مرتبط را در محل cursor اضافه می‌کنند .

همانطور که در ابتدا هم ذکر شد ، علاوه بر snippet‌های آماده‌ی موجود ، توسعه دهنده می‌تواند قطعه کدهایی را خود ایجاد کرده و مورد استفاده قرار دهد .

در اینجا یک expansion snippet  خواهیم ساخت تا  کار اضافه کردن بلاک try-catch-finally  را برای ما انجام دهد .

- ابتدا یک فایل xml به پروژه اضافه می‌کنیم و آنرا TryCatchFinally.snippet می‌نامیم . توجه کنید که نام فایل باید به .snippet ختم شود .

- فایل را باز  و درون آن راست کلیک کرده و گزینه Insert snippet > Snippet را انتخاب می‌کنیم . با اینکار یک قالب پایه snippet ( که یک ساختار xml ) است به فایل اضافه می‌شود .  هر فایل snippet از دو بخش اصلی header و  snippet تشکیل شده که بخش header اطلاعاتی کلی درباره قطعه کد را نگهداری می‌کند و بخش snippet مربوط به تعریف محتوای قطعه کد است .

<codesnippet format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <header>
    <title>title</title>
    <author>author</author>
    <shortcut>shortcut</shortcut>
    <description>description</description>
    <snippettypes>
      <snippettype>SurroundsWith</snippettype>
      <snippettype>Expansion</snippettype>
    </snippettypes>
  </header>
  <snippet>
    <declarations>
      <literal>
        <id>name</id>
        <default>value</default>
      </literal>
    </declarations>
    <code language="XML">
      <!--[CDATA[<test-->
      <name>$name$</name>
      $selected$ $end$]]>
    </code>
  </snippet>
</codesnippet>
 

- قالب پیش فرض شامل هر دو نوع snippet است .


<codesnippet format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <header>
...
    <snippettypes>
      <snippettype>SurroundsWith</snippettype>
      <snippettype>Expansion</snippettype>
    </snippettypes>
  </header>
...
</codesnippet>

از آنجا که قصد داریم یک Expansion snippet بسازیم پس تگ SurroundsWith را حذف می‌کنیم . 


    <snippettypes>
      <snippettype>Expansion</snippettype>
    </snippettypes>

- در بخش header مقدار تگ Title را به “Try Catch Finally”و  مقدار تگ Shortcut را به “trycf” و Description را به “Adds a try-catch-finally block ” تغییر می‌دهیم . Title عنوان snippet است و وجود آن ضروری است . اضافه کردن shortcut  اختیاری است  و به عنوان یک متن میانبر برای اضافه کردن snippet استفاده می‌شود .


    <Header>
      <Title>Try Catch Finally</Title>
      <Author>mohsen.d</Author>
      <Shortcut>trycf</Shortcut>
      <Description>Adds a try-catch-finally block</Description>

- تگ Literal برای تعریف جایگزین برای  بخشی از کد  درون snippet  که احتمال دارد پس از اضافه شدن ، توسط  برنامه نویس و یا در صورت استفاده از  function توسط خود ویژوال استودیو تغییر کند استفاده می‌شود . در قطعه کد try-catch-finally ، ما می‌خواهیم به کاربر اجازه بدهیم که نوع استثنائی را که catch می‌شود تغییر دهد .
تگ id نامی برای بخش قابل ویرایش تعریف می‌کند ( که از آن در  ادامه در تعریف خود قطعه کد استفاده می‌کنیم ) . آنرا به “ExceptionName” تغییر می‌دهیم . تگ default هم مقدار پیش فرضی را  برای آن بخش مشخص می‌کند . ما می‌خواهیم تمام استثناها را Catch کنیم پس مقدار پیش فرض را برابر "Exception" قرار می‌دهیم .


.....
    <declarations>
      <literal>
        <id>ExceptionName</id>
        <default>Exception</default>
      </literal>
    </declarations>
...

- و در تگ Code ، خود قطعه کدی که ویژوال استودیو باید آن را اضافه کند ، تعریف می‌شود . مقدار مشخصه Language آن را به CSharp تغییر می‌دهیم و محتویات داخل آنرا به شکل زیر اضافه می‌کنیم . 


<code language="CSharp">
<!--[CDATA[
try
{
    $end$
}
catch($ExceptionName$)
{
  
}
finally
{
  
}
      ]]-->
</code>

به نحوه استفاده از ExceptionName که در قسمت Literal تعریف کردیم توجه کنید  . عبارت $end$ هم یک کلمه رزرو شده است که محل قرار گرفتن cursor را بعد از اضافه شدن قطعه کد مشخص می‌کند .

- در نهایت snippet ما به شکل زیر خواهد بود : 


<codesnippet format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <header>
    <title>Try Catch Finally</title>
    <author>mohsen.d</author>
    <shortcut>trycf</shortcut>
    <description>Adds a try-catch-finally block</description>
    <snippettypes>
      <snippettype>Expansion</snippettype>
    </snippettypes>
  </header>
  <snippet>
    <declarations>
      <literal>
        <id>ExceptionName</id>
        <default>Exception</default>
      </literal>
    </declarations>
    <code language="CSharp">
      <!--[CDATA[
try
{
    $end$
}
catch($ExceptionName$)
{
  
}
finally
{
  
}
      ]]-->
    </code>
  </snippet>
</codesnippet>

اضافه کردن snippet ساخته شده به visual studio


دو راه برای اضافه کردن snippet تعریف شده به ویژوال استودیو وجود دارد :
روش اول قرار دادن فایل .snippet در پوشه code snippets ویژوال استودیو است که مسیر پیش فرض آن 

C:\Users\<UserName>\Documents\Visual Studio 2010\Code Snippets\
است . این پوشه به ازای هر زبان دارای یک زیر پوشه است . این snippet را باید در پوشه C# قرار دهیم . همین که فایل را در پوشه مناسب قرار دهیم ویژوال استودیو بدون نیاز به restart شدن آن را خواهد شناخت .

گزینه دوم import کردن فایل .snippet به داخل ویژوال استودیو است . در ویژوال استودیو به مسیر

Tools -> Code Snippets Manager (Ctrl+K,Ctrl+B)
می‌رویم . در پنجره Code Snippets Manager ، بر روی کلید import کلیک و فایل موردنظر را یافته و انتخاب کرده و پوشه‌ی محل ذخیره شدن آن را تعیین می‌کنیم .

استفاده از snippet ساخته شده

برای استفاده از snippet می‌توانیم متن میانبر تعریف شده را تایپ کنیم و با دو بار فشردن کلید tab قطعه کد تعریف شده به محل کرسر اضافه می‌شود 



همینطور با فشردن کلیدهای Ctrl+K و Ctrl+X  به صورت پشت سر هم منوی “Insert Snippet” ظاهر می‌شود که از طریق آن می‌توانیم Snippet موردنظر را یافته  ( بدنبال Title تعریف شده برای snippet  در پوشه ای که آنرا ذخیره کرده اید بگردید ) و با انتخاب آن کد تعریف شده اضافه خواهد شد .



 برای آشنایی با روش‌های مختلف دسترسی به snippet‌ها اینجا را بررسی کنید .

ابزارها

دستکاری خود فایل xml چندان جالب و خالی از خطا نیست . روش‌های بهتری برای ساخت و ویرایش snippet‌ها وجود دارد . Snippet Editor ابزاری برای ویرایش و ساخت snippet هاست و Snippet Designer هم یک پلاگین برای ویژوال استودیوست که کار مشابهی را انجام می‌دهد . یکی از کارهای جالبی که با این ابزار می‌توانید انجام دهید انتخاب یک قطعه از کد ( مثل یک تابع ) و سپس ساختن یک snippet از روی آن است .

در این پروژه هم مجموعه snippet‌های موجود ویژوال استودیو 2010 برای زبان سی شارپ ، جهت سازگاری با stylecop ویرایش و refactor شده اند ( در کنار تعریف snippet‌های دیگر ).
نظرات مطالب
فشرده سازی فایل ها در NET 4.5.
نکته تکمیلی : در صورتی که ZipFile را در فضای نام System.IO.Compression مشاهده نکردید؛ اسمبلی System.IO.Compression.FileSystem.dll  را به قسمت رفرنس اضافه کنید