مطالب
مدیریت هماهنگ شماره نگارش اسمبلی در چندین پروژه‌ی ویژوال استودیو
عموما برای نگهداری ساده‌تر قسمت‌های مختلف یک پروژه، اجزای آن به اسمبلی‌های مختلفی تقسیم می‌شوند که هر کدام در یک پروژه‌ی مجزای ویژوال استودیو قرار خواهند گرفت. یکی از نیازهای مهم این نوع پروژه‌ها، داشتن شماره نگارش یکسانی بین اسمبلی‌های آن است. به این ترتیب توزیع نهایی ساده‌تر شده و همچنین پشتیبانی از آن‌ها در دراز مدت، بر اساس این شماره نگارش بهتر صورت خواهد گرفت. برای مثال در لاگ‌های خطای برنامه با بررسی شماره نگارش اسمبلی مرتبط، حداقل می‌توان متوجه شد که آیا کاربر از آخرین نسخه‌ی برنامه استفاده می‌کند یا خیر.
روش معمول انجام این‌کار، به روز رسانی دستی تمام فایل‌های AssemblyInfo.cs یک Solution است و همچنین اطمینان حاصل کردن از همگام بودن آن‌ها. در ادامه قصد داریم با استفاده از فایل‌های T4، یک فایل SharedAssemblyInfo.tt را جهت تولید اطلاعات مشترک Build بین اسمبلی‌های مختلف یک پروژه، تولید کنیم.


ایجاد پروژه‌ی SharedMetaData

برای نگهداری فایل مشترک SharedAssemblyInfo.cs نهایی و همچنین اطمینان از تولید مجدد آن به ازای هر Build، یک پروژه‌ی class library جدید را به نام SharedMetaData به Solution جاری اضافه کنید.



سپس نیاز است یک فایل text template جدید را به نام SharedAssemblyInfo.tt، به این پروژه اضافه کنید.


به خواص فایل SharedAssemblyInfo.tt مراجعه کرده و Transform on build آن‌را true کنید. به این ترتیب مطمئن خواهیم شد این فایل به ازای هر build جدید، مجددا تولید می‌گردد.



اکنون محتوای این فایل را به نحو ذیل تغییر دهید:
 <#@ template debug="false" hostspecific="false" language="C#" #>
//
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
//
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyCompany("some name")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguageAttribute("en")]

[assembly: AssemblyProduct("product name")]
[assembly: AssemblyCopyright("Copyright VahidN 2014")]
[assembly: AssemblyTrademark("some name")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

// Assembly Versions are incremented manually when branching the code for a release.
[assembly: AssemblyVersion("<#= this.MajorVersion #>.<#= this.MinorVersion #>.<#= this.BuildNumber #>.<#= this.RevisionNumber #>")]
// Assembly File Version should be incremented automatically as part of the build process.
[assembly: AssemblyFileVersion("<#= this.MajorVersion #>.<#= this.MinorVersion #>.<#= this.BuildNumber #>.<#= this.RevisionNumber #>")]

<#+
// Manually incremented for major releases, such as adding many new features to the solution or introducing breaking changes.
int MajorVersion = 1;
// Manually incremented for minor releases, such as introducing small changes to existing features or adding new features.
int MinorVersion = 0;
// Typically incremented automatically as part of every build performed on the Build Server.
int BuildNumber = (int)(DateTime.UtcNow - new DateTime(2013,1,1)).TotalDays;
// Incremented for QFEs (a.k.a. “hotfixes” or patches) to builds released into the Production environment.
// This is set to zero for the initial release of any major/minor version of the solution.
int RevisionNumber = 0;
#>
در این فایل اجزای شماره نگارش برنامه به صورت متغیر تعریف شده‌اند. هر بار که نیاز است یک نگارش جدید ارائه شود، می‌توان این اعداد را تغییر داد.
MajorVersion با افزودن تعداد زیادی قابلیت به برنامه، به صورت دستی تغییر می‌کند. همچنین اگر یک breaking change در برنامه یا کتابخانه وجود داشته باشد نیز این شماره باید تغییر نماید.
MinorVersion با افزودن ویژگی‌های کوچکی به نگارش فعلی برنامه تغییر می‌کند.
BuildNumber به صورت خودکار بر اساس هر Build انجام شده باید تغییر یابد. در اینجا این عدد به صورت خودکار به ازای هر روز، یک واحد افزایش پیدا می‌کند. ابتدای مبداء آن در این مثال، 2013 قرار گرفته‌است.
RevisionNumber با ارائه یک وصله جدید برای نگارش فعلی برنامه، به صورت دستی باید تغییر کند. اگر اعداد شماره نگارش major یا minor تغییر کنند، این عدد باید به صفر تنظیم شود.

اکنون اگر این محتوای جدید را ذخیره کنید، فایل SharedAssemblyInfo.cs به صورت خودکار تولید خواهد شد.


افزودن فایل SharedAssemblyInfo.cs به صورت لینک به تمام پروژه‌ها

نحوه‌ی افزودن فایل جدید SharedAssemblyInfo.cs به پروژه‌های موجود، اندکی متفاوت است با روش معمول افزودن فایل‌های cs هر پروژه. ابتدا از منوی پروژه گزینه‌ی add existing item را انتخاب کنید. سپس فایل  SharedAssemblyInfo.cs را یافته و به صورت add as link، به تمام پروژه‌های موجود اضافه کنید.


اینکار باید در مورد تمام پروژه‌ها صورت گیرد. به این ترتیب چون فایل SharedAssemblyInfo.cs به این پروژه‌ها صرفا لینک شده‌است، اگر محتوای آن در پروژه‌ی metadata تغییر کند، به صورت خودکار و یک دست، در تمام پروژه‌های دیگر نیز منعکس خواهد شد.

در ادامه اگر بخواهید Solution را Build کنید، پیام تکراری بودن یک سری از ویژگی‌ها را یافت خواهید کرد. این مورد از این جهت رخ می‌دهد که هنوز فایل‌های AssemblyInfo.cs اصلی، در پروژه‌های برنامه موجود هستند.
این فایل‌ها را یافته و صرفا چند سطر همیشه ثابت ذیل را در آن‌ها باقی بگذارید:
 using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("title")]
[assembly: AssemblyDescription("")]
[assembly: ComVisible(false)]
[assembly: Guid("9cde6054-dd73-42d5-a859-7d4b6dc9b596")]


اضافه کردن build dependency  به پروژه  MetaData

در پایان کار نیاز است اطمینان حاصل کنیم، فایل SharedAssemblyInfo.cs به صورت خودکار پیش از Build هر پروژه، تولید می‌شود. برای این منظور، از منوی Project، گزینه‌ی Project dependencies را انتخاب کنید. سپس در برگه‌ی dependencies آن، به ازای تمام پروژه‌های موجود، گزینه‌ی SharedMetadata را انتخاب نمائید.


این مساله سبب اجرای خودکار فایل SharedAssemblyInfo.tt پیش از هر Build می‌شود و به این ترتیب می‌توان از تازه بودن اطلاعات SharedAssemblyInfo.cs اطمینان حاصل کرد.
اکنون اگر پروژه را Build کنید، تمام اجزای آن شماره نگارش یکسانی را خواهند داشت:

و در دفعات آتی، تنها نیاز است تک فایل SharedAssemblyInfo.tt را برای تغییر شماره نگارش‌های اصلی، ویرایش کرد.
اشتراک‌ها
امکانات جدید GIT 2.7

A quick two months after 2.6, Git 2.7 has been released with a plethora of features, fixes and performance improvements. Here's some of the new stuff we found interesting on the Bitbucket team. 

امکانات جدید GIT 2.7
مطالب
Garbage Collector در #C - قسمت سوم
در قسمت قبلی درباره تفاوت‌های Stack و Heap، صحبت کرده و به این نتیجه رسیدیم که برای آزادسازی حافظه Heap، در صورتی‌که نخواهیم اینکار را بصورت دستی انجام دهیم، نیاز به Garbage Collector پیدا خواهیم کرد.


تاریخچه‌ای مختصر از GC در NET.

ایده اولیه ایجاد Garbage Collector در NET.، در سال 1990 بود که در آن زمان، مایکروسافت مشغول پیاده سازی خود از JavaScript بنام JScript بود. در ابتدا JScript توسط تیمی چهار نفره توسعه داده میشد و در آن زمان یکی از اعضای این تیم به نام Patrick Dussud که بعنوان پدر Garbage Collector در NET. شناخته میشود، یک Conservative GC را داخل تیم توسعه داد. در آن زمان CLR ای وجود نداشت و Patrick Dussud برروی JVM کار میکرد.

مایکروسافت سعی بر پیاده سازی نسخه‌ای اختصاصی از JVM را برای خود بجای ایجاد چیزی شبیه به NET Runtime. فعلی داشت؛ اما بعد از شکل گیری تیم CLR، به این نتیجه رسیدند که JVM برای آنها محدودیت‌هایی را ایجاد میکند و به همین دلیل شروع به ایجاد Environment خود کردند.

با این تصمیم، Patrick Dussud مجددا یک GC جدید را با ایده "بهترین GC ممکن" با زبان LISP که در آن بیشترین مهارت را داشت، بصورت Prototype نوشت و سپس یک Transpiler از LISP را به ++C نوشت که کدهای آن قابل استفاده در Runtime مایکروسافت باشد.

کدهای فعلی مربوط به Garbage Collector مورد استفاده در NET. در این فایل از ریپازیتوری runtime مایکروسافت قابل دسترسی هستند. در حال حاضر خانم Maoni Stephens مدیر فنی تیم GC مایکروسافت هستند که کنفرانس‌ها و مقالات زیادی نیز درباره نکات مختلف پیاده سازی GC در بلاگ خود نوشته و ارائه کرده‌اند.


در حال حاضر، سه حالت (flavor) از GC در NET. تعبیه شده‌است و هرکدام از این حالات برای انواع مختلفی از برنامه‌ها بهینه شده‌است که در ادامه به بررسی آنها میپردازیم.


Server GC

این نوع GC برای برنامه‌های سمت سرور نظیر ASP.NET Core و WCF بهینه سازی شده‌است که تعداد ریکوئست‌های زیادی به آنها وارد میشود و هر ریکوئست باعث allocate شدن اشیا مختلفی شده و بطور کلی، نرخ allocation و deallocation در آنها بالاست.

Server GC به ازای هر پردازنده، از یک Heap و یک GC Thread مجزا استفاده میکند. این بدین معناست که اگر شما یک پردازنده را با هشت Core داشته باشید، در زمان Garbage Collection، روی هرکدام از Coreها یک Heap و GC Thread مستقل وجود دارد که عمل Garbage Collection را انجام میدهند.

این شکل عملکرد باعث میشود که Collection، در سریعترین زمان ممکن، بدون وقفه اضافه انجام شود و برنامه شما اصطلاحا ((Freeze)) نشود.

Server GC فقط روی پردازنده‌های چند هسته‌ای قابل اجراست و اگر سعی کنید برنامه خود را روی یک سیستم با پردازنده تک هسته‌ای در حالت Server GC اجرا کنید، بصورت خودکار برنامه شما از Non-Concurrent Workstation GC استفاده کرده و اصطلاحا Fallback خواهد شد.

اگر نیاز دارید که در برنامه‌هایی به‌غیر از Server-Side Applicationها، نظیر WPF و Windows Service‌ها و ... از این نوع GC استفاده کنید (به شرط چند هسته بودن پردازنده)، میتوانید این تنظیمات را به فایل app.config یا web.config خود اضافه کنید:
<configuration>
  <runtime>
    <gcServer enabled="true"/>
  </runtime>
</configuration>

همچنین در برنامه‌های NET Core.ای نیز میتوانید این تنظیمات را داخل فایل csproj. برنامه خود اضافه کنید:
<PropertyGroup>
  <ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>


Concurrent Workstation GC


این حالت، حالت پیشفرض مورد استفاده در برنامه‌های Windows Forms و Windows Service است. این حالت از GC برای برنامه‌هایی بهینه شده‌است که در آنها، هنگام وقوع Garbage Collection، برنامه توقف و مکث حتی چند لحظه‌ای نداشته و Collection باعث نشود که کاربر نتواند روی یک دکمه کلیک کند و اصطلاحا برنامه ((Unresponsive)) شود.

برای فعالسازی Concurrent Workstation GC این تنظیمات را داخل config برنامه خود باید اعمال کنید:
<configuration>
  <runtime>
    <gcConcurrent enabled="true" />
  </runtime>
</configuration>


Non-Concurrent Workstation GC


این حالت شبیه به حالت Server GC است؛ با این تفاوت که عمل Collection روی Thread ای که درخواست allocate کردن یک object را کرده است، صورت میگیرد.

برای مثال:

  • Thread شماره یک درخواست allocate کردن یک string با طول 10000 کاراکتر را میدهد.
  • حافظه، فضای کافی برای تخصیص این حجم از حافظه را نداشته و سعی میکند با اجرای Garbage Collector، این حجم فضای مورد نیاز از حافظه را خالی کند.
  • CLR تمام Thread‌های برنامه را متوقف میکند و Garbage Collector شروع به کار کرده و اشیا بلااستفاده «روی Thread ای که آن را فراخوانی کرده است» را Collect میکند.
  • بعد از پایان Collection، تمامی Threadهای برنامه که در مرحله قبل متوقف شده بودند، مجددا شروع به کار خواهند کرد.


این حالت از GC برای برنامه‌های Server-Side ای که برروی پردازنده تک هسته‌ای اجرا میشوند، پیشنهاد میشود. برای فعالسازی این حالت، تنظیمات داخل config برنامه به این صورت باید تغییر پیدا کند:
<configuration>
  <runtime>
    <gcConcurrent enabled="false" />
  </runtime>
</configuration>



این جدول، کمک خواهد کرد که بر اساس نوع برنامه خود، تنظیمات درستی را برای GC اعمال نمایید (در اکثر موارد، تنظیمات پیشفرض بهترین انتخاب بوده و نیازی به تغییر روند کار GC نیست):

 Server GC  Non-Concurrent Workstation  Concurrent Workstation  
 Maximize throughput on multi-processor machines for server apps that create multiple threads to handle the same types of requests.  Maximize throughput on single-processor machines.  Balance throughput and responsiveness for client apps with UI. Design Goal 
1 per processor ( hyper thread aware )  1  Number of Heaps
 1 dedicated GC thread per processor The thread which performs the allocation that triggers the GC. The thread which performs the allocation that triggers the GC.  GC Threads
 EE is suspended during a GC. EE is suspended during a GC. EE is suspended much shorter but several times during a GC.  Execution Engine
Suspension
<gcServer enabled="true">
<gcConcurrent enabled="false">
 <gcConcurrent enabled="true"> 
 Config Setting
Non-Concurrent Workstation GC      On a single
processor
(fallback)
اشتراک‌ها
ارسال ایمیل در برنامه های ASP.NET MVC

This article takes a comprehensive look at the business of generating and sending email from an ASP.NET MVC application. It covers the most common use cases as well as some advanced scenarios. It also explores some of the more common errors that arise from attempting to generate and send email programmatically from an ASP.NET MVC site. 

ارسال ایمیل در برنامه های ASP.NET MVC
اشتراک‌ها
نکاتی در رابطه با ویژگی‌های جدید C# 7.0

C# 7 is a major update with a lot of interesting new capabilities. And while there are plenty of articles on what you can do with it, there aren't quite as many on what you should do with it. Using the principles found in the .NET Framework Design Guidelines, we're going to take a first pass at laying down strategies for getting the most from these new features. 

نکاتی در رابطه با ویژگی‌های جدید C# 7.0
اشتراک‌ها
مقایسه‌ای بین Mapperly و AutoMapper
There is a better alternative — a mapping library based on source generators And the name of this library is Mapperly ( https://github.com/riok/mapperly)
This library solves the problems of AutoMapper and doesn’t exclude the use of manual mapping if you really want to :)
مقایسه‌ای بین Mapperly و AutoMapper
اشتراک‌ها
کتابخانه unitegallery

The Unite Gallery is multipurpose javascript gallery based on jquery library. It's built with a modular technique with a lot of accent of ease of use and customization. It's very easy to customize the gallery, changing it's skin via css, and even writing your own theme. Yet this gallery is very powerfull, fast and has the most of nowdays must have features like responsiveness, touch enabled and even zoom feature, it's unique effect.  Demo

Features

  • The gallery plays VIDEO from: Youtube, Vimeo, HTML5, Wistia and SoundCloud (not a video but still )
  • Responsive - fits to every screen with automatic ratio preserve
  • Touch Enabled - Every gallery parts can be controlled by the touch on touch enabled devices
  • Responsive - The gallery can fit every screen size, and can respond to a screen size change.
  • Skinnable - Allow to change skin with ease in different css file without touching main gallery css.
  • Themable - The gallery has various of themes, each theme has it's own options and features, but it uses gallery core objects
  • Zoom Effect - The gallery has unique zoom effect that could be applied within buttons, mouse wheel or pinch gesture on touch - enabled devices
  • Gallery Buttons - The gallery has buttons on it, like full screen or play/pause that optimized for touch devidces access
  • Keyboard controls - The gallery could be controlled by keyboard (left, right arrows)
  • Tons of options. The gallery has huge amount of options for every gallery object that make the customization process easy and fun.
  • Powerfull API - using the gallery API you can integrate the gallery into your website behaviour and use it with another items like lightboxes etc.
کتابخانه unitegallery