مطالب
intern pool جدول نگهداری رشته‌ها در دات‌نت
کد زیر را در نظر بگیرید :
object text1 = "test";
object text2 = "test";

object num1 = 1;
object num2 = 1;

Console.WriteLine("text1 == text2 : " + (text1 == text2));
Console.WriteLine("num1 == num2 : " + (num1 == num2));

به نظر شما چه چیزی در خروجی نمایش داده میشود؟

هر چهار متغییر text1  و text2 و num1 و num2 از نوع object هستند. با اینکه مقدار text1 و text2 یکی و مقدار num1 و num2 هم یکی است، نتیجه text1==text2 برابر true است اما num1==num2 برابر false.

خطی که text2 تعریف شده است را تغییر میدهیم :
object text2 = "test".ToLower();

اینبار با این که باز مقدار text1 و text2 یکی و هر دو "test" است، اما نتیجه text1==text2 برابر false است. انتظار ما هم همین است. دو object ایجاد شده است و یکی نیستند. تنها در صورتی باید نتیجه == آنها true باشد که هر دو به یک object اشاره کنند.

اما چرا در کد اولی اینگونه نبود؟

دلیل این کار برمیگردد به رفتار دات‌نت نسبت به رشتههایی که به صورت صریح در برنامه تعریف میشوند. CLR یک جدول برای ذخیره رشتهها به نام intern pool برای برنامه میسازد. هر رشتهای تعریف میشود، اگر در intern pool رشتهای با همان مقدار وجود نداشته باشد، یک رشته جدید ایجاد و به جدول اضافه میشود، و اگر موجود باشد متغییر جدید فقط به آن اشاره میکند. در واقع اگر 100 جای برنامه حتی در کلاسهای مختلف، رشتههایی با مقادیر یکسان وجود داشته باشند، برای همه آنها یک نمونه وجود دارد.

بنابراین text1 و text2 در کد اولی واقعا یکی هستند و یک نمونه برای آنها ایجاد شده است.

البته چند نکته در اینجا هست :
اگر text1 و text2 به صورت string تعریف شوند، نتیجه text1==text2 در هر دو حالت فوق برابر true است. چون عملگر == در کلاس string یکبار دیگر overload شده است:
public sealed class String : ...
{
    ...
    public static bool operator ==(string a, string b)
    {
      return string.Equals(a, b);
    }
   ...
}

این که کدام یک از overload‌ها اجرا شوند (کلاس پایه، کلاس اصلی، ...) به نوع دو متغییر اطراف == بستگی دارد. مثلا در کد زیر :
string text1 = "test";
string text2 = "test".ToLower();

Console.WriteLine("text1 == text2 (string) : " + (text1 == text2));
Console.WriteLine("text1 == text2 (object) : " + ((object)text1 == (object)text2));

اولین نتیجه true و دومی false است. چون در اولی عملگر == تعریف شده در کلاس string مورد استفاده قرار می‏‏گیرد اما در دومی عملگر == تعریف شده در کلاس object.

اگر دقت نشود این رفتار مشکلزا میشود. مثلا حالتی را در نظر بگیرید که text1 ورودی کاربر است و text2 از بانک اطلاعاتی خوانده شده است و با اینکه مقادیر یکسان دارند نتیجه == آنها false است. اگر تعریف عملگرها در کلاس object به صورت virtual بود و در کلاس‌های دیگر override می‌شد، این تغییر نوع‌ها تاثیری نداشت. اما عملگرها به صورت static تعریف می‌شوند و امکان override شدن ندارند. به همین خاطر کلاس object متدی به اسم Equals در اختیار گذاشته که کلاس‌ها آنرا override می‌کنند و معمولا از این متد برای سنجش برابری دو کلاس استفاده می‌شود :
object text1 = "test";
object text2 = "test".ToLower();

Console.WriteLine("text1 Equals text2 : " + text1.Equals(text2));
Console.WriteLine("text1 Equals text2 : " + object.Equals(text1, text2));

البته یادآور می‌شوم که فقط رشته‌هایی که به صورت صریح در برنامه تعریف شده‌اند، در intern pool قرار می‌گیرند و این فهرست شامل رشته‌هایی که از فایل یا بانک اطلاعاتی خوانده می‌شوند یا در برنامه تولید می‌شوند، نیست. این کار منطقی است وگرنه حافظه زیادی مصرف خواهد شد.

با استفاده از متد string.Intern می‌توان یک رشته را که در intern pool وجود ندارد، به فهرست آن افزود. اگر رشته در intern pool وجود داشته باشد، reference آنرا بر می‌گرداند در غیر اینصورت یک reference به رشته جدید به intern pool اضافه می‌کند و آنرا برمی‌گرداند.

یک مورد استفاده آن هنگام lock روی رشته‌هاست. برای مثال در کد زیر DeviceId یک رشته است که از بانک اطلاعاتی خوانده می‌شود و باعث می‌شود که چند job همزمان به یک دستگاه وصل نشوند :
lock (job.DeviceId)
{
    job.Execute();
}

اگر یک job با DeviceId برابر COM1 در حال اجرا باشد، این lock جلوی اجرای همزمان job دیگری با همین DeviceId را نمی‌گیرد. زیرا هر چند مقدار DeviceId دو job یکی است ولی به یک نمونه اشاره نمی‌کنند.

می‌توان lock را اینگونه اصلاح کرد :
lock (string.Intern(job.DeviceId))
{
    job.Execute();
}

بازخوردهای پروژه‌ها
راهنمایی برای دستورات for .use.جهت Initialize کردن ObjectFactory
من سرویس‌ها و اینترفیسهای مربوطه و مپینگ بین ویومدلها و کلاسهای POCO ی خودم را بشکل فایلهای پروفایل کامل کردم و با استفاده از StructureMap و مقالات تزریق وابستگی برای جدولی شبیه به Applicant (متقاضی) توانستم جواب بگیرم: 
استفاده از StructureMap به عنوان یک IoC Container
 خیلی شیوا روند کار را بیان کرده ولی برای کلاسی شبیه به Address (که یک ارتباط یک به چند با Applicant دارد ) که این کلاس جدید را خودم ایجاد کرده ام خطای No default Instance is registered and cannot be automatically determined for type را دریافت می‌کنم در سایت جستجو کردم و علت را متوجه شدم یعنی عدم وجود جملاتی مثل  
ObjectFactory.Initialize(x =>
{
  x.For<IEmailsService>().Use<EmailsService>();
  x.For<IUsersService>().Use<UsersService>();
});
در صورتی که آقای مهندس ربال این بخش را مثل کدهای بالا ننوشته اند و من ممنون میشم اگه باز راهنمایی بفرمایید.
نظرات مطالب
مدیریت Instance در WCF
سلام
یه سوالی برام پیش اومده ممنون میشم راهنمایی فرمایید:
من یک سرویس WCF  ایجاد کردم  و اونو به شکل زیر تنظیم کردم :
 [ServiceContract(SessionMode=SessionMode.Reqquired)]
 و همچنین برای کلاس پیاده سازی کننده اینترفیس :
 [ServiceBehavior( InstanceContextMode = InstanceContextMode.PerSession)]
من داخل این کلاس یه متغیر از یک کلاس به صورت سراسری تعریف کردم که میخوام ازش توی متدهای متفاوت استفاده کنم اما ظاهرا با هر بار فراخوانی باز هم این متغیر داده‌های خودشو ازدست میده البته static نیست و به دلیل ساختار اون نمیتونم استاتیکش کنم
ممنون میشم راهنمایی نمایید
مطالب
9# آموزش سیستم مدیریت کد Git : کار به صورت remote
تا اینجا هر آنچه درباره git آموختیم در رابطه با عملکرد git به صورت محلی بود. اما یکی از ویژگی‌های سیستم‌های توزیع شده، امکان استفاده از آن‌ها به صورت remote می‌باشد.
در مورد git تفاوت چندانی بین سرور‌ها و کلاینت‌ها وجود ندارد. تنها تفاوت، نحوه‌ی پیکربندی سرور است که این امکان را می‌دهد تا چندین کلاینت به صورت همزمان به آن متصل شده و با repository آن کار کنند. اما عملا تفاوتی بین repository موجود در کلاینت و سرور نیست.
تذکر ۱: در این مقاله از وب سایت github برای توضیح مثال‌ها استفاده شده است. github قدیمی‌ترین و قدرتمندترین وب سایت برای مدیریت repository‌های git است. اما اجباری در انتخاب آن نیست؛ زیرا انتخاب‌های فراوانی از جمله bitbucket   نیز وجود دارد.
تذکر ۲: نام مستعار origin اجباری نیست؛ اما از آن جهت که نام پیش فرض است، در اکثر مثال‌ها و توضیحات استفاده شده است.
قبل از شروع مبحث بهتر است کمی درباره‌ی پروتکل‌های ارتباطی پشتیبانی شده توسط git صحبت کنیم:
git از ۴ نوع پروتکل پشتیبانی می‌کند:
۱) (http(s: پروتکل http با پورت ۸۰ و https با پورت ۴۴۳ کار می‌کند و معمولا فایروال‌ها مشکلی با این پروتکل‌ها ندارند. از هر دوی آن‌ها می‌توان برای عملیات نوشتن و یا خواندن استفاده نمود و می‌توان آن‌ها را به گونه‌ای تنظیم کرد که برای برقراری ارتباط نیاز به تائید هویت داشته باشند.
۲) git: پروتکلی فقط خواندنی است که به صورت  anonymous و بر روی پورت ۹۴۱۸ کار می‌کند. شکل استفاده از آن به صورت زیر است و معمولا در github کاربرد فراوانی دارد:
git://github.com/[username]/[repositoryname].git
۳) ssh: همان پروتکل استفاده شده در یونیکس است که بر اساس مقادیر کلیدهای عمومی و خصوصی تعیین هویت را انجام می‌دهد. شکل استفاده از آن به صورت زیر است و بر روی پورت ۲۲ کار می‌کند و امکان نوشتن و خواندن را می‌دهد:
git@github.com:[username]/[repositoryname].git
۴) file: تنها استفاده محلی دارد و امکان نوشتن و خواندن را می‌دهد.

نحوه‌ی عملکرد git به صورت remote:
به طور کلی هر برنامه‌نویس نیاز به دو نوع از دستورات دارد تا همواره repository محلی با remote هماهنگ باشد:
۱) بتواند به طریقی داده‌های موجود در repository محلی خود را به سمت سرور بفرستد.
۲) این امکان را داشته باشد تا repository محلی خود را با استفاده از repository در سمت سرور آپدیت نماید تا از آخرین تغییراتی که توسط بقیه اعضای گروه صورت گرفته است آگاهی یابد.

طریقه رفتار git برای کار با repository‌های remote به صورت زیر است:
هنگامی‌که کاربر قصد دارد تا repository یا شاخه‌ای از آن را به سمت سرور بفرستد، git ابتدا یک شاخه با نام همان شاخه به اضافه /origin ایجاد می‌کند. مثلا برای شاخه master، آن نام به صورت زیر می‌شود:
origin/master
عملکرد این شاخه دقیقا مانند دیگر شاخه‌های git است؛ با این تفاوت که امکان check-in یا out برای این نوع شاخه‌ها وجود ندارد. زیرا git باید این شاخه‌ها را با شاخه‌ها متناظرشان در remote هماهنگ نگه دارد.
از این پس این شاخه‌ی ایجاد شده، به عنوان واسطی بین شاخه محلی و شاخه راه دور عمل می‌کند.

cloning:
با استفاده از دستور clone می‌توان یک repository در سمت سرور را به طور کامل در سمت کلاینت کپی کرد. به عنوان مثال repository مربوط به کتابخانه jquery از وب سایت github به صورت زیر است:
git clone https://github.com/jquery/jquery.git
همچنین می‌توان با استفاده از دستور زیر پوشه‌ای با نامی متفاوت را برای repository محلی انتخاب نمود:
git clone [URL][directory name]

اضافه کردن یک remote repository:
برای آن‌که بتوان تغییرات یک remote repository را به repository محلی منتقل نمود، ابتدا باید آن را به لیست repository‌های ریموت که در فایل config. ذخیره می‌شود به شکل زیر اضافه نمود:
git remote add [alias][URL]
در دستور فوق، برای repository باید یک نام مستعار تعریف کرد و در بخش URL باید آدرسی که سرور به وسیله آن امکان دریافت اطلاعات را به ما می‌دهد، نوشت. البته این بستگی به نوع پروتکل انتخابی دارد. به عنوان مثال:
git remote add origin https://github.com/jquery/jquery.git
اگر بخواهیم لیست repository‌هایی که به صورت remote اضافه شده‌اند را مشاهده کنیم، از دستور زیر استفاده می‌کنیم:
git remote
در صورتی‌که دستور فوق را با v- تایپ کنید اطلاعات کامل‌تری در رابطه با repository‌ها مشاهده خواهید کرد.
همچنین برای حذف یک remote repository از دستور زیر استفاده می‌‌کنیم:
git remote [alias] -rm
در صورتی‌که بخواهید لیستی از شاخه‌های remote را مشاهده کنید کافیست از دستور زیر استفاده کنید:
git branch -r
همچنین می‌توان از دستور زیر برای نمایش تمامی شاخه‌ها استفاده کرد:
git branch -a

fetch:
برای دریافت اطلاعات از دستور زیر استفاده می‌کنیم:
git fetch [alias][alias/branch name]
در صورتی‌که تنها یک repository باشد می‌توان از نوشتن نام مستعار صرفنظر نمود. همچنین اگر شاخه یا شاخه‌های مورد نظر به صورت track شده باشند، می‌توان قسمت دوم دستور فوق را نیز ننوشت.
اگر بعد از اجرای دستور فوق، بر روی یک شاخه log بگیرید، خواهید دید که تغییرات در شاخه محلی اعمال نشده است زیرا دستور فوق تنها داده‌ها را بر روی شاخه [origin/[branchname ذخیره کرده است. برای آپدیت شدن شاخه اصلی باید با استفاده از دستور merge آن را در شاخه مورد نظر ادغام کرد.

pulling:
چون کاربرد دو دستور fetch و merge به صورت پشت سر هم زیاد است git دو دستور فوق را با استفاده از pull انجام می‌دهد:
pull [alias][remote branch name ]
اگر دو مقدار فوق را برای دستور pull تعیین نکنید، ممکن است در هنگام اجرای دستور فوق با خطایی مواجه شوید مبنی بر اینکه git نمی‌داند دقیقا شاخه ریموت را با کدام شاخه محلی باید ادغام کند. این مشکل زمانی پیش می‌آید که برای شاخه ریموت یک شاخه محلی متناظر وجود نداشته باشد. برای ایجاد تناظر بین دو شاخه ریموت و لوکال درگذشته باید فایل config. را تغییر می‌دادیم، اما نسخه جدید git دستوری را برای آن دارد:
git branch --set-upstream [local brnach][alias/branch name]
با اجرای این دستور از این پس شاخه محلی تغییرات شاخه remote را دنبال می‌کند.

pushing:
با استفاده از push می‌توان تغییرات ایجاد شده را به remote repository انتقال داد:
git push -u [alias][branch name ]
وجود u- در اینجا بدین معنا است که ما میخواهیم تغییرات repository در سمت سرور دنبال شود. در صورت استفاده نکردن از u- بایستی برای push هر بار مقادیر داخل کروشه‌ها را بنویسیم. در صورتی‌که بعدا بخواهیم، می‌توان توسط همان دستوری که در قسمت pull گفته شد دو شاخه را به هم وابسته کنیم.
tag:
همانطور که قبلا گفته شد تگ‌ها برای نشانه‌گذاری و دسترسی راحت‌تر به به commitها هستند. برای ایجاد یک تگ از دستور زیر استفاده می‌شود:
git tag [tag name]
همچنین می‌توان با a- برای تگ پیامی نوشت و یا با s- آن را امضا کرد. برای مشاهده تگ‌ها از دستور زیر استفاده می‌شود:
git tag
در حالت پیشفرض git تگ‌ها را push نمی‌کند. برای push کردن تگ‌ها باید دستور push را با اصلاح‌کننده tages-- به کارببرید.
مطالب
آشنایی با CLR: قسمت چهارم
در قسمت قبلی با اسمبلی‌ها تا حدی آشنا شدیم. امروز می‌خواهیم یاد بگیریم که چگونه اسمبلی‌ها در حافظه بارگذاری می‌شوند. همانطور که می‌دانید CLR مسئول اجرای کدهای داخل اسمبلی‌هاست. به همین دلیل یک نسخه‌ی دات نت فریم ورک هم باید در ماشین مقصد نصب باشد. به همین منظور مایکروسافت بسته‌های توزیع شونده‌ی دات نت فریمورک را فراهم کرده تا به سادگی بر روی سیستم مشتری نصب شوند و بعضی از ویندوزها نیز نسخه‌های متفاوتی از دات نت فریم ورک را شامل می‌شوند.
برای اینکه مطمئن شوید که آیا دات نت فریم ورک نصب شده است، می‌توانید در شاخه‌ی system32 سیستم، وجود فایل MSCorEE.dll را بررسی نمایید. البته بر روی یک سیستم می‌تواند نسخه‌های مختلفی از یک دات نت فریم ورک نصب باشد. برای آگاهی از اینکه چه نسخه‌هایی بر روی سیستم نصب است باید مسیرهای زیر را مورد بررسی قرار دهید:
%SystemRoot%\Microsoft.NET\Framework
%SystemRoot%\Microsoft.NET\Framework64

بسته‌ی دات نت فریمورک شامل ابزار خط فرمانی به نام CLRVer.exe می‌شود که همه‌ی نسخه‌های نصب شده را نشان می‌دهد. این ابزار با سوییچ all می‌تواند نشان دهد که چه پروسه‌هایی در حال حاضر دارند از یک نسخه‌ی خاص استفاده می‌کنند. یا اینکه ID یک پروسه را به آن داده و نسخه‌ی در حال استفاده را بیابیم.

قبل از اینکه پروسه‌ی بارگیری یک اسمبلی را بررسی کنیم، بهتر است به نسخه‌های 32 و 64 بیتی ویندوز، نگاهی بیندازیم:
یک برنامه در حالت عمومی بر روی تمامی نسخه‌ها قابل اجراست و نیازی نیست که توسعه دهنده کار خاصی انجام دهد. ولی اگر توسعه دهنده نیاز داشته باشد که برنامه را محدود به پلتفرم خاصی کند، باید از طریق برگه build در projectProperties در قسمت PlatformTarget معماری پردازنده را انتخاب کند:

موقعیکه گزینه برای روی anyCPU تنظیم شده باشد و تیک گزینه perfer 32-bit را زده باشید، به این معنی است که بر روی هر سیستمی قابل اجراست؛ ولی اجرا به شیوه‌ی 32 بیت اصلح است. به این معنی که در یک سیستم 64 بیت برنامه را به شکل 32 بیت بالا می‌آورد.
بسته به پلتفرمی که برای توزیع انتخاب می‌کنید، کامپایلر به ساخت اسمبلی‌های با هدرهای (+)P32 می‌پردازد. مایکروسافت دو ابزار خط فرمان را به نام‌های DumpBin .exe و CoreFlags .exe در راستای آزمایش و بررسی هدرهای تولید شده توسط کامپایلر ارائه کرده است.
موقعی که شما یک فایل اجرایی را اجرا می‌کنید، ابتدا هدرها را خوانده و طبق اطلاعات موجود تصمیم می‌گیرد برنامه به چه شکلی اجرا شود. اگر دارای هدر p32 باشد قابل اجرا بر روی سیستم‌های 32 و 64 بیتی است و اگر +PE32 باشد روی سیستم‌های 64 بیتی قابل اجرا خواهد بود. همچنین به بررسی معماری پردازنده که در قسمت هدر embed شده، پرداخته تا اطمینان کسب کند که با خصوصیات پردازنده مقصد مطابقت می‌کند.
نسخه‌های 64 بیتی ارائه شده توسط مایکروسافت دارای فناوری به نام WOW64 یا Windows On Windows64 هستند که اجازه‌ی اجرای برنامه‌های 32 بیت را روی نسخه‌های 64 بیتی، می‌دهند.
جدول زیر اطلاعاتی را ارائه میکند که در حالت عادی برنامه روی چه سیستم‌هایی ارائه شده است و اگر آن‌را محدود به نسخه‌های 32 یا 64 بیتی کنیم، نحوه‌ی اجرا آن بر روی سایر پلتفرم‌ها چگونه خواهد بود.


بعد از اینکه هدر مورد آزمایش قرار گرفت و متوجه شد چه نسخه‌ای از آن باید اجرا شود، بر اساس نسخه‌ی انتخابی، یک از نسخه‌های MSCorEE سی و دو بیتی یا 64 بیتی یا ARM را که در شاخه‌ی system32 قرار دارد، در حافظه بارگذاری می‌نماید. در نسخه‌های 64 بیتی ویندوز که نیاز به MSCorEE نسخه‌های 32 بیتی احساس می‌شود، در آدرس زیر قرار گرفته است:
%SystemRoot%\SysWow64
بعد از آن ترد اصلی پروسه، متدی را در MSCorEE صدا خواهد زد که موجب آماده سازی CLR بارگذاری اسمبلی اجرایی EXE در حافظه و صدا زدن مدخل ورودی برنامه یعنی متد Main می‌گردد. به این ترتیب برنامه‌ی مدیریت شده (managed) شما اجرا می‌گردد.
مسیرراه‌ها
ASP.NET MVC
              پاسخ به بازخورد‌های پروژه‌ها
              درخواست مستندات
              - طراحی گزارش برای کاربرنهایی زمانی معنا پیدا می‌کند که بتواند جداول و فیلدها را هم بصری انتخاب کند. وگرنه کاربری که می‌تواند SQL بنویسد، شاید نیازی به کار برنامه نویس نداشته باشد.
              + اینکار نیازی به فایل XML ندارد. طراحی فعلی شما یک حالت خاص از گزارشات PdfReport است. قسمت‌های متغیر آن‌را تبدیل به یک سری خاصیت متغیر کنید در گزارش نهایی؛ تا کاربر بتواند آن‌ها را پر کند یا تغییر دهد. پشت صحنه آن یک فایل cs است (مزیت code first بودن آن)، UI آن یک سری فیلد متغیر. این‌ها را در دیتابیس هم می‌شود ذخیره کرد.
              بازخوردهای پروژه‌ها
              عدم نمایش سطر آخر رکورد در pdf
              سلام..مشکلی که دارم اینه که خروجی pdf من سطر آخررکودهای خروجی  رو توی فایل pdf بر نمیگردونه.چک کردم dt من مشکلی نداره..میخواستم راهنمایی کنید..

              کد‌های من :
              public IPdfReportData CreatePdfReport(DataTable dt,string OrganName,string DateFrom,string DateEnd,string FilePath)
                      {
                          FileStream fo = new FileStream(FilePath, FileMode.Create);
                          fo.Close();
                          return new PdfReport().DocumentPreferences(doc =>
                          {
                              doc.RunDirection(PdfRunDirection.RightToLeft);
                              doc.Orientation(PageOrientation.Portrait);
                              doc.PageSize(PdfPageSize.A4);
                              doc.DocumentMetadata(new DocumentMetadata { Author = "AjansDaneshjo", Application = "PdfRpt", Keywords = "Report", Subject = "Test Rpt", Title = "Report" });
                          })
                          .DefaultFonts(fonts =>
                          {
                              fonts.Path(Application.StartupPath+"\\BNAZANIN.ttf", Application.StartupPath + "\\BNAZNNBD.ttf");
                              fonts.Size(13);
                          })
                          .PagesFooter(footer =>
                          {
                              footer.DefaultFooter(PersianDate.ToPersianDateTime(DateTime.Now, "/", false, false));
                          })
                          .PagesHeader(header =>
                          {
                              header.CustomHeader(new MasterDetailsHeaders { PdfRptFont = header.PdfFont ,DateFrom=DateFrom,DateTo= DateEnd,ProjTitle=ProjTitle });
                          })
                          .MainTableTemplate(template =>
                          {
                              template.BasicTemplate(BasicTemplate.SilverTemplate);
                          })
                          .MainTablePreferences(table =>
                          {
                              table.ColumnsWidthsType(TableColumnWidthType.Relative);
                              table.NumberOfDataRowsPerPage(50);
                              table.GroupsPreferences(new GroupsPreferences
                              {
                                  GroupType = GroupType.HideGroupingColumns,
                                  RepeatHeaderRowPerGroup = true,
                                  ShowOneGroupPerPage = true,
                                  SpacingBeforeAllGroupsSummary = 5f
                              });
                          })
                          .MainTableDataSource(dataSource =>
                          {
                              dataSource.DataTable(dt);
                          })
                          .MainTableSummarySettings(summarySettings =>
                          {
                              summarySettings.OverallSummarySettings(" جمع کل ");
                              summarySettings.PageSummarySettings("جمع صفحه");
                          })
                          .MainTableColumns(columns =>
                          {
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("rowNo");
                                  column.IsRowNumber(true);
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(0);
                                  column.Width(1);
                                  column.HeaderCell("ردیف");
                              });
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("Name_Family");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(1);
                                  column.Width(2);
                                  column.HeaderCell("در اختیار");
                                  column.ColumnItemsTemplate(template =>
                                  {
                                      template.TextBlock();
                                      template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj));
                                  });
              
                              });
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("DateAjans");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(2);
                                  column.Width(2);
                                  column.HeaderCell("تاریخ");
                                  column.ColumnItemsTemplate(template =>
                                  {
                                      template.TextBlock();
                                      template.DisplayFormatFormula(obj => obj == null ? string.Empty : PersianDate.ToPersianDateTime((DateTime)obj,"/",false,false) );
                                  });
                              });
              
                              
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("Receipt_number");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(3);
                                  column.Width(2);
                                  column.HeaderCell("شماره قبض");
              
                              });
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("Price");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(5);
                                  column.Width(2);
                                  column.HeaderCell("مبلغ");
                                  column.ColumnItemsTemplate(template =>
                                  {
                                      template.TextBlock();
                                      template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj));
                                  });
                                  column.AggregateFunction(aggregateFunction =>
                                  {
                                      aggregateFunction.NumericAggregateFunction(AggregateFunction.Sum);
                                      aggregateFunction.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0} ریال", obj));
                                  });
                              });
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("Organ_Name");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(5);
                                  column.Width(2);
                                  column.HeaderCell("نام سازمان");
                                  column.Group(true,
                                  (val1, val2) =>
                                  {
                                      return val1.ToString() == val2.ToString();
                                  });
                                  
                              });
              
              
                              columns.AddColumn(column =>
                              {
                                  column.PropertyName("Destination");
                                  column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                                  column.IsVisible(true);
                                  column.Order(4);
                                  column.Width(2);
                                  column.HeaderCell("مقصد");
              
                              });
                          })
                          .MainTableEvents(events =>
                          {
                              events.DataSourceIsEmpty(message: "There is no data available to display.");
                          })
                          .Export(export =>
                          {
                              export.ToExcel();
                          })
                          .Generate(data => data.AsPdfFile(fo.Name/*string.Format("{0}\\RptCalculatedFieldsSample-{1}.pdf", Application.StartupPath, Guid.NewGuid().ToString("N")))*/));
                      }

              کلاس MasterDetailsHeaders  :
              public  class MasterDetailsHeaders : IPageHeader
                  {
                      public IPdfFont PdfRptFont { set; get; }
                      public string DateFrom;
                      public string DateTo;
                      public string ProjTitle;
                      public PdfGrid RenderingGroupHeader(Document pdfDoc, PdfWriter pdfWriter, IList<CellData> newGroupInfo, IList<SummaryCellData> summaryData)
                      {
                         
                          var table = new PdfGrid(numColumns: 1) { WidthPercentage = 100 };
                          var organName = newGroupInfo.GetSafeStringValueOf("Organ_Name");
                          table.AddSimpleRow(
                              (cellData, cellProperties) =>
                              {
                                  cellData.Value = " گزارش " + organName + " از تاریخ " + DateFrom + " الی " + DateTo;
                                  cellProperties.PdfFont = PdfRptFont;
                                  cellProperties.PdfFontStyle = DocumentFontStyle.Bold;
                                  cellProperties.HorizontalAlignment = HorizontalAlignment.Center;
                                  cellProperties.RunDirection = PdfRunDirection.RightToLeft;
                              });
                          return table.AddBorderToTable(borderColor: BaseColor.LIGHT_GRAY, spacingBefore: 5f);
                      }
                    public  PdfGrid RenderingReportHeader(Document pdfDoc, PdfWriter pdfWriter, IList<SummaryCellData> summaryData)
                      {
                          return null;
                      }

              مطالب
              کامپایل پویای کد در دات نت

              در دات نت فریم ورک امکان کامپایل پویای یک قطعه کد دریافت شده از یک رشته، توسط فضای نام CodeDom مهیا است که قدرت قابل توجهی را در اختیار برنامه نویس قرار می‌دهد.

              مثال یک:
              رشته زیر را کامپایل کرده و تبدیل به یک فایل exe کنید:

              string source =
              @"
              namespace Foo
              {
              public class Bar
              {
              static void Main(string[] args)
              {
              Bar.SayHello();
              }

              public static void SayHello()
              {
              System.Console.WriteLine(""Hello World"");
              }
              }
              }
              ";
              روش انجام کار به همراه توضیحات مربوطه به صورت کامنت:

              using System;
              using System.Collections.Generic;
              //دو فضای نامی که برای این منظور اضافه شده‌اند
              using Microsoft.CSharp;
              using System.CodeDom.Compiler;

              namespace compilerTest
              {
              class Program
              {
              static void compileIt1()
              {
              //سورس کد ما جهت کامپایل
              string source =
              @"
              namespace Foo
              {
              public class Bar
              {
              static void Main(string[] args)
              {
              Bar.SayHello();
              }

              public static void SayHello()
              {
              System.Console.WriteLine(""Hello World"");
              }
              }
              }
              ";

              //تعیین نگارش کامپایلر مورد استفاده
              Dictionary<string, string> providerOptions = new Dictionary<string, string>
              {
              {"CompilerVersion", "v3.5"}
              };
              //تعیین اینکه کد ما سی شارپ است
              CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);

              //تعیین اینکه خروجی یک فایل اجرایی است بعلاوه مشخص سازی محل ذخیره سازی فایل نهایی
              CompilerParameters compilerParams = new CompilerParameters
              {
              OutputAssembly = "D:\\Foo.EXE",
              GenerateExecutable = true
              };

              //عملیات کامپایل در اینجا صورت می‌گیرد
              CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

              //اگر خطایی وجود داشته باشد نمایش داده خواهد شد
              Console.WriteLine("Number of Errors: {0}", results.Errors.Count);
              foreach (CompilerError err in results.Errors)
              {
              Console.WriteLine("ERROR {0}", err.ErrorText);
              }
              }

              static void Main(string[] args)
              {
              compileIt1();

              Console.WriteLine("Press a key...");
              Console.ReadKey();
              }
              }
              }
              مثال 2:
              کد مورد نظر را به صورت یک فایل dll کامپایل کنید.
              برای این منظور تمامی مراحل مانند قبل است فقط GenerateExecutable ذکر شده به false تنظیم شده و نام خروجی نیز به foo.dll باید تنظیم شود.


              مثال 3:
              کد مورد نظر را در حافظه کامپایل کرده (خروجی dll یا exe نمی‌خواهیم)، سپس متد SayHello آن را به صورت پویا فراخوانی نموده و خروجی را نمایش دهید.
              در این حالت روش کار همانند مثال 1 است با این تفاوت که GenerateInMemory = true و GenerateExecutable = false تنظیم می‌شوند. همچنین جهت دسترسی به متد کلاس ذکر شده،‌ از قابلیت‌های ریفلکشن موجود در دات نت فریم ورک استفاده خواهد شد.

              using System;
              using System.Collections.Generic;
              using Microsoft.CSharp;
              using System.CodeDom.Compiler;
              using System.Reflection;

              namespace compilerTest
              {
              class Program
              {
              static void compileIt2()
              {
              //سورس کد ما جهت کامپایل
              string source =
              @"
              namespace Foo
              {
              public class Bar
              {
              static void Main(string[] args)
              {
              Bar.SayHello();
              }

              public static void SayHello()
              {
              System.Console.WriteLine(""Hello World"");
              }
              }
              }
              ";

              //تعیین نگارش کامپایلر مورد استفاده
              Dictionary<string, string> providerOptions = new Dictionary<string, string>
              {
              {"CompilerVersion", "v3.5"}
              };
              //تعیین اینکه کد ما سی شارپ است
              CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);

              //نحوه تعیین مشخص سازی کامپایل در حافظه
              CompilerParameters compilerParams = new CompilerParameters
              {
              GenerateInMemory = true,
              GenerateExecutable = false
              };

              //عملیات کامپایل در اینجا صورت می‌گیرد
              CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

              // اگر خطایی در کامپایل وجود نداشت متد دلخواه را فراخوانی می‌کنیم
              if (results.Errors.Count == 0)
              {
              //استفاده از ریفلکشن برای دسترسی به متد و فراخوانی آن
              Type type = results.CompiledAssembly.GetType("Foo.Bar");
              MethodInfo method = type.GetMethod("SayHello");
              method.Invoke(null, null);
              }
              }


              static void Main(string[] args)
              {
              compileIt2();

              Console.WriteLine("Press a key...");
              Console.ReadKey();
              }
              }
              }
              نکته: نحوه‌ی استفاده از اسمبلی‌های دیگر در رشته سورس کد خود
              مثال:
              اگر رشته سورس ما به صورت زیر بوده و از اسمبلی System.Drawing.Dll نیز کمک گرفته باشد،‌

              string source =
              @"
              namespace Foo
              {

              public class Bar
              {
              static void Main(string[] args)
              {
              Bar.SayHello();
              }

              public static void SayHello()
              {
              System.Console.WriteLine(""Hello World"");
              var r = new System.Drawing.Rectangle(0,0,100,100);
              System.Console.WriteLine(r);
              }
              }
              }
              ";
              هنگام کامپایل آن توسط روش مثال یک، با خطای زیر مواجه خواهیم شد.

              Number of Errors: 1
              ERROR The type or namespace name 'Drawing' does not exist in the namespace 'System' (are you missing an assembly reference?)

              برای رفع این مشکل و معرفی این اسمبلی،‌ سطر زیر باید پس از تعریف compilerParams اضافه شود.

              compilerParams.ReferencedAssemblies.Add("System.Drawing.Dll");
              اکنون کد کامپایل شده و مشکلی نخواهد داشت.
              نمونه‌ای دیگر از این دست، استفاده از LINQ می‌باشد. در این حالت اسمبلی System.Core.Dll نیز به روش ذکر شده باید معرفی گردد تا مشکلی در کامپایل کد رخ ندهد.


              کاربردها:
              1- استفاده در ابزارهای تولید کد (برای مثال در برنامه Linqer از این قابلیت استفاده می‌شود)
              2- استفاده‌های امنیتی (ایجاد روش‌های تولید یک سریال به صورت پویا و کامپایل پویای کد مربوطه در حافظه‌ای محافظت شده)
              3- استفاده جهت مقاصد محاسباتی پیشرفته
              4- دادن اجازه‌ی کد نویسی به کاربران برنامه‌ی خود (شبیه به سیستم‌های ماکرو و اسکریپت نویسی موجود)
              و ...

              نظرات مطالب
              ویدیوهای آموزشی QT
              اول تشکر می کنم بابت زحمتی که برای جمع اوری این آموزش کشیدید.
              دوم یه سوالی داشتم. من فایل ها رو از هات فایل دانلود کردم ، اما مشکلی که دارم این که شماره فایل ها به عنوان پسوند فایل قرار گرفته و خوب بالطبع نمی تونم با برنامه وینرر بازشون کنم. باید چی کار کنم؟ ممنون میشم کمک کنید.