پاسخ به بازخورد‌های پروژه‌ها
نمایش دو جدول در یک صفحه
با تشکر.آقای نصیری بنظرم کتابخانه فوق العاده ای هست که روز به روز هم بهتر میشه.مخصوصا تو پشتیبانی از ویژگی‌ها زبان فارسی .فقط اولش تا مهارت پیدا کنیم کمی زمانبر هست.
پاسخ به بازخورد‌های پروژه‌ها
چند متد الحاقی SEO
متد GenerateSlug حروف فارسی رو حذف می‌کنه. بازه زبان فارسی رو در متد ToSeoUrl می‌تونید مشاهده کنید.
نظرات نظرسنجی‌ها
اگر بخواهید کنار دات نت بر روی یک پلتفرم یا زبان دیگری نیز کار کنید کدام را انتخاب می کنید؟
هدف بنده بیشتر پلتفرم بود تا خود زبان، کاتلین هم زیر مجموعه جاوا محسوب میشه! با اینحال کاش بفرمایید چرا کاتلین؟!
نظرات نظرسنجی‌ها
چرا زبان جاوااسکریپت محبوب است؟
سلام
بله جناب محزونی حق با شماست 
هدف بنده از نوشتن اون گزینه "یادگیری آسان" صرفا، کلیته یادگیری اولیه زبان هست. 
مطالب
Roslyn #1
معرفی Roslyn

سکوی کامپایلر دات نت یا Roslyn (با تلفظ «رازلین») بازنویسی مجدد کامپایلرهای VB.NET و #C توسط همین زبان‌ها است. این سکوی کامپایلر به همراه یک سری کتابخانه و اسمبلی ارائه می‌شود که امکان آنالیز زبان‌های مدیریت شده را به صورت مستقل و یا یکپارچه‌ی با ویژوال استودیو، فراهم می‌کنند. برای نمونه در VS.NET 2015 تمام سرویس‌های زبان‌های موجود، با Roslyn API جایگزین و بازنویسی شده‌اند. نمونه‌هایی از این سرویس‌های زبان‌ها، شامل  Intellisense و مرور کدها مانند go to references and definitions، به همراه امکانات Refactoring می‌شوند. به علاوه به کمک Roslyn می‌توان یک کامپایلر و ابزارهای مرتبط با آن، مانند FxCop را تولید کرد و یا در نهایت یک فایل اسمبلی نهایی را از آن تحویل گرفت.


چرا مایکروسافت Roslyn را تولید کرد؟

پیش از پروژه‌ی Roslyn، کامپایلرهای VB.NET و #C با زبان ++C نوشته شده بودند؛ از این جهت که در اواخر دهه‌ی 90 که کار تولید سکوی دات نت در حال انجام بود، هنوز امکانات کافی برای نوشتن این کامپایلرها با زبان‌های مدیریت شده وجود نداشت و همچنین زبان محبوب کامپایلر نویسی در آن دوران نیز ++C بود. این انتخاب در دراز مدت مشکلاتی مانند کاهش انعطاف پذیری و productivity تیم کامپایلر نویس را با افزایش تعداد سطرهای کامپایلر نوشته شده به همراه داشت و افزودن ویژگی‌های جدید را به زبان‌های VB.NET و #C سخت‌تر و سخت‌تر کرده بود. همچنین در اینجا برنامه نویس‌های تیم کامپایلر مدام مجبور بودند که بین زبان‌های مدیریت شده و مدیریت نشده سوئیچ کنند و امکان استفاده‌ی همزمان از زبان‌هایی را که در حال توسعه‌ی آن هستند، نداشتند.
این مسایل سبب شدند تا در طی بیش از یک دهه، چندین نوع کامپایلر از صفر نوشته شوند:
- کامپایلرهای خط فرمانی مانند csc.exe و vbc.exe
- کامپایلر پشت صحنه‌ی ویژوال استودیو (برای مثال کشیدن یک خط قرمز زیر مشکلات دستوری موجود)
- کامپایلر snippet‌ها در immediate window ویژوال استودیو

هر کدام از این کامپایلرها هم برای حل مسایلی خاص طراحی شده‌اند. کامپایلرهای خط فرمانی، با چندین فایل ورودی، به همراه ارائه‌ی تعدادی زیادی خطا و اخطار کار می‌کنند. کامپایلر پشت صحنه‌ی ویژوال استودیوهای تا پیش از نسخه‌ی 2015، تنها با یک تک فایل در حال استفاده، کار می‌کند و همچنین باید به خطاهای رخ داده نیز مقاوم باشد و بیش از اندازه گزارش خطا ندهد. برای مثال زمانیکه کاربر در حالت تایپ یک سطر است، بدیهی است تا اتمام کار، این سطر فاقد ارزش دستوری صحیحی است و کامپایلر باید به این مساله دقت داشته باشد و یا کامپایلر snippet‌ها تنها جهت ارزیابی یک تک سطر از دستورات وارد شده، طراحی شده‌است.

با توجه به این مسایل، مایکروسافت از بازنویسی سکوی کامپایلر دات نت این اهداف را دنبال می‌کند:
- بالا بردن سرعت افزودن قابلیت‌های جدید به زبان‌های موجود
- سبک کردن حجم کاری کامپایلر نویسی و کاهش تعداد آن‌ها به یک مورد
- بالا بردن دسترسی پذیری به API کامپایلرها
برای مثال اکنون برنامه نویس‌ها بجای اینکه یک فایل cs را به کامپایلر csc.exe ارائه کنند و یک خروجی باینری دریافت کنند، امکان دسترسی به syntax trees، semantic analysis و تمام مسایل پشت صحنه‌ی یک کامپایلر را دارند.
- ساده سازی تولید افزونه‌های مرتبط با زبان‌های مدیریت شده.
اکنون برای تولید یک آنالیز کننده‌ی سفارشی، نیازی نیست هر توسعه دهنده‌ای شروع به نوشتن امکانات پایه‌ای یک کامپایلر کند. این امکانات به صورت یک API عمومی در دسترس برنامه نویس‌ها قرار گرفته‌اند.
- آموزش مسایل درونی یک کامپایلر و همچنین ایجاد اکوسیستمی از برنامه نویس‌های علاقمند در اطراف آن.
همانطور که اطلاع دارید، Roslyn به صورت سورس باز در GitHub در دسترس عموم است.


تفاوت Roslyn با کامپایلرهای سنتی

اکثر کامپایلرهای موجود به صورت یک جعبه‌ی سیاه عمل می‌کنند. به این معنا که تعدادی فایل ورودی را دریافت کرده و در نهایت یک خروجی باینری را تولید می‌کنند. اینکه در این میان چه اتفاقاتی رخ می‌دهد، از دید استفاده کننده مخفی است.


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


خلاصه‌ی مراحل رخ داده در کامپایلر سی‌شارپ را در تصویر فوق ملاحظه می‌کنید. در اینجا ابتدا کار parse اطلاعات متنی دریافتی شروع می‌شود و از روی آن syntax tree تولید می‌شود. در مرحله‌ی بعد مواردی مانند ارجاعاتی به mscorlib و امثال آن پردازش می‌شوند. در مرحله‌ی binder کار پردازش حوزه‌ی دید متغیرها، اشیاء و اتصال آن‌ها به هم انجام می‌شود. در مرحله‌ی آخر، کار تولید کدهای IL و اسمبلی باینری نهایی صورت می‌گیرد.
با معرفی Roslyn، این جعبه‌ی سیاه، به صورت یک API عمومی در دسترس برنامه نویس‌ها قرار گرفته‌است:


همانطور که مشاهده می‌کنید، هر مرحله‌ی کامپایل جعبه‌ی سیاه، به یک API عمومی Roslyn نگاشت شده‌است. برای مثال Parser به Syntax tree API نگاشت شده‌است. به علاوه این API صرفا به موارد فوق خلاصه نمی‌شود و همانطور که پیشتر نیز ذکر شد، برای اینکه بتواند جایگزین سه نوع کامپایلر موجود شود، به همراه Workspace API نیز می‌باشد:


Roslyn امکان کار با یک Solution و فایل‌های آن را دارد و شامل سرویس‌های زبان‌های مورد نیاز در ویژوال استودیو نیز می‌شود. برفراز Workspace API، یک مجموعه API دیگر به نام Diagnostics API تدارک دیده شده‌است تا برنامه نویس‌ها بتوانند امکانات Refactoring جانبی را توسعه داده و یا در جهت بهبود کیفیت کدهای نوشته شده، اخطارهایی را به برنامه نویس‌ها تحت عنوان Code fixes و آنالیز کننده‌ها، ارائه دهند.

نظرات مطالب
آشنایی با الگوی طراحی Decorator
فرقی نمیکنه. اگر قرار بود فرق میکرد و نیاز به ایجاد تغییرات در کد بود که این الگوها ارائه نمی‌شدند.
// ساخت کیک معمولی با روکش کاکائویی
Cake c = new CommonCake();
c = new Chocolate(c);

// ساخت کیک معمولی با روکش میوه‌ای 
Cake c = new CommonCake();
c = new Fruity(c);

// ساخت کیک معمولی مخلوط با روکش کاکائویی و روکش میوه‌ای به صورت همزمان
Cake c = new CommonCake();
c = new Chocolate(c);
c = new Fruity(c);

// ساخت کیک مخصوص مخلوط با روکش کاکائویی و روکش میوه‌ای به صورت همزمان
Cake c = new SpecialCake();
c = new Chocolate(c);
c = new Fruity(c);

برای هر c میتوان متدهای اینترفیسش را اجرا کرد.
مطالب
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   
مطالب
سرویس جمع و مفرد سازی اسامی

اگر به Entity data model wizard در VS.Net 2010 دقت کرده باشید، گزینه‌ی "Pluralize or singularize generated object names" نیز به آن اضافه شده است:



این مورد از این جهت حائز اهمیت است که عموما نام جداول در بانک اطلاعاتی، جمع است و نام کلاس متناظر ایجاد شده برای آن در کدهای برنامه بهتر است مفرد باشد. برای مثال نام جدول، Customers است و نام کلاس آن بهتر است Customer تعریف گردد. به این صورت کار کردن با آن توسط یک ORM با معناتر خواهد بود؛ زیرا زمانیکه یک وهله از شیء Customer ایجاد می‌شود، فقط یک رکورد از بانک اطلاعاتی مد نظر است؛ در حالیکه یک جدول مجموعه‌ای است از رکوردها.
زبان انگلیسی هم پر است از اسامی جمع و مفرد باقاعده و بی‌قاعده و کل عملیات با اضافه و حذف کردن یک s و یا es پایان نمی‌یابد؛ برای مثال phenomenon و phenomena را در نظر بگیرد تا Money و Moneys.
این امکان مهیا شده توسط Entity Framework 4.0 یا همان EF v2 با برنامه نویسی هم قابل دسترسی است و در اسمبلی System.Data.Entity.Design.dll و فضای نام System.Data.Entity.Design.PluralizationServices قرار گرفته است.
این اسمبلی جزیی از دات نت 4 است و اگر آن‌را توسط گزینه‌ی Add references در VS.NET مشاهده نمی‌کنید، علت آن است که در تنظیمات پروژه جاری، گزینه‌ی Target framework بر روی Client profile قرار گرفته است که باید به دات نت 4 کامل تغییر یابد.
استفاده از آن هم به صورت زیر است:

using System;
using System.Data.Entity.Design.PluralizationServices;
using System.Globalization;

namespace PluralizationServicesTest
{
class Program
{
static void Main(string[] args)
{
var service = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
Console.WriteLine(service.Pluralize("mouse"));
Console.WriteLine(service.IsPlural("phenomena"));
}
}
}

ملاحظات:
این روش فعلا به زبان انگلیسی محدود است و اگر Culture را به مورد دیگری تنظیم کنید با خطای "We don't support locales other than English yet" متوقف خواهید شد.


روش دیگر:
کتابخانه‌ی سورس باز Castle ActiveRecord نیز دارای کلاسی است به نام Inflector که برای همین منظور طراحی شده است:


کاربرد آن در Fluent NHibernate
در Fluent NHibernate کار نگاشت کلاس‌ها به جداول به صورت خودکار صورت می‌گیرد و همچنین تولید ساختار بانک اطلاعاتی نیز به همین نحو می‌باشد. اما می‌توان تولید نام جداول را سفارشی نیز نمود. برای مثال از کلاس Book به صورت خودکار ساختار جدولی به نام Books را تولید کند:
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
using NHibernate.Helper.Toolkit;

namespace NHibernate.Helper.MappingConventions
{
public class TableNameConvention : IClassConvention
{
public void Apply(IClassInstance instance)
{
instance.Table(Inflector.Pluralize(instance.EntityType.Name));
}
}
}
و برای تزریق آن خواهیم داشت:

... = new AutoPersistenceModel()
.Where(...)
.Conventions.Setup(c =>c.Add<TableNameConvention>())
.AddEntityAssembly(...)
...

مطالب
سخنان بزرگان!

اشکال زدایی (debug) یک کد چندین مرتبه از نوشتن آن سخت‌تر است. بنابراین اگر کد اولیه خود را بسیار هوشمندانه بنویسید، جهت اشکال زدایی آن به اندازه‌ی کافی باهوش نخواهید بود! (Brian Kernighan)

تنها دو نوع زبان برنامه نویسی وجود دارد: آنهایی که برنامه نویس‌ها از آن شکایت دارند و آن‌هایی که اصلا مورد استفاده قرار نمی‌گیرند! (Bjarne Stroustrup)

هر کسی می‌تواند کدی بنویسد که یک کامپیوتر آن‌را درک کند. یک برنامه نویس خوب کدی را می‌نویسد که برای سایر همکارانش قابل درک باشد. (Martin Fowler)

اندازه‌گیری درصد پیشرفت یک پروژه برنامه نویسی با شمارش تعداد سطرهای کدهای آن همانند اندازه گیری درصد پیشرفت ساخت یک هواپیما از طریق وزن کردن آن است! (Bill Gates)

برنامه نویسی سطح پایین (Low-level) روح برنامه نویس‌ها را جلا می‌بخشد! (John Carmack, ID software)

بزرگی واقعی با اندازه گیری مقدار آزادی که به دیگران عطا می‌کنید، سنجیده می‌شود و نه به اینکه چگونه دیگران را وادار می‌کنید تا آنچه را که مد نظر شما است اجرا کنند. (Larry Wall)

هیچگاه از gets و sprintf استفاده نکنید، در غیر اینصورت شیاطین به زودی به سراغ شما خواهند آمد! (FreeBSD Secure Programming Guidelines)

صحبت کردن ساده است. کدت رو نشون بده! (Linus Torvalds)

علوم رایانه هیچگاه شخصی را تبدیل به یک برنامه نویس خوب نمی‌کنند همانطور که مطالعه در مورد رنگ‌ها و قلم‌ها شما را تبدیل به یک نقاش خوب نمی‌کند. (Eric Raymond)

برنامه نویسی مانند س.ک.س است. یک اشتباه و سپس تحمل کردن و پشتیبانی آن تا آخر عمر! (Michael Sinz)

هیچ برنامه‌ای تا زمانیکه آخرین یوزر آن بمیرد به پایان نخواهد رسید! (از یک گروه پشتیبانی نرم افزار ناشناس!)

برنامه نویس‌های C هرگز نخواهند مرد. آن‌ها فقط تبدیل به void خواهند شد. (ناشناس)

پایان دنیای یونیکس 2 به توان 32 ثانیه پس از اول ژانویه 1970 است! (ناشناس)

زمانی‌ که کد می‌نویسید فرض کنید شخصی که قرار است در آینده از کدهای شما نگهداری کند یک دیوانه‌ی زنجیری است که آدرس خانه‌ی شما را می‌داند! (Rick Osborne)

سادگی یک برنامه یکی از شرایط قابل اطمینان بودن آن است. (Edsger Dijkstra)

یونیکس سیستم عامل ساده‌ای است، اما شما باید فرد باهوشی باشید تا بتوانید این سادگی را درک کنید! (Dennis Ritchie)

اگر به کامپایلر دروغ بگوئید او بعدا انتقام خواهد گرفت! (Henry Spencere)

پرل تنها زبان برنامه نویسی است که پیش و پس از رمزنگاری RSA به یک شکل به نظر می‌رسد! (Keith Bostic)

تنها دو صنعت هستند که به مصرف کنندگان خود "کاربر" می‌گویند: صنعت کامپیوتر و تجارت مواد مخدر! (ناشناس)

مطالب
افزایش کارآیی گزارش‌ها در Stimulsoft
به صورت پیش فرض، تمام گزارشات Stimulsoft، قبل از رندر باید به صورت اسمبلی کامپایل شوند. در برنامه‌های NET. در صورتیکه اسمبلی در حافظه بارگذاری شده باشد، تا زمانیکه برنامه اصلی از حافظه خارج نشود، فایل اسمبلی قفل خواهد بود و امکان حذف و یا تغییر آن وجود ندارد.
در هر بار کامپایل گزارش، فایل اسمبلی کامپایل شده، در پوشه %Temp% ذخیره و در حافظه بارگذاری می‌شود. به هرحال، بارگذاری اسمبلی گزارش، سبب قفل شدن و اختصاص حافظه‌ای برای آن می‌شود.

همانطور که مشاهده می‌کنید در هر بار کامپایل گزارش، این فایل‌ها ساخته می‌شوند.
چندین راه حل برای رفع این مشکل وجود دارد:
  1. استفاده گزارشات به صورت کلاس‌های #C در برنامه شما (با استفاده از Designer و Save as آن به صورت کلاس #C). در این صورت گزارش همزمان با کامپایل برنامه شما، کامپایل شده و در زمان فراخوانی، دیگر نیاز به کامپایل مجدد آن نیست.
    اشکال: در صورتیکه قالب گزارش شما نیاز به تغییر داشته باشد، برنامه‌ی شما باید با کلاس‌های جدید گزارش مجددا کامپایل شود.
  2. می‌توان گزارش را از طریق برنامه Designer به صورت اسمبلی ( dll ) ذخیره کرد.
    اشکال: این روش برای مدیریت گزارش‌ها در طول ارتقاء آن‌ها مفید نمی‌باشد.
  3. از گزارش کامپایل شده استفاده نکنید و به جای آن از تفسیر عبارات در گزارش استفاده کنید. برای فعالسازی این حالت، خصوصیت Calculation Mode گزارش را در پنجره خصوصیت‌ها در برنامه Designer بر روی Interpretation قرار دهید.
    اشکال: این روش به این معنی است که تمامی اصطلاحات زبان C# / VB.NET تفسیر نمی‌شوند. همچنین استفاده از رخدادهای مربوط به اجزاء گزارش غیرممکن می‌باشد.
  4. کامپایل و رندر گزارش، در دامنه‌ی برنامه‌ی دیگری انجام شود. در این مورد می‌توان پس از رندر گزارش، اسمبلی را در دامنه‌ی برنامه جاری بارگذاری کرد و فایل قفل شده‌ی آن، بعدا حذف خواهد شد. با استفاده از متد ()CreateReportInNewAppDomain از کلاس StiReport می‌توان گزارش را ایجاد کرد و با استفاده از متد ()UnloadReportAppDomain آن را بارگذاری کرد.
    اشکال در این روش متدهای RegData و RegBusinessObject با سرعت خیلی کمی اجرا می‌شوند؛ چرا که هدایت داده‌ها به دامنه‌ی دیگری استفاده شده است. ایجاد و بارگذاری در دامنه‌ی برنامه نیازمند زمان می‌باشد.
  5. کارآمدترین روش: کامپایل گزارش تنها در زمان اولین فراخوانی انجام شود و هر زمان که درخواست فراخوانی گزارش انجام می‌شود، گزارش را از اسمبلی کامپایل شده، در حافظه بارگذاری می‌کنیم. در این مورد تنها یک کپی از گزارش در حافظه ذخیره می‌شود و تنها یک اسمبلی در درایو وجود دارد. پوشه مربوط به گزارش‌های کامپایل شده می‌تواند قبل از استفاده از گزارشات حذف شود، چرا که در اولین درخواست گزارش، دوباره ایجاد خواهد شد.
    مثال:
var report = new StiReport();
report.Load( "Report.mrt" );

var folder = Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData );
folder = Path.Combine( folder, "Stimulsoft\\CompiledReports" );
folder = Path.Combine( folder, System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion() );
var compiledReportFile = Path.Combine( folder, report.GetReportAssemblyCacheName() );

if ( File.Exists( compiledReportFile ) )
    report = StiReport.GetReportFromAssembly( compiledReportFile, true );
else
{
    if ( !Directory.Exists( folder ) ) Directory.CreateDirectory( folder );
    report.Compile( compiledReportFile );
}

report.RegBusinessObject( "TestData", new { Title = "Vahid " + DateTime.Now.Millisecond } );

report.Render( false );
همانطور که در مثال بالا مشاهده کنید، یک گزارش ساخته می‌شود و در صورت عدم وجود فایل کامپایل شده و یا تغییر در فایل گزارش، مجددا فایل گزارش با نام جدیدی کامپایل شده و نمایش داده می‌شود.
نکته: حتما بارگذاری دیتا مربوط به گزارش را بعد از عملیات کامپایل قراردهید.