نظرات مطالب
معرفی ASP.NET Identity
با سلام.
بنده می‌خواستم بدونم آیا در .NET ورژن 4 هم میتوانیم استفاده کنیم؟
با ویژوال استادیو 2012
بازخوردهای پروژه‌ها
عدم اجرای پروژه در VS 2012
سلام،
پروژه رو توی ویژوال استدیو 2012 وقتی Debug میکنم اجرا نمیشه، هر بار هم روی پورت 18600 اجرا میشه، تصویر خطا :

مطالب
مقدمه‌ای بر بازسازی کد (Refactoring)
بازسازی کد یا  Refactoring، یکی از روال‌های بسیار مهم در حفظ کیفیت نرم افزار است. انجام به موقع و مداوم این روال در یک پروژه نرم افزاری، اثرات بلند مدت بسیار مثبتی را برای آن خواهد داشت. این نوشتار مقدمه کوتاهی بر مفاهیم ابتدایی و سوالاتی مهم در این زمینه است. 

تعریف بازسازی کد

از نظر لغوی Refactoring به معنی «بازسازی» است و در منابع مهندسی نرم افزار، بازسازی کد به صورت زیر تعریف شده است: 
بازسازی ساختار درونی یک نرم افزار که باعث سهولت در درک آن و سادگی نگهداری آن می‌شود، بدون تغییر رفتار بیرونی آن  
چند نکته در تعریف بالا قابل توجه است: 
  • Refactoring بازسازی است، نه بازنویسی
  • بازسازی مربوط به ساختار درونی یک نرم افزار است؛ نه رفتاری که مشتریان از یک نرم افزار یا کامپوننت انتظار دارند
  • حاصل بازسازی باید سهولت درک کد و سادگی نگهداری آن باشد 


چرا کد را بازسازی کنیم؟ 

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

1-  طراحی نرم افزار را بهبود می‌بخشد 

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

2-  درک کد را آسان‌تر می‌کند 

یکی از مزیت‌های کد خوب، درک آسان آن توسط سایر افراد است. هنگام بازسازی کد، با کدی مواجه هستیم که کار می‌کند، ولی نظم و طراحی درستی ندارد. درک آسان کد، یکی از کلیدی‌ترین نکات جهت سهولت نگهداری یک نرم افزار است.

 3- به یافتن خطاها کمک می‌کند 

یافتن تمامی باگ‌ها در زمان نوشتن یک کد، به نظر می‌رسد غیر ممکن باشد. اما اقدام به بازسازی کد می‌تواند قدمی باشد برای بازنگری و بهبود ساختار آن. زمانیکه ساختار کد خواناتر و منظم‌تر شد، یافتن برخی باگ‌ها نیز آسان‌تر خواهند شد. 

4-  سرعت توسعه را بالا می‌برد 

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

چه زمانی کد را بازسازی کنیم؟ 

روش‌های مختلفی برای زمان بندی انجام بازسازی کد مطرح است. یکی از پرکاربردترین زمان بندی‌ها برای انجام بازسازی کد به صورت زیر می‌باشد: 
  • زمانیکه امکان جدیدی اضافه می شود 
  • زمانیکه باگ یا اشکالی، رفع می شود 
  • زمان بازبینی کد یا Code review 
مطالب
معرفی و روش استفاده از Dispatcher در WPF
باید این سوال را از خودمان بپرسیم که اصلا چه نیازی به استفاده از Dispatcher در WPF می‌باشد و این که ما چه نیازی داریم با ساختمان Thread آشنا شویم؟

می‌دانید که در پروژه و نرم افزارهایی که توسعه داده می‌شوند بعضی مواقع مشاهده می‌کنیم قسمتی از برنامه نیاز به زمان یا پردازش بیشتری دارد تا عملیات خود را به اتمام برساند و رابط کاربری (User Interface) برنامه در این حین منتظر می‌ماند و یا به اصطلاح (Freeze) می‌شود تا یک پردازش طولانی به اتمام برسد و بعد رابط کاربری به کار خود ادامه می‌دهد و بعضی مواقع پنجره Windows explorer is not responding را مشاهده کرده‌اید که با کلیک بر روی Close the program از آن گذر می‌کنیم. در حالی که برنامه ما باید حالت Responsive  داشته باشد و نباید برنامه با یک‌چنین مواردی روبه رو شود.

ساختمان Thread :
تمامی اشیاء (Objects) در این مدل به دو گروه تقسیم بندی می‌شوند:
Single-Threaded Apartment
Multi-Threaded Apartment
ساختمان  Single-Threaded Apartment (STA) :

STA شامل فقط یک Thread می‌باشد و تمامی اشیاء در این ساختمان فقط می‌توانند متدی را که در این Thread صدا زده می‌شود دریافت کنند؛ یا به عبارتی دیگر هنگامیکه شیء به Thread ای متصل می‌شود دیگر شما قادر نخواهید بود اشیاء UI را به صورت مستقیم و یا از طریق Thread‌های دیگر تغییر دهید. لازم به ذکر است WPF از مدل STA پشتیبانی می‌کند که شامل نکات  زیر می‌باشد:
1. یک Thread در کل برنامه اجرا می‌شود و شامل همه Object‌های WPF می‌باشد.
2. عناصر یا المان‌های  WPF، قابلیت تنظیم Thread Affinity را دارند. منظور این می‌باشدکه Thread‌ها نمی‌توانند با یکدیگر ارتباط  برقرار کنند.
3. اشیاء WPF که قابلیت Thread Affinityرا دارند، از یک Object Dispatcher مشتق می‌شوند.
4. اشیاء WPF متعلق به Thread ای می‌باشند که توسط آن ایجاد شده است و Thread دیگر قادر به دسترسی مستقیم به این اشیاء نمی‌باشد.

ساختمان Multi-Threaded Apartment (MTA) :

MTA  شامل یک یا چندین Thread می‌باشد. تمامی اشیاء در این مدل می‌توانند از هر Thread ای فراخوانی شوند. در حقیقت رجیستر‌های CPU و Ram که در اختیار برنامه قرار داده شده تکه تکه می‌شوند و برنامه ما تعداد Thread‌های مورد نظر را اجرا می‌کند و یکی از راه حل‌های بر طرف کردن اینکه رابط کاربری ما در حالت انتظار باقی نماند استفاده از پردازش کارها بصورت غیر همزمان (Asynchronous) می‌باشد که در اصطلاح Multithreading نامیده می‌شود. 

WPF Dispatcher :

WPF از مدل STA پشتیبانی می‌کند. زمانیکه برنامه WPF  اجرا می‌شود، به طور خودکار یک Dispatcher Object ساخته می‌شود و متد Run صدا زده می‌شود و از آن برای آماده سازی صف پیام‌ها استفاده می‌شود که مدیریت یک صف از کارها بر عهده آن است و کارهای UI را در یک صف FIFO اجرا می‌کند. WPF یک Dispatcher را برای UI Thread ایجاد می‌کند. بنابراین شما نمی‌توانید یک dispatcher دیگر برای آن تعریف کنید. 

نکته : دیاگرام زیر نمایش می‌هد که تمامی اشیاء WPF از DispatcherObject مشتق شده‌اند.

نکته : زمانیکه برنامه WPF  اجرا می‌شود دو Thread ساخته می‌شود:
1.  UI Thread (Main Thread) 
2.  Render Thread
 

UI Thread : مسئولیت تمامی ورودی‌های کاربر، handle events, paints screen و اجرای کدهای برنامه را بر عهده دارد.

Render Thread : در Background اجرا می‌شود و برای Render صفحه نمایش WPF استفاده می‌شود.

نکته: همانطور که آشنا شدیم WPF نمی‌تواند UI Thread را از طریق یک Thread دیگر به روز رسانی کند و یا به عبارتی دیگر یک Thread نمی‌تواند بصورت مستقیم به اشیایی که توسط Thread دیگر ایجاد شده، دسترسی داشته باشد.

Dispatcher برای این کار دو متد را در اختیار ما قرار می‌دهد :

متد Invoke : یک Action یا Delegate را میگیرد و متد آن‌را به صورت همزمان اجرا می‌کند. این مورد به این معنا است که تا زمانی که اجرای متد کامل نگردد، عملیاتی صورت نخواهد گرفت و یا به عبارتی دیگر فراخوان را تا زمانیکه زمانبندی به پایان برسد، در حالت مسدود نگهداری خواهد کرد.

مثال :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Task.Factory.StartNew(() =>
            {
                InvokeMethodExample();
            });
    }
 
    private void InvokeMethodExample()
    {
        Thread.Sleep(2000);
        Dispatcher.Invoke(() =>
            {
                btn1.Content = "By Invoke";
            });
    }
}
متد BeginInvoke : یک Delegate را می‌گیرد و متد آن‌را به صورت ناهمزمان اجرا می‌کند. این مورد به این معنا است که قبل از آنکه متد فراخوانی گردد، برگشت داده می‌شود و یا به عبارتی دیگر به ما اجازه می‌دهد تا Thread جاری را با کنترل دوباره به جریان بیندازیم.
مثال :
public MainWindow()
{
    InitializeComponent();
    Task.Factory.StartNew(() =>
        {
            BeginInvokeExample();
        });
}
 
private void BeginInvokeExample()
{
    DispatcherOperation op = Dispatcher.BeginInvoke((Action)(() => {
         btn1.Content = "By BeginInvoke";
        }));
}
BeginInvoke یک شیء DispatcherOperation برگشت می‌دهد. این شیء یا Object برای دانستن اینکه وضعیت عملیات کامل شده است یا خیر می‌تواند استفاده شود و همچین دو رویداد Aborted و Completed را فراهم می‌کند. 

نظرات نظرسنجی‌ها
کدامیک از روش‌های زیر را برای تولید App های موبایل ترجیح می‌دهید؟ چرا؟
1- خروجی IOS هم به همین معضل مبتلا بود و به همین دلیل باز هم توسعه با سوئیفتُ ترجیح دادم
2- نه، دلفی از نسخه‌های XE نوعی از UI رو به اسم FMX ایجاد کرد و بعدن از همین تکنولوژی تازه تاسیس برای توسعه برنامه‌های موبایلی هم بهره برد، محیط توسعه همون محیط RAD Studio هست ولی نوع پروژه طبعا متفاوته .
ما هم بالاجبار تمام کتابخانه‌ها رو در پروژه اضافه کردیم چون خطا میداد، البته تلاش کردیم راه صحیح رو بریم ولی ممکنه برخی جاها هم اشتباهاتی کرده باشیم اما بازخوردی که از سایرین گرفتیم به همین موضوع منتج شد و از توسعه با دلفی منصرف شدیم .
مطالب
ترفندهای Visual Studio
در این نوشتار چند مورد از مفیدترین کلیدهای میانبر ویژوال استودیو شرح داده می‌شوند. ویژوال استودیو امکانات خوبی را برای سرعت بخشیدن به برنامه‌نویسی دارد. دانستن این نکات سرعت برنامه‌نویسی را افزایش خواهد داد. 

۱) جابجایی بین تب‌ها: «Ctrl + Tab»

با کلیدهای ترکیبی Ctrl + Tab و Ctrl + Shift + Tab می‌توانید بین پنجره‌های Active جابجا شوید. با کلیدهای جهت‌نما هم می‌توانید به بقیه پنجره‌ها از جمله Properties منتقل شوید. ناگفته نماند که این امکان در اکثر قسمت‌های ویندوز و نرم افزارهایی مثل کروم و حتی SSMS نیز وجود دارد. 

به طور کلی کلید شیفت برای دو کاربرد «برگشت از عملیات» و «انتخاب» استفاده می‌شود.


۲) جابه‌جاشدن بین کلاس‌ها، متدها و فایل‌ها : «Ctrl + ,»
معمولا برای رفتن به کلاس یا فایل خاصی، از طریق پنجره Solution Explorer به دنبال فایلی می‌گردیم؛ حتی ممکن است از «Ctrl + ;» برای دسترسی سریع‌تر به‌آن استفاده کنیم؛ با این حال روش بهتری وجود دارد: کلید ترکیبی «کنترل و کلید و» 

برای اینکه جستجویی را فیلتر کنید، می‌توانید از الگوهای زیر استفاده کنید:

f جستجو در فایل‌ها؛ r ‌‌‌برای فایل‌های اخیر؛ t جستجو در تایپ‌ها (مثل کلاس)؛ m ‌‌برای جستجو در اعضا (متدها، پراپرتی‌ها و Eventها).

برای مثال: اگر بنویسید t Controller، فقط Typeها را جست‌وجو می‌کند و نمایش می‌دهد.


۳) کلیپ‌بورد چرخشی : «Ctrl + Shift + V»

ویژوال استودیو تا ۲۰ مقدار کپی‌شده قبلی را در حافظه خود ذخیره نگه می‌دارد. با دکمه‌های ترکیبی گفته شده می‌توان از مقادیر قبلی کلیپ‌بورد هم استفاده کرد. این قابلیت از ویژوال استودیو ۲۰۰۳ وجود داشته است.


۴) اجرای سریع : « Ctrl + Q »

برای دسترسی سریع به تنظیمات ویژوال استودیو (مثل فونت) یا بازکردن پنجره‌هایی که کلید میانبر استاندارد برای آن‌ها تعریف نشده‌است، می‌توان از این منو استفاده کرد.

حتی می‌توان @nuget را نوشت، سپس اسم پکیج موردنظر نوشته می‌شود. با انجام این کار Manage NuGet Packages باز می‌شود و پکیج‌های مرتبط نمایش داده می‌شوند.


۵) پیدا کردن ابتدا و انتهای براکت: « Ctrl + ] »

کاربرد این روش در هنگامی است با Legacy code‌ی مواجه می‌شوید که بلوک‌های بزرگی از کد را دارد که فهم ابتدا و انتهای آن سخت است. با زدن این کلیدها می‌توانید به محلی که براکت باز و بسته مربوطه هست، منتقل شوید.


۶) رفتن به محل کرسر قبلی: « Ctrl + - »

با زدن کلیک‌های کنترل و Dash می‌توانید به جاهایی که قبلا کرسر بوده است، بروید. البته اگر Shift را هم بگیرید، برعکس این کار انجام می‌شود.

منابع: 

۱)  VisualStudioTipsAndTrick 

۲)  VisualStudiosMostUsefulAndUnderusedTips

مطالب
جزئیات برنامه نویسی افزونه فارسی به پارسی

این افزونه با استفاده از ابزار Visual Studio Tools for Office که به VSTO مشهور شده است، تهیه شد. در بسته به روز رسانی سیستم که در ذیل (معرفی افزونه) نیز معرفی شد نگارش sp1 vsto3.0 آن به صورت خودکار نصب خواهد شد.
برای ایجاد این پروژه در VS.Net 2008 ، تنها کافی است یک پروژه جدید Word add-in را آغاز نمائیم. (شکل زیر)





قبل از ادامه بحث، بهتر است در مورد بانک اطلاعاتی مورد استفاده نیز توضیح داده شود. در اینجا از SQLite استفاده شد. (بسیار سبک، کم حجم و سریع است و اساسا یک کاربر نهایی برای تنظیمات آن نیازی نیست اطلاعاتی داشته باشد). بسته به روز رسانی سیستم (در مطلب قبلی)، این مورد را نیز به صورت خودکار نصب خواهد کرد (در GAC باید نصب شود وگرنه افزونه قادر به یافتن آن نخواهد شد).
برای ایجاد این بانک اطلاعاتی، از افزونه SQLite manager برای فایرفاکس استفاده شد. (این افزونه رایگان شما را از هر ابزار جانبی برای مدیریت یک بانک اطلاعاتی SQLite بی‌نیاز می‌کند)
برای مثال فایل ErrorsBank.sqlite برنامه افزونه فارسی به پارسی را توسط افزونه SQLite manager فایرفاکس باز کنید (این فایل را در محل نصب افزونه می‌توانید پیدا کنید). در اینجا می‌توان جداول جدید را ایجاد کرد، کوئری‌های دلخواه را اجرا نمود و یا اطلاعات را مرور کرده، حذف یا ویرایش کرد (شکل زیر).




و خوشبختانه این بانک اطلاعاتی و محصور کننده‌های آن با اطلاعات یونیکد فارسی هیچ مشکلی ندارند و برای کارهایی با وسعت کم و تعداد رکورد پائین یکی از بهترین انتخاب‌ها به‌شمار می‌روند.
نحوه استفاده از SQLite نیز در دات نت بسیار ساده است. اگر با ADO.Net کار کرده باشید، پس از افزودن ارجاعی از اسمبلی System.Data.SQLite.DLL به پروژه و معرفی فضای نام آن به پروژه، تنها کافی است در کدهای قبلی خود برای مثال SqlConnection را به SQLiteConnectionتغییر دهید و امثال آن. یعنی دانش ADO.Net شما در اینجا نیز کاملا قابل استفاده خواهد بود و نیازی نیست مدتی را صرف آشنا شدن با کلاس‌ها و مفاهیم جدید نمائید (البته این تنها زمانی معنا خواهد داشت که به ویزاردها عادت نکرده باشید و کارهای خود را با کد نویسی انجام داده باشید).
تنها یک نکته را باید به‌خاطر داشت و آن هم مربوط است به ساز و کار درونی SQLite . هنگام انجام عملیات update یا insert حتما از transaction استفاده کنید تا سرعت کوئری‌های شما در SQLite به نحو شگفت انگیزی افزایش یابد. مثالی در این مورد را در فایل chm راهنمای SQLite.NET می‌توانید پیدا کنید.

مطلب دیگری که پیش از پرداختن به کد نویسی افزونه باید با آن آشنا شویم، مفهوم smart tags در مجموعه آفیس است که در این پروژه از آن استفاده گردید.
smart tags در مجموعه آفیس برچسب‌هایی هستند که به صورت خودکار توسط یکی از محصولات آفیس مثلا ورد یا اکسل و امثال آن، پس از تشخیص یک کلمه خاص ایجاد می‌شوند و می‌توان اعمالی را به این برچسب ایجاد شده انتساب داد. برای مثال در اینجا امکان جایگزین کردن کلمه فارسی با معادل پارسی در نظر گرفته شد.
ویدیویی در مورد نحوه ایجاد اسمارت تگ‌ها در VS.Net و یا مثالی پیشرفته‌تر در مورد تشخیص دمای فارنهایت در یک متن و ایجاد smart tag مخصوص به آن برای تبدیل به سلسیوس. (از regular expressions جهت یافتن یک الگو در متن استفاده شده است)

در این پروژه، حدود 3800 واژه فارسی به‌ یک smart tag انتساب داده می‌شود (در روال استاندارد ThisAddIn_Startup). سپس در هنگام نمایش آن، معادل پارسی کلمه نیز به منوی باز شده افزوده گشته و در روال رخداد کلیک آن، تعویض کلمه تشخیص داده شده با واژه پیدا شده صورت خواهد گرفت.

در ادامه فرض بر این است که یک پروژه جدید word add-in را در VS.Net ایجاد کرده‌اید و همچنین ارجاعی را به فایل System.Data.SQLite.DLL افزوده‌اید.

using System;
using System.Diagnostics;
using Microsoft.Office.Tools.Word;
using Action = Microsoft.Office.Tools.Word.Action;

private SmartTag _st;
private void init()
{
try
{
//Enable Smart Tags in Word
if (!Application.Options.LabelSmartTags)
{
//ممکن است اسمارت تگ‌ها در ورد غیرفعال باشند. به این صورت می‌شود آنها را فعال کرد
Application.Options.LabelSmartTags = true;
}

_st = new SmartTag(@"www.microsoft.com/Demo#FarsiSmartTag", @"فارسی به پارسی");

//دریافت واژه‌های فارسی از دیتابیس و افزودن خودکار آنها به اسمارت تگ‌ها
if (!DBhelper.AddSmartTagItems(_st, "select distinct farsi from tblFarsiToParsi")) return;

Action stActions = new Action("تبدیل");//تعریف یک اکشن جدید
stActions.Click += stActions_Click;//انتساب روال‌های رخداد گردان
stActions.BeforeCaptionShow += stActions_BeforeCaptionShow;
_st.Actions = new[] { stActions };
VstoSmartTags.Add(_st);//افزودن اسمارت تگ به مجموعه
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

private void ThisAddIn_Startup(object sender, EventArgs e)
{
init();
}

دو روال رخداد گردان زیر نیز جهت تغییر عنوان پیش فرض به واژه یافته شده در لحظه نمایش منو و روال کلیک نیز ایجاد خواهد شد:

static void stActions_BeforeCaptionShow(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
string parsi = DBhelper.FindParsi(e.Text);//معادل پارسی از دیتابیس دریافت می‌شود
clickedAction.Caption = (parsi == string.Empty ? e.Text : parsi);
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

static void stActions_Click(object sender, ActionEventArgs e)
{
try
{
Action clickedAction = sender as Action;
if (clickedAction != null)
{
e.Range.Text = clickedAction.Caption;//جایگزینی متن موجود با عنوانی که پیشتر پارسی شده است
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex.ToString(), EventLogEntryType.Error, 7);
}
}

نکته‌ای را که در اینجا باید حتما رعایت کرد بحث exception handling‌ است. خصوصا در روال استاندارد ThisAddIn_Startup . اگر در این روال خطایی مدیریت نشده رخ دهد، word افزودنی شما را به صورت غیرفعال به مجموعه اضافه خواهد کرد و فعال سازی بعدی آن پس از اصلاح کد واقعا مشکل خواهد بود. همانطور که ملاحظه می‌کنید تمامی خطاها در event log‌ ویندوز نوشته می‌شوند.
همچنین باید دقت داشت که اگر متغیری در سطح کلاس تعریف نشود به احتمال زیاد تا دقایقی بعد توسط garbage collector به دیار باقی خواهد شتافت (تعریف st_ در اینجا). اینجاست که شاید ساعت‌ها وقت صرف کنید که چرا روال‌های رخ‌داد گردان دیگر اجرا نمی‌شوند. چرا افزونه دیگر کار نمی‌کند.

همین! کل سورس این add-in منهای بحث دریافت اطلاعات از دیتابیس همین بود! وظیفه‌ی تشخیص کلمات معرفی شده به ms-word به‌عهده‌ی خود آن است و این‌کار را نیز به‌خوبی انجام می‌دهد. در گذشته‌های نچندان دور ایجاد یک افزونه برای word واقعا مشکل بود که با این روش بسیاری از موانع برطرف شده است.

کلاس DBHelper که کار دریافت اطلاعات واژه‌ها را از دیتابیس SQLite انجام می‌دهد به شرح زیر است:

using System;
using System.Data.SQLite;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Office.Tools.Word;

namespace Farsi2Parsi
{
class DBhelper
{
#region Methods (2)

// Public Methods (2)

public static bool AddSmartTagItems(SmartTag st, string strSQL)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
bool ret = false;
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();

if (myReader != null)
while (myReader.Read())
{
if (myReader.GetValue(0) != DBNull.Value)
st.Terms.Add(myReader.GetValue(0).ToString());
}

ret = true;
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 7);
}
finally
{
if (myReader != null)
myReader.Close();

if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}

public static string FindParsi(string farsi)
{
SQLiteDataReader myReader = null;
SQLiteCommand sqlCmd = null;
string ret = string.Empty;
string strSQL = "select parsi from tblFarsiToParsi where farsi='" + farsi.Replace("'", "''") + "'";
try
{
SQLiteConnection sqlCon = new SQLiteConnection
{
ConnectionString = "Data Source=" + ConStr.ConnectionString
};
sqlCon.Open();
sqlCmd = new SQLiteCommand(strSQL, sqlCon);
myReader = sqlCmd.ExecuteReader();

if (myReader != null)
{
myReader.Read(); //اولین مورد کافی است
if (myReader.GetValue(0) != DBNull.Value)
ret = myReader.GetValue(0).ToString();
}
}
catch (Exception ex)
{
EventLog.WriteEntry("FarsiToParsi", ex + "\n" + Environment.CurrentDirectory + "\n" +
Assembly.GetExecutingAssembly().Location, EventLogEntryType.Error, 8);
}
finally
{
if (myReader != null)
myReader.Close();

if (sqlCmd != null)
sqlCmd.Connection.Close();
}
return ret;
}
#endregion Methods
}
}

همانطور که پیشتر نیز عنوان شد اگر با ADO.net آشنایی داشته باشید، هیچ نکته‌ی خاص جدیدی را در اینجا مشاهده نخواهید کرد و تنها یک سری امور روزمره کاری با ADO.net مطرح شده است، باز کردن کانکشن، اجرای کوئری، دریافت اطلاعات و پاکسازی نهایی. (قسمت finally را با استفاده از عبارت using می‌شود حذف کرد)

هنگام نصب برنامه، مسیر پوشه نصب در رجیستری ویندوز توسط نصاب نوشته خواهد شد. از همین مورد برای ایجاد رشته اتصالی به دیتابیس استفاده گردید.

class ConStr
{
public static string ConnectionString
{
get
{
return Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\FarsiToParsi").GetValue("folder") + "\\ErrorsBank.sqlite";
}
}
}

سورس کامل این افزونه را به صورت یک پروژه VS.Net 2008 SP1 از اینجا می‌توانید دریافت کنید.
نصاب برنامه با استفاده از NSIS ایجاد شده که در روزی دیگر درباره‌ی آن توضیح خواهم داد.
اگر قصد داشته باشید از روش‌های متداول استفاده کنید، مشاهده ویدیوی زیر توصیه می‌شود:
http://msdn.microsoft.com/en-us/office/bb851702.aspx

برای توزیع این نوع افزونه‌ها علاوه بر دات نت فریم ورک، به چهار به روز رسانی دیگر نیز نیاز خواهد بود:
به روز رسانی نصاب ویندوز (که احتمالا نصب هست)
WindowsInstaller-KB893803-v2-x86.exe
Microsoft Office System Update: Redistributable Primary Interop Assemblies :
o2007pia.msi
نصب vsto و همچنین sp1 آن
vstor30.exe
vstor30sp1-KB949258-x86.exe

این موارد را من در بسته به روز رسانی سیستم قرار داده‌ام که به صورت خودکار و یکی پس از دیگری اجرا و نصب خواهند شد.
پس از آن با کلیک بر روی فایلی با پسوند vsto که در پوشه build برنامه موجود است، می‌توان افزونه را نصب کرد (click once installation).




سایر اطلاعات در مورد پروژه‌های VSTO را می‌توان از طریق وبلاگ رسمی آنها دنبال کرد:
http://blogs.msdn.com/vsto/

ایده‌های دیگری را هم در همین رابطه می‌توان پیاده سازی کرد. برای مثال درست کردن یک افزونه برای بررسی آئین نگارش فارسی در متون word. دقیقا با همین روش قابل پیاده سازی است و یا ایجاد غلط یاب بهتری نسبت به آن‌چه که هم اکنون برای آفیس 2003 توسط مایکروسافت ارائه شده است (این غلط یاب با صفحه کلید استاندارد تایپ ایران همخوانی ندارد، به همین جهت با استقبال نیز مواجه نشد).