
چند هفته پیش بود که مایکروسافت اعلام کرد قصد دارد پلتفرم گیتهاب را که بزرگترین منبع کدهای برنامه نویسی در دنیا محسوب میشود به قیمت ۷.۵ میلیارد دلار خریداری کند. توضیح اهمیت بالای گیتهاب برای جامعه برنامهنویسان در سراسر دنیا بسیار کار سادهای است چراکه این سرویس در حال حاضر بیش از ۲۸ میلیون کاربر دارد و حاوی ۸۵ میلیون پروژه برنامهنویسی در زمینههای مختلف و مرتبط با پلتفرم شرکتهای مهمی از جمله اپل، گوگل، آمازون، والمارت، فیسبوک و حتی دولت آمریکا است. ضمنا بیشتر این پروژهها به صورت منبع باز (اوپن سورس) برای برنامهنویسان در دسترس قرار گرفتهاند.
پس از خریداری شدن گیتهاب توسط مایکروسافت، آمار نشان میداد که مهاجرت برنامهنویسان و پروژههای برنامهنویسی آنها از پلتفرم گیتهاب به سرویسهای رقیب با افزایش ۱۰ برابری همراه بوده است. با این حال اخبار جدید نشان میدهد اکثریت برنامهنویسان گیتهاب قصد دارند حداقل یک فرصت را به مایکروسافت برای اثبات صداقت گفتههایش بدهند.
«کرت ساسمن» یکی از مدیران فنی برنامهنویسی مشهور در سخنرانی روز گذشته خود در جریان کنفرانس «Open Source Bridge» گفت: «مایکروسافت در گذشته اقدامات ضد رقابتی از خود نشان داده بود اما در چند سال اخیر این کمپانی قدمهای مهمی در زمینه گسترش دنیای اوپن سورس برداشته است. من در این مدت جایگزینهای گیتهاب را امتحان کردهام اما با این حال به آینده مایکروسافت و گیتهاب همچنان امیدوارم و باز هم گیتهاب را بهعنوان گزینه اصلی به برنامه نویسان سراسر دنیا پیشنهاد میکنم. این سرویس همچنان قابل اعتماد، با ثبات و دارای پشتیبانی بسیار خوبی است.»
«نت فریدمن» مدیرعامل جدید گیتهاب هم در جلسه پرسش و پاسخ آنلاینی که ۳ هفته پیش در وبسایت ردیت برگزار شد گفت تعداد کاربرانی که از پلتفرم گیتهاب پس از خریداری شدن توسط مایکروسافت کوچ کردهاند خیلی چشمگیر و نگران کننده نبوده است و اکثر کاربران همچنان گیتهاب را به هر سرویس دیگری ترجیح میدهند.
«ادریسا» یکی از برنامهنویسان معروف و برگزارکننده کنفرانسهای متبط با فریم ورک برنامهنویسی «Django» هم میگوید: «شاید ۵ سال پیش از شنیدن خبر فروش گیتهاب به مایکروسافت وحشت زده میشدم اما حالا اینطور نیست چرا که مایکروسافت در این چند سال به جای تضعیف جامعه برنامه نویسان و اوپن سورسها، بیشتر به فکر تشویق و تقویت آنها بوده است. بهطور مثال مایکروسافت در این چند سال پشتیبانی از ابزار لینوکس را هم به ویندوز ۱۰ اضافه کرده که نکته امیدوار کنندهای محسوب میشود. امروزه شاهد این هستیم که نه تنها برنامه نویسان همچنان از گیتهاب و خدمات مایکروسافت استفاده میکنند بلکه تکنولوژیهای مایکروسافت را به دیگر برنامه نویسان هم پیشنهاد میکنند. بنابراین میتوان همچنان به استفاده از سرویس گیتهاب امیدوار بود.»
البته مایکروسافت نباید خیلی از داشتن این کاربران خوشحال باشد چراکه برخی از دارندگان منابع بزرگ اوپن سورس اعلام کردهاند قصد دارند از پلتفرم گیتهاب خارج شود چون این دسته از افراد معتقدند مایکروسافت به دنبال ایجاد انحصار در حفظ و ارائه کدهای اوپن سورس به برنامهنویسان است. از طرف دیگر سرویسهای رقیب گیتهاب نیز میگویند که این دسته از نگرانیهای برنامه نویسان باعث پیشرفت آنها و جذب هرچه بیشتر کاربر توسط آنها شده است. برای مثال سرویس رقیب گیتهاب یعنی «SourceForge» اعلام کرده در طی ۳ هفته پس از اعلام خبر فروش گیتهاب به مایکروسافت، جذب کاربر توسط این پلتفرم با افزایش ۵۰۰ درصدی همراه شده و این میزان در حال حاضر در مقایسه با قبل از به خدمت گرفته شدن گیتهاب توسط مایکروسافت به ۲۵۰ درصد کاهش پیدا کرده است. باید توجه داشت که این افرادی که گیتهاب را ترک کردند تعداد قابل توجهی نیستند و این یعنی مایکروسافت میتواند با برنامه ریزی مناسب اعتماد افرادی که در گیتهاب باقی ماندهاند را جلب کند و در آینده نزدیک هم تعداد کاربران را بیشتر کند و حتی کوچ کنندگان را هم به این سرویس برگرداند.
حال با اینکه مایکروسافت اعلام کرده قصد ندارد رویه استفاد از خدمات گیتهاب برای برنامه نویسان را تغییر دهد و اکثر برنامهنویسان یک شانس مجدد به این شرکت دادهاند، اما در صورتی که این کمپانی ذرهای کوتاهی از خود نشان دهد و برنامهنویسان گیتهاب را تحت فشار بگذارد، مطمئنا شاهد کوچ درصد عظیمی از برنامهنویسان و کدهای اوپن سورس از این پلتفرم به سرویسهای رقیب گیتهاب خواهد بود.

ایتنا – سیستم انگولار که در حقیقت فریم ورک جاوا اسکریپت گوگل برای ساخت نرمافزارهای همراه و دسکتاپ است، با عرضه یک بهروزرسانی ویژه دیگر به نسخه ۵ انتقال پیدا کرده است.
سیستم انگولار که در حقیقت فریم ورک Java Script گوگل برای ساخت نرمافزارهای همراه و دسکتاپ محسوب میشود، به تازگی و با عرضه یک بهروزرسانی ویژه دیگر به نسخه ۵ ارتقاء یافته است.
به گزارش ایتنا از رایورز شرکت گوگل برای بسیاری از کاربران عام، صرفاً خدمات دهنده وبی محض است، اما در عمل، فعالیتهای نرمافزاری ویژهای را نیز به شرکتهای پدیدآورنده نرمافزار و نیز برنامهنویسان ارائه میکند.
یکی از محبوبترین سیستمهای ارائه شده توسط گوگل را میتوان فریم ورک جاوا اسکریپت دانست که با نام انگولار شناخته شده و سالی درخشان را سپری نموده است.
میزان کاربرد این فریمورک به قدری است که در طول ۱۴ ماه گذشته شاهد دو بار بروزرسانی برای آن و اواخر نوامبر سال جاری نیز شاهد عرضه نسخه ۵.۰.۰ این سیستم خواهیم بود.
ابتدا قرار بود این نسخه در اوایل ماه نوامبر عرضه شود که به دلیل برخی مشکلات در برنامه کاری گوگل، شاهد تأخیر در عرضه این سیستم محبوب طراحی نرمافزار هستیم.
مزایای نسخه ۵ انگولار، بسیار فراوان و متنوع است، اما بر اساس اعلام گوگل، چند ویژگی اصلی در این سیستم جای داده شده که به ترتیب شامل موارد زیر هستند:
– آسانسازی ساخت نرمافزارهای وبی پراگرسیو برای امکان اجرا بر روی مرورگر وب
– بهینهسازی کدها با کوچکتر کردن برنامه از طریق حذف کدهای اضافه
– سازگار نمودن سیستم طراحی با Rendering در سمت سرور
– پشتیبانی سراسری از API و dom برای به اشتراکگذاری کد بین سرورها و نسخه سمت مشتری از یک نرمافزار
– بهبود کامپایلر برای پشتیبانی از کامپایل بهصورت تصاعدی
– استانداردسازی سیستمهای عددی، مالی و تاریخی بینالمللی
– امکان استفاده از نامهای مختلف برای اجزا و دایرکتیوها که میتوان بدون نیاز به تغییر موارد متعدد، به این نسخه مهاجرت نمود
– وجود یک Httpclient بروزرسانی شده
– وجود CLI 1.5 که پروژههای انگولار ۵ را بهصورت پیشفرض ایجاد مینماید
– امکان تأیید و بروزرسانی مقادیر در فرمهای انگولار بهصورت گروهی بهجای رسیدگی به تکتک ورودیها
– بروزرسانی مجموعه برنامهنویسی باز فعال RxJS به نسخه ۵.۵.۲ و بالاتر از آن
– امکان ردیابی سایکلهای روتر از ابتدای اجرا تا پایان زمان فعالسازی کامل سیستم حفاظتی

بر اساس لیست TIOBE درمورد ۱۰ زبان محبوب برنامه نویسی ، زبان برنامهنویسی اپل سوئیفت –Apple Swift ، امسال با ۴ پله صعود نسبت به سال گذشته، در مکان دهم قرار گرفت. بر اساس آخرین جدول منتشر شده از شاخص TIOBE که محبوبترین زبانهای برنامهنویسی را معرفی میکند، شرکت اپل سال گذشته در جایگاه چهاردهم لیست قرار داشت و امسال توانست به جایگاه دهم ارتقا پیدا کند. البته شاید به عقیده بسیاری از افراد، این جایگاه چندان چشم گیر نباشد اما با در نظر گرفتن این واقعیت که عمر هر ۱۰ زبان برتر اشاره شده در این لیست بیش از بیست سال است، میتوان نتیجه گرفت که زبان جدید اپل سوئیفت، در این مدت رشد بالایی داشته است. اپل سوئیفت در سال ۲۰۱۴ عرضه شد و جایگزین زبان برنامهنویسی Apple Objective-C برای طراحی برنامههای مک، آی او اس ، اپل واچ و اپل تی وی شد.
اپل زبان سوئیفت را ساده تر از Objective-C ارائه کرده است و همچنین برنامه مخصوص آی پد Swift Playground را برای آموزش برنامهنویسی به کودکان و افراد مبتدی منتشر کرد. کودکان از طریق این برنامه، با حل کردن یک سری پازل مخصوص زبان سوئیفت، با مفاهیم پایهای و ابتدایی برنامه نویسی آشنا خواهند شد. Swift Playground در کنفرانس جهانی برنامه نویسان اپل در سال ۲۰۱۶ و به عنوان یک برنامه خلاقانه معرفی شد که آموزش و یادگیری برنامهنویسی را برای همه بسیار ساده میکند.
طبق گزارش MacRumors، شاخص TIOBE با استفاده از اطلاعات موتور جستجو، میزان محبوبیت زبانهای برنامه نویسی مختلف را در داخل جوامع برنامه نویسی آنلاین مشخص میکند.
منبع : آی تی ایران

مقدمه
اگر قصد اجرای برخی کارها به صورت زمانبندی شده و در فواصل زمانی مشخص را دارید، این مقاله به شما کمک خواهد کرد تا به بهترین شکل ممکن آن را انجام دهید. کارهایی مانند ارسال خبرنامه، فرستادن SMS تبریک تولد یا هماهنگ سازی دادهها بین دو منبع داده از جمله اَعمالی هستند که باید به صورت زمانبندی شده انجام شوند.
کتابخانهی Quartz.NET، از کتابخانه ای با نام Quartz و از زبان Java به NET. منتقل شده است. Quartz.NET، رایگان و باز متن است و از طریق آدرس
http://quartznet.sourceforge.net در دسترس است. از طریق NuGet نیز میتوانید با تایپ عبارت quartz در فرم مربوطه، این کتابخانه را نصب کنید. این کتابخانه را در برنامههای Desktop و Web (حتی یک Shared Server) تست کردم و به خوبی انجام وظیفه میکند.
شروع کار با Quartz.NET
ضمن در اختیار قرار دادن امکانات فوق العاده و انعطاف پذیری بسیار، کار با این کتابخانه آسان و از فرایندی منطقی تبعیت میکند. فرایند اجرای یک روال زمانبندی شده از طریق Quartz.NET، از چهار مرحلهی اصلی تشکیل شده است.
۱) پیاده سازی اینترفیس IJob
۲) مشخص کردن جزئیات روال با اینترفیس IJobDetail
۳) مشخص کردن تنظیمات زمان با استفاده از اینترفیس ITrigger
۴) مدیریت اجرا با استفاده از اینترفیس IScheduler
مثالی را بررسی میکنیم. در این مثال قصد داریم تا عبارتی را همراه با تاریخ و زمان جاری در یک فایل ذخیره کنیم. این پیغام باید ۳ بار و در فواصل زمانی ۱۰ ثانیه به فایل اضافه شود. در پایان، فایلی خواهیم داشت که در سه خط، یک عبارت، همراه با تاریخ و زمانهای مختلف را که ۱۰ ثانیه با یکدیگر اختلاف دارند در خود ذخیره کرده است. ابتدا کار زمانبندی شده را با ارائهی پیاده سازی برای متد Execute اینترفیس IJob این کتابخانه ایجاد میکنیم. وارد کردن فضای نام Quartz را فراموش نکنید.
namespace SchedulerDemo.Jobs
{
using System;
using System.IO;
using Quartz;
public class HelloJob : IJob
{
public void Execute(IJobExecutionContext context)
{
// for web apps
// string path = System.Web.Hosting.HostingEnvironment.MapPath(“~/Data/Log.txt”);
// for desktop apps
string path = @”C:\Log.txt”;
using (StreamWriter sw = new StreamWriter(path, true))
{
sw.WriteLine(“Message from HelloJob ” + DateTime.Now.ToString());
}
}
}
}
در اینترفیس IJob در ASP.NET، به شی HttpContext دسترسی ندارید، بنابراین در صورتی که قصد داشته باشید از متدی مانند Server.MapPath استفاده کنید، توفیقی به دست نخواهید آورد. در عوض میتوانید از متد System.Web.Hosting.HostingEnvironment.MapPath استفاده کنید.
حال، زمان انجام تنظیمات مختلف برای اجرای روال مربوطه است. بهتر است تا interfaceیی ایجاد و متدی با نام Run در آن داشته باشیم.
namespace SchedulerDemo.Interfaces
{
public interface ISchedule
{
void Run();
}
}
حال، پیاده سازی خود را برای این interface ارائه میدهیم.
namespace SchedulerDemo.Jobs
{
using System;
using Quartz;
using Quartz.Impl;
using SchedulerDemo.Interfaces;
using SchedulerDemo.Jobs;
public class HelloSchedule : ISchedule
{
public void Run()
{
//DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 2);
DateTimeOffset startTime = DateBuilder.FutureDate(2, IntervalUnit.Second);
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity(“job1”)
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(“trigger1”)
.StartAt(startTime)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(2))
.Build();
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sc = sf.GetScheduler();
sc.ScheduleJob(job, trigger);
sc.Start();
}
}
}
معرفی فضاهای نام Quartz و Quartz.Impl را فراموش نکنید.
از حالا، به روالی که قرار است به صورت زمانبندی شده اجرا شود، “وظیفه” میگوییم.
ابتدا باید مشخص کنیم که وظیفه در چه زمانی پس از اجرای برنامه شروع به اجرا کند. از آنجا که پایه و اساس زمانبندی، بر تاریخ و ساعت استوار است، کتابخانهی Quartz.NET، روشها و امکانات بسیاری را برای تعیین زمان در اختیار قرار میدهد. با بررسی تمامی آنها، سادهترین و منعطفترین را به شما معرفی میکنم. کلاس DateBuilder که همراه با Quartz.NET وجود دارد، امکان تعیین زمان را به اَشکال مختلف میدهد. در خط ۱۴، از متد FutureDate این کلاس استفاده شده است که خوانایی بهتری نسبت به بقیهی متدها دارد. پارامتر اول این متد، عدد، و پارامتر دوم، واحد زمانی را میپذیرد.
DateTimeOffset startTime = DateBuilder.FutureDate(2, IntervalUnit.Second);
در اینجا، زمان آغاز وظیفه را ۲ ثانیه پس از آغاز برنامه تعریف کرده ایم. واحدهای زمانی دیگر شامل میلی ثانیه، دقیقه، ساعت، روز، ماه، هفته و سال هستند. کلاس DateBuilder، متدهای مختلفی برای تعیین زمان را در اختیار قرار میدهد. تعیین زمان آغاز به روش دیگر را به صورت کامنت شده در خط ۱۳ مشاهده میکنید.
وظیفهی ایجاد شده در خط ۱۶ تا ۱۸ معرفی شده است.
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity(“job1”)
.Build();
پشتیبانی Quartz.NET از سینتکس fluent، کدنویسی را ساده و لذت بخش میکند. با استفاده از متد Create کلاس JobBuilder، وظیفه را معرفی میکنیم. متد Create، یک متد Generic است که نام کلاسی که اینترفیس IJob را پیاده سازی کرده است میپذیرد. یک نام را با استفاده از متد WithIdentity به وظیفه نسبت میدهیم (البته این کار، اختیاری است) و در انتها، متد Build را فراخوانی میکنیم. خروجی متد Build، از نوع IJobDetail است.
و حالا نوبت به تنظیمات زمان رسیده است. در Quartz.NET، این مرحله، “ایجاد trigger” نام دارد. خطوط ۲۰ تا ۲۴ به این کار اختصاص دارند.
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(“trigger1”)
.StartAt(startTime)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(2))
.Build();
ابتدا متد Create کلاس TriggerBuilder را فراخوانی میکنیم، سپس با استفاده از متد WithIdentity، یک نام به trigger اختصاص میدهیم (البته این کار، اختیاری است). با متد StartAt، زمان شروع وظیفه را که در ابتدا با استفاده از کلاس DateBuilder ایجاد کردیم تعیین میکنیم. مهمترین قسمت، تعیین دفعات و فواصل زمانی اجرای وظیفه است. همان طور که احتمالاً حدس زده اید، Quartz.NET مجموعه ای غنی از روشهای مختلف برای تعیین بازهی زمانی اجرا را در اختیار قرار میدهد. آسانترین راه، استفاده از متد WithSimpleSchedule است. با استفاده از یک عبارت Lambda که ورودی آن از نوع کلاس SimpleScheduleBuilder است، دفعات و فواصل زمانی اجرا را تعیین میکنیم. متد WithIntervalInSeconds، برای تعیین فواصل زمانی در بازهی ثانیه استفاده میشود. متد WithRepeatCount نیز برای تعیین دفعات اجرا است. وظیفهی ما، ۳ مرتبه و در فواصل زمانی ۱۰ ثانیه اجرا میشود. مطمئن باشید اشتباه نکردم! بله، سه مرتبه. تعداد دفعات اجرا برابر است با عددی که برای متد WithRepeatCount تعیین میکنید، به علاوهی یک. منطقی است، چون مرتبهی اول اجرا زمانی است که با استفاده از متد StartAt تعیین کرده اید. در پایان، متد Build را فراخوانی میکنیم. خروجی متد Build، از نوع ITrigger است.
آخرین کار (خطوط ۲۶ تا ۳۰)، ایجاد شی از اینترفیس IScheduler، فراخوانی متد ScheduleJob آن، و پاس دادن اشیای job و trigger که در قسمت قبل ایجاد شده اند به این متد است. در انتها، متد ()Start را برای آغاز وظیفه فراخوانی میکنیم.
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sc = sf.GetScheduler();
sc.ScheduleJob(job, trigger);
sc.Start();
حال شما یک وظیفه تعریف کرده اید که در هر جای برنامه به صورت زیر، قابل فراخوانی است.
ISchedule myTask = new HelloSchedule();
myTask.Run();

در حین بروز استثناهای Entity framework، میتوان توسط ابزارهای Logging متنوعی مانند ELMAH، جزئیات متداول آنها را برای بررسیهای آتی ذخیره کرد. اما این جزئیات فاقد SQL نهایی تولیدی و همچنین پارامترهای ورودی توسط کاربر یا تنظیم شده توسط برنامه هستند. برای اینکه بتوان این جزئیات را نیز ثبت کرد، میتوان یک IDbCommandInterceptor جدید را طراحی کرد.
کلاس EfExceptionsInterceptor
در اینجا نمونهای از یک پیاده سازی اینترفیس IDbCommandInterceptor را مشاهده میکنید. همچنین طراحی یک متد عمومی که میتواند به جزئیات SQL نهایی و پارامترهای آن دسترسی داشته باشد، در اینترفیس IEfExceptionsLogger ذکر شدهاست
public interface IEfExceptionsLogger
{
void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext);
}
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
namespace ElmahEFLogger
{
public class EfExceptionsInterceptor : IDbCommandInterceptor
{
private readonly IEfExceptionsLogger _efExceptionsLogger;
public EfExceptionsInterceptor(IEfExceptionsLogger efExceptionsLogger)
{
_efExceptionsLogger = efExceptionsLogger;
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
}
}
تهیه یک پیاده سازی سفارشی از IEfExceptionsLogger توسط ELMAH
اکنون که ساختار کلی IDbCommandInterceptor سفارشی برنامه مشخص شد، میتوان پیاده سازی خاصی از آنرا جهت استفاده از ELMAH به نحو ذیل ارائه داد:
using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using Elmah;
namespace ElmahEFLogger.CustomElmahLogger
{
public class ElmahEfExceptionsLogger : IEfExceptionsLogger
{
/// <summary>
/// Manually log errors using ELMAH
/// </summary>
public void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext)
{
var ex = interceptionContext.OriginalException;
if (ex == null)
return;
var sqlData = CommandDumper.LogSqlAndParameters(command, interceptionContext);
var contextualMessage = string.Format(“{0}{1}OriginalException:{1}{2} {1}”, sqlData, Environment.NewLine, ex);
if (!string.IsNullOrWhiteSpace(contextualMessage))
{
ex = new Exception(contextualMessage, new ElmahEfInterceptorException(ex.Message));
}
try
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
catch
{
ErrorLog.GetDefault(null).Log(new Error(ex));
}
}
}
}
در اینجا شیء Command به همراه SQL نهایی تولید و پارامترهای مرتبط است. همچنین interceptionContext.OriginalException جزئیات عمومی استثنای رخ داده را به همراه دارد. میتوان این اطلاعات را پس از اندکی نظم بخشیدن، به متد Raise مربوط به ELMAH ارسال کرد تا جزئیات بیشتری از استثنای رخ داده شده، در لاگهای آن ظاهر شوند.
استفاده از ElmahEfExceptionsLogger جهت طراحی یک Interceptor عمومی
public class ElmahEfInterceptor : EfExceptionsInterceptor
{
public ElmahEfInterceptor()
: base(new ElmahEfExceptionsLogger())
{ }
}
برای استفاده از ElmahEfExceptionsLogger و تهیه یک Interceptor عمومی، میتوان با ارث بری از کلاس Interceptor ابتدای بحث شروع کرد و وهلهای از ElmahEfExceptionsLogger را به سازندهی آن تزریق نمود (یکی از چندین روش ممکن). سپس برای استفاده از آن کافی است به ابتدای متد Application_Start فایل Global.asax.cs مراجعه و در ادامه سطر ذیل را اضافه نمود:
DbInterception.Add(new ElmahEfInterceptor());
پس از آن جزئیات کلیه استثناهای EF در لاگهای نهایی ELMAH به نحو ذیل ظاهر خواهند شد:

یکی از مباحثی که به نظرم هر دانشجوی رشته کامپیوتر، فناوری اطلاعات و علاقمند به این حوزه باید بداند بحث کاراکترهاست؛ جدا از اینکه همه ما در مورد وجود ascii یا UTF-8 و … و توضیحات مختصر آن اطلاع داریم ولی عدهای از دوستان مثل من هنوز اطلاعات پایهایتر و جامعتری در این باره نداریم؛ در این مقاله که برداشتی از وب سایت smashing magazine و W3 است به این مبحث میپردازیم.
کامپیوترها تنها با اعداد سر و کار دارند نه با حروف؛ پس این بسیار مهم هست که همه کامپیوترها بر روی یک سری اعداد مشخص به عنوان نمایندهای از حروف به توافق برسند. این توافق یکسان بین همه کامپیوترها بسیار مهم هست و باید طبق یک استاندارد مشترک استفاده شود تا در همه سیستمها قابل استفاده و انتقال باشد؛ برای همین در سال ۱۹۶۰ اتحادیه استاندارهای آمریکا، یک سیستم رمزگذاری ۷ بیتی را ایجاد کرد؛ به نام American Standard Code for Information Interchange یا کد استاندارد سازی شده آمریکایی برای تبادل اطلاعات یا همان ASCII. این هفت بیت به ما اجازه میداد تا ۱۲۸ حرف را کدگذاری کنیم. این مقدار برای حروف کوچک و بزرگ انگلیسی و هم چنین حروف لاتین، همراه با کدگذاری ارقام و یک سری علائم نگارشی و کاراکترهایی از قبیل space ، tab و موارد مشابه و نهایتا کلیدهای کنترلی کافی بود. در سال ۱۹۶۸ این استاندارد توسط رییس جمهور وقت آمریکا لیندون جانسون به رسمیت شناخته شده و همه سیستمهای کامپیوتری ملزم به رعایت و استفاده از این استاندارد شدند.
برای لیست کردن و دیدن این کدها و نمادهای حرفیشان میتوان با یک زبان برنامه نویسی یا اسکریپتی آنها را لیست کرد. کد زیر نمونهای از کد نوشته شده در جاوااسکریپت است.
<html>
<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>
<script type=”text/javascript”>
for (var i=0; i<128; i++) document.writeln ((i%32?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);
</script>
</body>
</html>
در سالهای بعدی، با قویتر شدن پردازشگرها و ۸ بیت شدن یک بایت به جای ذخیره ۱۲۸ عدد توانستند ۲۵۶ عدد را ذخیره کنند ولی استاندارد اسکی تا ۱۲۸ کد ایجاد شده بود و مابقی را به عنوان ذخیره نگاه داشتند. در ابتدا کامپیوترهای IBM از آنها برای ایجاد نمادهای اضافهتر و همچنین اشکال استفاده میکرد؛ مثلا کد ۲۰۰ شکل ╚ بود که احتمالا برنامه نویسان زمان داس، این شکل را به خوبی به خاطر میاورند یا مثلا حروف یونانی را اضافه کردند که با کد ۲۲۴ شکل آلفا α بود و بعدها به عنوان code page 437 نامگذاری شد. هر چند که هرگز مانند اسکی به یک استاندارد تبدیل نشد و بسیاری از کشورها از این فضای اضافی برای استانداردسازی حروف خودشان استفاده میکردند و در کشورها کدپیجهای مختلفی ایجاد شد. برای مثال در روسیه کد پیچ ۸۸۵ از کد ۲۲۴ برای نمایش Я بهره میبرد و در کد پیچ یونانی ۷۳۷ برای نمایش حرف کوچک امگا ω استفاده میشد. این کار ادامه داشت تا زمانیکه مایکروسافت در سال ۱۹۸۰ کد پیچ Windows-1251 الفبای سریلیک را ارئه کرد. این تلاش تا سال ۱۹۹۰ ادامه پیدا کرد و تا آن زمان ۱۵ کدپیج مختلف استاندارسازی شده برای الفبایی چون سیریلیک، عربی، عبری و … ایجاد شد که این استانداردها از ISO-8859-1 شروع و تا ISO-8859-16 ادامه داشت و موقعی که فرستنده پیامی را ارسال میکرد، گیرنده باید از کدپیج مورد نظر مطلع میبود تا بتواند پیام را صحیح بخواند.
بیایید با یک برنامه علائم را در این ۱۵ استاندارد بررسی کنیم. تکه کدی که من در اینجا نوشتم یک لیست را که در آن اعداد یک تا ۱۶ لیست شده است، نشان میدهد که با انتخاب هر کدام، کدها را از ۰ تا ۲۵۵ بر اساس هر استاندارد به ترتیب نمایش میدهد. این کار توسط تعیین استاندارد در تگ متا رخ میدهد.
در زمان بارگذاری، استانداردها با کد زیر به لیست اضافه میشوند.در مرحله بعد لیستی که postback را در آن فعال کردهایم، کد زیر را اجرا میکند. در این کد ابتدا charset انتخاب شده ایجاد شده و سپس یکی یکی کدها را به کاراکتر تبدیل میکنیم و رشته نهایی را درج میکنیم
private String ISO = “ISO-8859-“;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 1; i < 16; i++)
{
ListItem item = new ListItem();
item.Text = ISO + i.ToString();
item.Value = i.ToString();
DropDownList1.Items.Add(item);
}
ShowCodes(1);
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedItem != null)
{
int value = int.Parse(DropDownList1.SelectedValue);
ShowCodes(value);
}
}
private void ShowCodes(int value)
{
Response.Charset = ISO + value;
string s = “”;
for (int i = 0; i < 256; i++)
{
char ch = (char)i;
s += i + “-” + ch;
s += “
“;//br tag
}
Label1.Text = s;
}
تقریبا سال ۱۹۹۰ بود که بسیاری از اسناد به همین شیوهها نوشته و ذخیره شد. ولی باز برای بسیاری از زبانها، حتی داشتن یکی دو حرف بیشتر مشکلاتی را به همراه داشت. مثلا حروف بعضی زبانها مثل چینی و ژاپنی چینی که ۲۵۶ عدد، پاسخگو نبود و با آمدن شبکهای چون اینترنت و بحث بین المللی شدن و انتقال اطلاعات، این مشکل بزرگتر از آنچه بود، شد.
یونیکد نجات بخش
اواخر سال ۱۹۸۰ بود که پیشنهاد یک استاندارد جدید داده شد و در آن به هر حرف و یا نماد در هر زبانی یک عدد یکتا نسبت داده میشد و باید بیشتر از ۲۵۶ عدد میبود که آن را یونیکد نامیدند. در حال حاضر یونیکد نسخه ۶۰۱ شامل ۱۱۰ هزار کد می شود. ۱۲۸ تای آن همانند اسکی است. از ۱۲۸ تا ۲۵۵ مربوط به علائم و علامتهاست که بیشتر آنها از استاندارد ISO-8859-1 وام گرفته شدهاند. از ۲۵۶ به بعد هم بسیاری از علائم تلفظی و … وجود دارد و از کد ۸۸۰ زبان یونایی آغاز شده و پس از آن زبانهای سیریلیک، عبری، عربی و الی آخر ادامه مییابند. برای نشان دادن یک کد یونیکد به شکل هگزادسیمال U+0048 نوشته میشود و برای تبدیل آن به دسیمال ۴*۱۶+۸=۷۲ استفاده میشود. به هر کد یونیکد، کد پوینت code point گفته میشود.
در ویکی پدیای فارسی، یونیکد اینگونه توضیح داده شده است: “نقش یونیکد در پردازش متن این است که به جای یک تصویر برای هر نویسه یک کد منحصر به فرد ارایه میکند. به عبارت دیگر، یونیکد یک نویسه را به صورت مجازی ارایه میکند و کار ساخت تصویر (شامل اندازه، شکل، قلم، یا سبک) نویسه را به عهده نرمافزار دیگری مانند مرورگر وب یا واژهپرداز میگذارد. “
یونیکد از ۸ بیت یا ۱۶ بیت استفاده نمیکند و با توجه به اینکه دقیقا ۱۱۰ ،۱۱۶ کد را حمایت میکند به ۲۱ بیت نیاز دارد. هر چند که کامپیوترها امروزه از معمارهای ۳۲ بیتی و ۶۴ بیتی استفاده میکنند، این سوال پیش میآید که ما چرا نمیتوانیم کاراکترها را بر اساس این ۳۲ بیت و ۶۴ بیت قرار بدهیم؟ پاسخ این سوال ایناست که چنین کاری امکان پذیر است و بسیاری از نرم افزارهای نوشته شده در زبان سی و سی ++ از wide character حمایت میکنند. این مورد یک کاراکتر ۳۲ بیتی به نام wchar_t است که نوعی داده char توسعه یافته هشت بیتی است و بسیاری از مرورگرهای امروزی از آن بهره مند هستند و تا ۴ بیلیون کاراکتر را حمایت میکنند.
شکل زیر دسته بندی از انواع زبانهای تحت حمایت خود را در نسخه ۵.۱ یونیکد نشان میدهد
کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کردهایم نشان میدهد
<html>
<body>
<style type=”text/css”>p {float: left; padding: 0 15px; margin: 0;}</style>
<script type=”text/javascript”>
for (var i=0; i<2096; i++)
document.writeln ((i%256?”:'<p>’) + i + ‘: ‘ + String.fromCharCode (i) + ‘
‘);
</script>
</body>
</html>
CSS & Unicode
یکی از جذابترین خصوصیات در css، خصوصیت Unicode-range است. شما میتوانید برای هر کاراکتر یا حتی رنج خاصی از کاراکترها، فونت خاصی را اعمال کنید. به دو نمونه زیر دقت کنید:
/* cyrillic */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-style: normal;
src: local(‘Roboto Regular’), local(‘Roboto-Regular’), url(https://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format(‘woff2’);
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
در صورتی که در Unicode-range، تنها یک کد مانند U+20AD نوشته شود، فونت مورد نظر فقط بر روی کاراکتری با همین کد اعمال میشود. ولی اگر بین دو کد از علامت – استفاده شود، فونت مورد نظر بر روی کاراکترهایی که بین این رنج هستند اعمال میشود U+0025-00FF و حتی میتوان اینگونه نوشت ??U+4 روی کاراکترهایی در رنج U+400 تا U+4FF اعمال میشوند. برای اطلاعات بیشتر به اینجا و اینجا مراجعه کنید.
به ۶۵۵۳۶ کد اول یونیکد Basic Multilingual Plan یا به اختصار BMP میگویند و شامل همه کاراکترهای رایجی است که مورد استفاده قرار میگیرند. همچنین یونیکد شامل یک فضای بسیار بزرگ خالی است که به شما اجازه توسعه دادن آن را تا میلیونها کد میدهد. به کاراکترهایی که در این موقعیت قرار میگیرند supplementary characters یا کاراکترهای مکمل گویند. برای اطلاعات بیشتر میتوانید به سایت رسمی یونیکد مراجعه کنید. در اینجا هم مباحث آموزشی خوبی برای یونیکد دارد، هر چند کاملتر آن در سایت رسمی برای نسخههای مختلف یونیکد وجود دارد.
UTF-8 نجات بخش میشود
بسیاری از مشکلات ما حل شد. همه حروف را داریم و مرورگرها نیز همه حروف را میشناسند؛ ولی برای ما دو مشکل ایجاد کرده است:
بسیاری از نرم افزارها و پروتکلها هنوز ۸ بیتی کار میکنند.
اگر یک متن انگلیسی ارسال کنید، ۸ بیت هم کافی است ولی در این حالت ۳۲ بیت جابجا میشود؛ یعنی ۴ برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد میکند.
برای حل این مشکل استاندارهای زیادی چون USC-2 یا UTF-16 ایجاد شدند ولی در سالهای اخیر برنده رقابت، UTF-8 بود که مخفف عبارت Universal Character Set Transformation Format 8 bit میباشد. این کدگذاری بسیار هوشمندانه عمل میکند. موقعی که شما کاراکتری را وارد میکنید که کدش بین ۰ تا ۲۵۵ است، ۸ بیت به آن اختصاص میدهد و اگر در محدودهای است که بتوان دو بایت را به آن اختصاص داد، دوبایت و اگر بیشتر بود، سه بایت و اگر باز بیشتر بود ۴ بایت به آن اختصاص میدهد. پس با توجه به محدوده کد، تعداد بایتها مشخص میشوند. بنابراین یک متن نوشته شده انگلیسی که مثلا از کدهای بین ۰تا ۱۲۸ استفاده میکند و فرمت ذخیره آن UTF-8 باشد به ازای هر کارکتر یک بایت ذخیره میکند.
مقایسهای بین نسخههای مختلف :
همانطور که میبینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMPها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از ۴ بایت برای نمایش کاراکترهای مکمل استفاده میکند و در UTF-32 از ۴ بایت برای همه کاراکترها یا کد پوینتها استفاده میشود.

var d = new Date();
$.jCookies({
name: ‘dotnettips.info’,
value: { Title: ‘ساخت کوکی با jcookie’, Author: ‘علی یگانه مقدم’, Seen: d.getDate(), Favorite: true }
});
همانطور که میبینید ذخیره اطلاعات توسط jcookie بسیار ساده و راحت بوده و هر نوع داده ای در آن به راحتی قابل ذخیره سازیست. برای مثال میتوانید اطلاعات یک کلاس را خیلی راحت و سریع با آن ذخیره کنید. به طور پیش فرض تاریخ انقضای کوکی ۲۷ روز بعد از ایجاد آن میباشد. در صورتی که تمایل دارید این تاریخ را تغییر دهید یکی از خاصیتهای seconds,minutes,hours و days در دسترس شماست و مقادیری که جلوی آنها به کارگرفته میشود باید نوع صحیح بوده و در صورتی که مقدار نامعتبر وارد شود خاصیت مورد نظر نادیده گرفته میشود.
$.jCookies ({ name : ‘User’, value : { username : ‘Bob’ , level : 5 }, minutes : 60 });
برای تغییر پیش فرضهای ساخت کوکی مانند انقضای ۲۷ روز به عدد پیش فرض خودتان فایل jcookies.js را باز کرده و تنظیمات پیش فرض آن را تغییر بدهید. برای تغییر دنبال کد زیر بگردید:
$.jCookies.defaults =
{
name : ”,
value : ”,
days : 27
}
Error : {
arguments : undefined,
message : “Invalid base64 data”,
stack : “—”,
type : undefined
}
بازیابی همه کوکی ها
var values = $.jCookies({ get: ‘*’ });
alert(values[“dotnettips.info”].Title);
alert(values[“data2”].Title);
- برگشت دادهها از حالت رمزگذاری base64
- دادهها در فرمت json هستند و باید به حالتی قابل استفاده در محیط شی گرا تبدیل شوند.
Title | ایجاد کوکی با jcookie |
Author | علی یگانه مقدم |
Seen | 2015/1/14 |
Favorite | true |
byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
string json = Encoding.UTF8.GetString(from64);
Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Page.Response.Write(“Title: “+ (string)article[“Title”]);
پشتیبانی از یونیکد
موقعی که من اولین مثال بالا را نوشتم و مقادیر را به صورت فارسی وارد کردم متوجه شدم که رشتههای یونیکد را انکود نمیکند و در نتیجه زبان فارسی در آن پشتیبانی نمیشود. برای همین تغییراتی در فایل js ایجاد کرده و عبارت value قبل از تبدیل به base64 را به صورت utf-16 انکود کردم و در هنگام خواندن کوکی هم به صورت utf-16 دیکود کردم و مشکل زبان فارسی هم در این حالت حل شد. البته کدی که اضافه کردم قابلیتهای انکودینگ بیشتری هم دارد.
فقط تنها مورد این هست که برای خواندن کوکی در سمت سرور باید یک تغییر کوچک یک کلمه ای بدهیم؛ باید کلمه UTF8 را به Unicode که میشود همان UTF-16 در کد تغییر دهیم، که به کد زیر تغییر خواهد یافت:
byte[] from64 = Convert.FromBase64String(Page.Request.Cookies[“dotnettips.info”].Value);
string json = Encoding.Unicode.GetString(from64);
Dictionary<string, object> article =new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Page.Response.Write(“Title: “+ (string)article[“Title”]);

توسط روشی که امروز باهم بررسی می کنیم شما می توانید IP کاربری که به سرور متصل شده را بدست آورید.
بدست آوردن IP کاربر کاربردهای فراوانی دارد . شما می توانید اجازه دسترسی به دیتاهای خاصی را به کاربر بدهید یا کلا ورود کاربر را مسدود کنید یا حتی می توانید ساعات ورود و خروج کاربران را ثبت کنید تا برای گزارشات خاصی استفاده شود .
CREATE FUNCTION [dbo].[GetCurrentIP] ()
RETURNS varchar(255)
AS
BEGIN
DECLARE @IP_Address varchar(255);
SELECT @IP_Address = client_net_address
FROM sys.dm_exec_connections
WHERE Session_id = @@SPID;
Return @IP_Address;
END
جدول sys.dm_exec_connections از جداول SQL SERVER حاوی اطلاعاتی در مورد اتصال به Instance های نصب شده و جزییات هر یک از این اتصال ها می باشد بطور مثال مدت زمان برقراری اتصال ((connect_time ، پروتکل برقراری اتصال ( protocol_type که می تواند TDS یا SOAP باشد) ، protocol_version ، last_write ، last_read ( مدت زمان نوشته شدن و خوانده شدن اطلاعات ) و …
فیلد client_net_address هم آدرس هاست (ip) اتصال شده به سرور را برمی گرداند .
فیلد Session_id هم id سشن (session) مربوط به اتصال کنونی است .