سؤال

هل يمكن استخدام فئة مجردة ككائن عقد بين "مضيف" و "مكون إضافي"؟ الفكرة هي أن المكون الإضافي يرث العقد (نسميه محول). نحن نفهم أيضًا أن جميع المشاركين في الإطار يجب أن يرثوا MarshalByRefObject (MBRO). لذلك ، هذا ما كنا نفكر فيه -

مضيف:

class Host : MarshalByRefObject
{
}

اتفافية:

public abstract class PluginAdapter : MarshalByRefObject
{
}

توصيل في:

class myPlugin : PluginAdapter
{
}

الثلاثة موجودة في ASM منفصلة. سيقوم مضيفنا بإنشاء AppDomain جديد لكل مكون إضافي ، ويتم إنشاء البرنامج المساعد على النحو التالي:

{
    ObjectHandle instHandle = Activator.CreateInstance(
    newDomain, data.Assembly.FullName, data.EntryPoint.FullName);

    PluginAdapter adapter = (PluginAdapter)instHandle.Unwrap();
}

تعديل: أين data هو النوع الملموس myPlugin.

كنا نتساءل عما إذا كان هذا التنفيذ للإطار سيعمل. لقد رأينا مقالات باستخدام واجهة (iPlugin) للاشتقاق المكون الإضافي ، وفئة ملموسة كعقد. قد تقول هذه المقالات أيضًا أنه يمكن استخدام فئة مجردة ، ولكن لا توجد أمثلة على هذا التنفيذ المقدم. هل يلزم أن يكون العقد فئة ملموسة؟

تعديل: في هذا المثال بقلم ريتشارد بلويت - C# الانعكاس - يستخدم تنفيذ أبسط بكثير:

اتفافية:

public interface IPlugIn  
{  
    // do stuff  
}

توصيل في:

public class PlugIn : MarshalByRefObject, IPlugIn  
{  
}

الآن ، إذا كان استخدام فئة مجردة كعقد ، فلا يمكن للمكون الإضافي أن يرث كل من العقد و MBRO. ما ، إذن ، يصبح أفضل تطبيق لإطار إضافي قابل للتطوير. هل يجب أن نمضي قدمًا وننفذ عن بُعد على الرغم من أننا في البداية ، نطور لتشغيل الآلة الواحدة؟ من المتوقع أن يتم توزيع هذا المشروع عبر شبكة ، ربما عبر الإنترنت أيضًا. نحن ببساطة لم ننفذ TCP بعد لأننا نحاول الحصول على أساسيات إطار البرنامج المساعد مفهومة تمامًا وتعمل.

هل من المنطقي تنفيذ TCP عن بعد على جهاز واحد باستخدام Loopback؟

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

المحلول

الفصول التجريدية هي خيارات أفضل لهذا ، IMHO. في المقام الأول لأن الواجهات أصعب في الإصدار. منشور المدونة هذا يصف المشكلة التي قد تجدها على الطريق إذا لم تستخدم فصول الأساس. هذه القاعدة لا تنطبق فقط على الإضافات ، راجع للشغل.

حول تصميمك ...

لا ينبغي أن يمتد الإضافات MBRO. يجب عليك استخدام مضيفك (الذي يجب أن يمتد MBRO) إلى مارشال جميع المكالمات عبر الإضافات الخاصة بك ، بما في ذلك معالجة أحداث البرنامج المساعد. من السهل جدًا تحميل DLL المكوّن الإضافي عن غير قصد في AppDomain الرئيسي إذا حاولت سحبها واستخدام الوكلاء.

على سبيل المثال ، إذا قام المكون الإضافي بإرجاع عملية غير قابلة للتطبيق لأحد طرقه ، فقد يعيد تنفيذ iEnumerable الذي يتم تعريفه في مجموعة البرنامج المساعد. إذا لم يمتد هذا MBRO ، فسيتعين على AppDomain الرئيسي تحميل مجموعة البرنامج المساعد.


لقد قمت بتحميل ثلاثة مشاريع تتعامل مع AppDomains هنا:

http://cid-f8be9de57b85cc35

يستخدم المرء عمليات الاسترجاعات عبر AppDomains ، والثاني هو معالجة الأحداث المتقاطعة ، والثالث هو مثال إضافي.

في مثال البرنامج المساعد ، يحدد التطبيق واجهة مكون الإضافي (إنه عرض تجريبي وليس أفضل الممارسات!) ومضيف مكون إضافي. يقوم التطبيق بتحميل تجميع إضافي RAW من القرص وينقله إلى AppDomain المكون الإضافي عبر وكيل مضيف البرنامج المساعد ، حيث يتم تحميله. ثم يقوم مضيف البرنامج المساعد بتثبيت البرنامج المساعد ويستخدمه. ولكن عندما يقوم المضيف بإرجاع نوع محدد في تجميع البرنامج المساعد مرة أخرى في Appdomain ، يتم تحميل مجموعة البرنامج المساعد في مجال التطبيق الرئيسي ، مما يجعل الشيء المكون الإضافي بالكامل بلا معنى.

أفضل شيء لتجنب ذلك هو توفير فئة أساسية مجردة للإضافات غير قابلة للتسلسل ولا تمتد MBRO ، ولإعادة البدائية أو الأنواع المختومة فقط التي تحددها عبر الحدود من مجال البرنامج المساعد.

ملاحظة: المشاريع كلها 4.0 RC. ستحتاج إلى هذا أو فوق لتشغيلها. وإلا فإن عليك تحرير ملفات المشروع باليد أو إعادة بنائها لجعلها تعمل في B2 أو 2008.

نصائح أخرى

المقدمة "data.entrypoint.fullname" هو اسم النوع الكامل ، يجب أن يعمل الرمز أعلاه.

ومع ذلك ، إذا كنت تحاول إبقاء هذا النوع معزولًا في AppDomain الخاص به ، فيجب أن تكون حذرًا هنا. عن طريق القيام data.Assembly, ، ستقوم بسحب التجميع (وأنواعها) إلى appdomain الخاص بك ، مما تسبب في تحميل الأنواع في Appdomain التنفيذ ...

قد ترغب في إلقاء نظرة على MAF (إطار الإضافة المدارة) وهو إطار قابلية للتمديد مدمج في .NET للقيام بالإضافات. إنه مشابه (وكبار السن) من MEF (إطار التمديد المدارة), ، ولكن لديه المزيد من الخيارات فيما يتعلق بالحفاظ على الإضافات في مجال التطبيق الخاص بهم ، من بين أشياء أخرى.

لو data.EntryPoint.FullName يشير إلى نوع الخرسانة myPlugin لا أرى أي سبب لعدم عمل ذلك (ما لم يكن هناك مشاكل في تحميل التجميع في AppDomain الأخرى ولكن هذه مشكلة مختلفة).

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