يمكن لآلية الانعكاس التي يوفرها .NET تحميل المكونات الإضافية بسهولة. توفر هذه المقالة طريقة يمكنها تحميل المكونات الإضافية المطلوبة بمرونة وبشكل صحيح.
في .NET، يكون اسم النوع الكامل بالتنسيق "اسم النوع، اسم التجميع".
على سبيل المثال: "System.Configuration.NameValueSectionHandler، System، Version=1.0.3300.0، Culture=محايد، PublicKeyToken=b77a5c561934e089".
اسم النوع هو: System.Configuration.NameValueSectionHandler، وهو اسم النوع الكامل مع مساحة الاسم.
يمكنك أيضًا الحصول على الاسم الكامل باستخدام النوع.
على سبيل المثال: string typeName = typeof(NameValueSectionHandler).FullName;
اسم التجميع هو: "النظام، الإصدار=1.0.3300.0، الثقافة=محايدة، PublicKeyToken=b77a5c561934e089"،
يُسمى التجميع System، ويقوم النظام تلقائيًا بتعديل امتداده (مثل System.dll أو System.exe)؛
الإصدار والثقافة وPublicKeyToken هي الإصدار المحدد والخلفية الثقافية والتوقيع الخاص بالتجميع. ولا توجد متطلبات محددة، ويمكن حذفها.
يمكننا تحميل النوع المطلوب ديناميكيًا بناءً على اسم النوع. يحب:
string typeName = "System.Configuration.NameValueSectionHandler, System";
اكتب t = Type.GetType(typeName);
Object obj = Activator.CreateInstance(t);
//أو
System.Configuration.NameValueSectionHandler obj = (System.Configuration.NameValueSectionHandler)Activator.CreateInstance(t);
عند هذه النقطة، obj هو مثيل النوع المطلوب.
عادةً ما تكون المكونات الإضافية عبارة عن فئات تحتاج إلى تنفيذ واجهات معينة. لذلك، قبل تحميل مكون إضافي، تحتاج إلى تحديد ما إذا كان نوع المكون الإضافي مناسبًا أم لا.
على سبيل المثال، إذا كانت واجهة البرنامج الإضافي هي IPlugin، فيمكننا التعرف عليه بالطريقة التالية:
اسم واجهة السلسلة = typeof(IPlugin).FullName;
string typeName = "Muf.MyPlugin, MyPlugin";
اكتب t = Type.GetType(typeName);
إذا (ر == فارغة
||. !t.IsClass
||.!t.IsPublic
||.t.GetInterface(interfaceName) == null)
{
return null; // ليس البرنامج المساعد المطلوب
}
بتلخيص الكود أعلاه، يمكننا إنشاء كود عام لتحميل المكونات الإضافية:
/**//// <الملخص>
/// قم بتحميل وإنشاء نوع له الواجهة المحددة ديناميكيًا
/// </الملخص>
/// <param name="className">اكتب الاسم</param>
/// <param name="interfaceName">اسم الواجهة المحددة</param>
/// <param name="param">حدد معلمات المُنشئ (الصفيف الفارغ أو الفارغ يعني استدعاء المُنشئ الافتراضي)</param>
/// <returns>إرجاع النوع الذي تم إنشاؤه (القيمة الفارغة تعني أنه لا يمكن إنشاء النوع أو لا يمكن العثور عليه)</returns>
كائن ثابت عام LoadObject (اسم فئة السلسلة، اسم واجهة السلسلة، الكائن [] المعلمة)
{
يحاول
{
اكتب t = Type.GetType(className);
إذا (ر == فارغة
||. !t.IsClass
||.!t.IsPublic
||.t.IsAbstract
||.t.GetInterface(interfaceName) == null)
{
عودة فارغة؛
}
object o = Activator.CreateInstance(t, param);
إذا (س == فارغة)
{
عودة فارغة؛
}
العودة س؛
}
قبض (استثناء على سبيل المثال)
{
عودة فارغة؛
}
}
لاحقًا، يمكننا استخدام LoadObject لتحميل أي مكونات إضافية مطلوبة.
يتم وضع المكونات الإضافية بشكل عام في ملفات التكوين ويقرأها البرنامج:
أمثلة على ملفات التكوين (راجع مقالاتي ذات الصلة لاستخدام ملفات التكوين):
<?xml version="1.0" encoding="utf-8" ?>
<التكوين>
<أقسام التكوين>
<section name="Channels" type="Vmp.Configuration.ChannelsSectionHandler, Communication" />
</configSections>
<القنوات>
<قناة
ChannelType="Vmp.Communication.TcpChannel، الاتصال"
ملف التتبع = "d:logchannel1.log"
المنفذ = "2020" MaxConnections = "300" حجم المخزن المؤقت = "2048"
/>
</القنوات>
</التكوين>
مثال التعليمات البرمجية:
قناة ArrayList الخاصة = new ArrayList()
;
{
ArrayListchannelConfig = (ArrayList)ConfigurationSettings.GetConfig( "Channels");
foreach (تكوين Hashtable في ChannelConfig)
{
stringchannelType = (string) config["ChannelType"]
;
إذا (القناة == فارغة)
continue;
channelsList.Add(channel);
}
يمكنك أيضًا اجتياز دليل المكونات الإضافية المحدد وتحميل كافة المكونات الإضافية التي تلبي المتطلبات، على سبيل المثال:
IPlugin العام[] LoadAllPlugIn(string pluginDir)
{
// قم بتعيين دليل البرنامج المساعد الافتراضي
إذا (pluginDir == null || pluginDir == "")
pluginDir = "./PlugIns";
// احصل على اسم واجهة البرنامج الإضافي
string InterfaceName = typeof(IPlugin).FullName;
// المصفوفة المستخدمة لتخزين المكونات الإضافية
ArrayList arr = new ArrayList();
// اجتياز دليل المكون الإضافي (بافتراض أن المكون الإضافي هو ملف dll)
foreach (ملف سلسلة في Directory.GetFiles (pluginDir، "*.dll"))
{
// قم بتحميل ملف البرنامج الإضافي
التجميع asm = Assembly.LoadFile(file);
// اجتياز فئات المكونات الإضافية المصدرة
foreach (اكتب t في asm.GetExportedTypes ())
{
// قم بتحميل المكون الإضافي إذا كان المكون الإضافي لا يتوافق مع الواجهة المحددة، فارجع فارغًا
IPlugin plugin = LoadObject(t.FullName, InterfaceName, null) كـ IPlugin
;
arr.Add(plugin);
}
}
// العودة إلى البرنامج المساعد
return (IPlugin[])arr.ToArray(typeof(IPlugin));
}