سؤال

أرغب في تقديم طريقة ما لإنشاء مكونات إضافية قابلة للتحميل ديناميكيًا في برنامجي.الطريقة النموذجية للقيام بذلك هي استخدام تحميل المكتبة وظيفة WinAPI لتحميل ملف DLL والاتصال GetProcAddress للحصول على مؤشر إلى وظيفة داخل ملف dll هذا.

سؤالي هو كيف يمكنني تحميل مكون إضافي ديناميكيًا في تطبيق C#/.Net؟

هل كانت مفيدة؟

المحلول

يقوم مقتطف التعليمات البرمجية التالي (C#) بإنشاء مثيل لأي فئات محددة مشتقة من Base الموجودة في مكتبات الفئة (*.dll) في مسار التطبيق وتخزينها في القائمة.

using System.IO;
using System.Reflection;

List<Base> objects = new List<Base>();
DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);

foreach (FileInfo file in dir.GetFiles("*.dll"))
{
    Assembly assembly = Assembly.LoadFrom(file.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(typeof(Base)) && type.IsAbstract == false)
        {
            Base b = type.InvokeMember(null,
                                       BindingFlags.CreateInstance,
                                       null, null, null) as Base;
            objects.Add(b);
        }
    }
}

يحرر: الفصول التي أشار إليها غير لامع من المحتمل أن تكون خيارًا أفضل في .NET 3.5.

نصائح أخرى

اعتبارًا من .NET 3.5، توجد طريقة رسمية ومدمجة لإنشاء المكونات الإضافية وتحميلها من تطبيق .NET.كل ذلك في System.AddIn مساحة الاسم.لمزيد من المعلومات يمكنك مراجعة هذه المقالة على MSDN: الوظائف الإضافية وقابلية التوسعة

تحميل المكونات الإضافية ديناميكيًا

للحصول على معلومات حول كيفية تحميل تجميعات .NET ديناميكيًا، راجع هذا السؤالإجابتي).فيما يلي بعض التعليمات البرمجية لتحميل إنشاء ملف AppDomain وتحميل التجمع فيه.

var domain = AppDomain.CreateDomain("NewDomainName");
var pathToDll = @"C:\myDll.dll"; 
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName) 
    as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

تفريغ المكونات الإضافية

أحد المتطلبات النموذجية لإطار عمل البرنامج المساعد هو إلغاء تحميل المكونات الإضافية.لتفريغ التجميعات المحملة ديناميكيًا (على سبيل المثال.المكونات الإضافية والوظائف الإضافية) عليك إلغاء تحميل المحتوى المحتوي AppDomain.لمزيد من المعلومات، راجع هذه المقالة على MSDN حول تفريغ AppDomains.

باستخدام WCF

هناك كومة تجاوز السؤال والجواب التي تصف كيفية استخدام Windows Communication Framework (WCF) لإنشاء إطار عمل إضافي.

أطر المكونات الإضافية الموجودة

أعرف إطارين للمكونات الإضافية:

بعض الناس يتحدثون عن إطار قابلية التوسعة المُدارة (MEF) كإطار عمل مكون إضافي أو وظيفة إضافية، وهو ليس كذلك.لمزيد من المعلومات، راجع هذا السؤال StackOverflow.com و هذا السؤال StackOverflow.com.

إحدى النصائح هي تحميل كافة المكونات الإضافية وما شابه ذلك في AppDomain خاص بك، نظرًا لأن التعليمات البرمجية التي يتم تشغيلها قد تكون ضارة.يمكن أيضًا استخدام AppDomain الخاص "لتصفية" التجميعات والأنواع التي لا تريد تحميلها.

AppDomain domain = AppDomain.CreateDomain("tempDomain");

ولتحميل التجميع في مجال التطبيق:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
Assembly assembly = domain.Load(assemblyName);

لإلغاء تحميل مجال التطبيق:

AppDomain.Unload(domain);

نعم، ++ إلى Matt وSystem.AddIn (تتوفر مقالة من جزأين في مجلة MSDN حول System.AddIn هنا و هنا).تقنية أخرى قد ترغب في إلقاء نظرة عليها للحصول على فكرة عن الاتجاه الذي قد يتجه إليه .NET Framework في المستقبل هي إطار التوسعة المدارة متوفر حاليًا في نموذج CTP على Codeplex.

في الأساس يمكنك القيام بذلك بطريقتين.

الأول هو استيراد kernel32.dll واستخدام LoadLibrary وGetProcAddress كما استخدمته من قبل:

[DllImport("kernel32.dll")]

internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]

internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

والثاني هو القيام بذلك بطريقة .NET:باستخدام الانعكاس.تحقق من مساحة الاسم System.Reflection والطرق التالية:

أولاً، تقوم بتحميل التجميع حسب مساره، ثم تحصل على النوع (الفئة) منه باسمه، ثم تحصل على طريقة الفئة باسمه مرة أخرى، وأخيرًا تستدعي الطريقة بالمعلمات ذات الصلة.

المقالة قديمة بعض الشيء، ولكنها لا تزال قابلة للتطبيق لإنشاء طبقة قابلة للتوسعة داخل التطبيق الخاص بك:

اسمح للمستخدمين بإضافة وظائف إلى تطبيقات .NET الخاصة بك باستخدام وحدات الماكرو والمكونات الإضافية

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top