تبلیغات

امکان نوشتن پلاگین برای برنامه ای که با سی شارپ نوشتیم با Pluginer

نوشته شده توسط هادی اکبرزاده

آموزش Pluginer (پلاگینر)
امکان نوشتن پلاگین برای برنامه ای که با سی شارپ نوشتیم با Pluginer


یکی از مهم‌ترین چیزهایی که در برنامه‌های زیادی دیده می‌شود، امکان نوشتن پلاگین (افزونه) برای آن برنامه است. به این صورت که کاربر برنامه را نصب می‌کند و در کنار قابلیت‌های اصلی برنامه، می‌تواند برخی قابلیت‌های دیگر را نیز با استفاده از پلاگین‌ها به برنامه اضافه کند!
برای انجام این کار، کتابخانه‌ی بسیار ساده‌ای با نام پلاگینر (Pluginer) را توسعه داده‌ایم؛ و شما با استفاده از آن می‌توانید به سادگی این قابلیت را برای نرم‌افزار خود فراهم کنید. قبل از هرچیزی، کتابخانه را از این «لینک» دریافت نمایید.

در ادامه روش استفاده کلی + یک مثال را آماده کرده‌ایم.

روش استفاده از پلاگینر

فایل DLL را به پروژه خود اضافه کنید. سپس کلاسی با نام PluginRunner در فضای نامی Pluginer.PluginRunner قابل استفاده خواهد بود.

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

  • path: از نوع String
    مسیر پوشه‌‍ای که DLL های کتابخانه در آن قرار می‌گیرند.
    پیش‌فرض برابر مقدار “Plugins” است
  • targets: از نوع string[]
    تعیین می‌کند کدام کلاس‌های DLL اجرا شوند! به این ضورت که نام کامل (نام کلاش + فضای نامی، مثل Pluginer.PluginRunner) هایی که میخواهیم اگر یک کلاس در DLL از آن به ارث برده باشد، اجرا شود. یعنی اگر کلاسی داخل dll از یکی از کلاس‌های تعیین شده در آرایه targets ارث بری کرده باشد، new خواهد شد.
    پیش‌فرض: null (یعنی از تمام کلاس‌های داخل DLL یک new ایجاد کند)
  • passInApp: از نوع bool
    مشخص می‌کند که آیا path، از ادامه مسیر فعلی برنامه هست یا خیر! که اگر true باشد بایستی یک مسیر از ادامه مسیر فعلی داده شود؛ و اگر false باشد، بایستی مسیر کامل از ابتدا داده شود.
    پیش‌فرض: true

بنابراین اگر آبجکتی از کلاس PluginRunner بدون هیچ ورودی برای متد سازنده بسازیم، به پوشه‌ی Plugins در محل نصب برنامه اشاره خواهد داشت.


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


رویداد OnNoAnyPlugins
زمانی که هیچ پلاگینی وجود نداشته باشد.


رویداد OnInitialized
زمانی که پلاگین‌ها شناسایی شوند.

  • pluginsPath: از نوع string[]
    مسیر پلاگین‌ها
  • count: از نوع int
    تعداد پلاگین‌ها

رویداد OnErrorLoadingPlugin
زمانی که در اجرای یک فایل پلاگین خطایی رخ دهد.

  • pluginName: از نوع string
    نام فایل پلاگین بدون پسوند
  • ex: از نوع Exception
    خطای ایجاد شده

رویداد OnNewPluginChecked
زمانی که بررسی یک پلاگین تمام شود.

  • pluginName: از نوع string
    نام فایل پلاگین بدون پسوند

رویداد OnNewClassLoaded
زمانی که کلاسی از یک پلاگین با موفقیت اجرا شود.

  • pluginName: از نوع string
    نام فایل پلاگین بدون پسوند
  • type: از نوع Type
    آبجکت تایپ کلاس لود شده

رویداد OnErrorLoadingClass
زمانی که خطایی در اجرای یک کلاس رخ دهد. (با خطای اجرای خود پلاگین متفاوت است. این خطا در کد رخ میدهد ولی خطای پلاگین در کلیت پلاگین رخ میدهد)

  • pluginName: از نوع string
    نام فایل پلاگین بدون پسوند
  • type: از نوع Type
    آبجکت تایپ کلاس لود شده
  • ex: از نوع Exception
    خطای ایجاد شده

یک مثال

کتابخانه Pluginer را به پروژه خود اضافه کرده و سپس یک RichTextBox و یک MenuStrip ایجاد کنید. و در نهایت کد فرم را به صورت زیر تکمیل نمایید:

همانطور که می‌بینید، قرار است کلاس‌هایی اجرا شوند که از کلاس “System.Text.ASCIIEncoding” ارث‌بری کرده باشند! البته System.Text.ASCIIEncoding یک مقدار آزمایشی بوده و هدف خاصی پشت آن نیست.

اما در اینجا ما قصد داریم پلاگینی بنویسیم که به MenuStrip اپلیکیشن، منوهایی را اضافه کند. و از آنجایی که قرار است به MenuStrip از طریق فرمی که به متد Load ارسال شده است دسترسی داشته باشیم، چون در یک کلاس دیکری هستیم، بایستی از بخش Properties کنترل MenuStrip، مقدار ویژگی Modifiers را روی Public قرار دهیک.


حالا وقت ایجاد پلاگین است. ویژوال استودیو را اجرا کرده و یک Class Library با نام دلخواه ایجاد کنید. پس از ایجاد پروژه، کلاس Class1 را مشاهده خواهید کرد.

آن را به صورت زیر تکمیل کنید:

توجه داشته باشید که تمامی ورودی متدسازنده‌ی کلاس‌هایی که می‌خواهیم اجرا شوند، بایستی به صورت بالا باشند.

از آنجایی که در کد نرم‌افزار، ما خود فرم را به عنوان پارامتر اول به داخل پلاگین‌ها ارسال کرده‌ایم، پس می‌دانیم که در اینجا نیز ورودی اول آرایه args، خود فرم خواهد بود! و از آنجایی که فیلدها و بقیه موارد در کتابخانه شناخته شده نیستند، از متغیر داینامیک استفاده می‌کنیم. یعنی متغیر را با استفاده از dynamic تعریف می‌کنیم تا به نبودن فیلدها و متدها گیر ندهد.

سپس منوهای خود را به menuStrip1 اضافه می‌کنیم و همچنین یادمان هست که menuStrip1 را پابلیک کرده باشیم.

بهتر است یک کتابخانه برای نرم افزار خود توسعه دهید که شامل API (کلاس‌ها و توابع اصلی) و همچنین آن کلاس‌هایی که پلاگین‌ها می‌توانند از آن برای اجرا شدن ارث‌بری نماییند باشد. سپس زمان توسعه‌ی پلاگین، می‌توانید این کتابخانه را به پروژه اضافه کنید تا ویژوال استودیو آن را بشناسد و همچنین این کتابخانه قرار نیست در پوشه Plugins قرار گیرد! چرا که قبلا در کنار خود برنامه قرار گرفته است.
تبلیغات
0
کانال تلگرام فول کده

درباره نویسنده

هادی اکبرزاده

[ مدیر فول کده ]

دانشجوی ارشد شبیه ساز هوشمند و مدیر فول کده
Telegram

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

نظرات ثبت شده بدون دیدگاه