بنية المساعد مع واجهات؛ فحص الواجهة لا يعمل
-
13-09-2019 - |
سؤال
أقوم بتنفيذ بنية مساعدية بسيطة في تطبيق. يتم تعريف متطلبات البرنامج المساعد باستخدام واجهة (iplugin) الموجودة في * .dll تمت الإشارة إليها عن طريق التطبيق والمكون الإضافي. يحتوي التطبيق على مدير البرنامج المساعد (أيضا في نفسه * .dll) الذي يقوم بتحميل الإضافات من خلال البحث عن كل مجلد الإضافات * .dll، يتم تحميلها، ثم يتحقق من أن البرنامج المساعد ينفذ الواجهة. لقد فعلت هذا التحقق من طرق مختلفة [سابقا من قبل بسيطة إذا كان (البرنامج المساعد Iplugin)]، ولكن لن يتعرف أحد عندما يقوم البرنامج المساعد بتنفيذ الواجهة. إليك الرمز:
Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
foreach (Type currType in pluginAssembly.GetTypes())
{
if (currType.GetInterfaces().Contains(typeof(IPlugin)))
{
// Code here is never executing
// even when the currType derives from IPlugin
}
}
}
اعتدت اختبار اسم فئة معينة ("البرنامج المساعد")، ولكن بعد ذلك سمحت له بالدورة من خلال جميع الفصول في التجمع دون جدوى. (يتبع ذلك مثالا وجدته في مكان آخر.) لجعل هذا أكثر تعقيدا قليلا، هناك اثنين من الواجهات التي تنفذ الواجهة الأصلية (iplugina، ipluginb). البرنامج المساعد ينفذ في الواقع واحدة من واجهات أكثر تحديدا (ipluginb). ومع ذلك، لقد جربتها مع البرنامج المساعد فقط تنفيذ الواجهة الأكثر عمومية (iplugin)، وهذا لا يزال لا يعمل.
عدل: استجابة للردودتين التي تلقيتها لأول مرة] نعم، لقد حاولت استخدام isassignablefrom. انظر ما يلي:
Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
foreach (Type currType in pluginAssembly.GetTypes())
{
if (typeof(IPlugin).IsAssignableFrom(currType))
{
string test = "test";
}
}
}
المحلول
هل حاولت:
typeof(IPlugin).IsAssignableFrom(currType)
أيضا، أنواع ينفذ واجهات، لكنهم لا استخلاص منهم. ال BaseType
الممتلكات و IsSubclassOf
طريقة عرض الاشتقاق، حيث IsAssignableFrom
يظهر الاشتقاق أو التنفيذ.
يحرر: هل توقيع جمعياتك؟ يمكن تحميلها إصدارات جنبا إلى جنب من تجميعك, ، ومنذ ذلك Type
تتم مقارنة الكائنات ReferenceEquals
, ، نفس النوع في مجالين جنبا إلى جنب سيكون مستقلا تماما.
تحرير 2: جرب هذا:
public Type[] LoadPluginsInAssembly(Assembly otherAssembly)
{
List<Type> pluginTypes = new List<Type>();
foreach (Type type in otherAssembly.GetTypes())
{
// This is just a diagnostic. IsAssignableFrom is what you'll use once
// you find the problem.
Type otherInterfaceType =
type.GetInterfaces()
.Where(interfaceType => interfaceType.Name.Equals(typeof(IPlugin).Name, StringComparison.Ordinal)).FirstOrDefault();
if (otherInterfaceType != null)
{
if (otherInterfaceType == typeof(IPlugin))
{
pluginTypes.Add(type);
}
else
{
Console.WriteLine("Duplicate IPlugin types found:");
Console.WriteLine(" " + typeof(IPlugin).AssemblyQualifiedName);
Console.WriteLine(" " + otherInterfaceType.AssemblyQualifiedName);
}
}
}
if (pluginTypes.Count == 0)
return Type.EmptyTypes;
return pluginTypes.ToArray();
}
نصائح أخرى
الطريقة isassignablefrom هي ما تبحث عنه:
Type intType = typeof(IInterface);
foreach (Type t in pluginAssembly.GetTypes())
{
if (intType.IsAssignableFrom(t))
{
}
}