كيف يمكن العثور على تطبيق لواجهة C# في التجميع الحالي باسم محدد؟
-
09-06-2019 - |
سؤال
لدي واجهة تسمى IStep
يمكنها القيام ببعض العمليات الحسابية (انظر "التنفيذ في مملكة الأسماء").في وقت التشغيل، أريد تحديد التنفيذ المناسب حسب اسم الفئة.
// use like this: IStep step = GetStep(sName);
المحلول
سؤالك محير جدا..
إذا كنت تريد العثور على الأنواع التي تطبق IStep، فقم بما يلي:
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
if (!typeof(IStep).IsAssignableFrom(t)) continue;
Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}
إذا كنت تعرف بالفعل اسم النوع المطلوب، فما عليك سوى القيام بذلك
IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
نصائح أخرى
إذا كان التطبيق يحتوي على مُنشئ بدون معلمات، فيمكنك القيام بذلك باستخدام فئة System.Activator.ستحتاج إلى تحديد اسم التجميع بالإضافة إلى اسم الفئة:
IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
وبناء على ما أشار إليه الآخرون، فهذا ما انتهى بي الأمر إلى كتابته:
/// /// Some magic happens here: Find the correct action to take, by reflecting on types /// subclassed from IStep with that name. /// private IStep GetStep(string sName) { Assembly assembly = Assembly.GetAssembly(typeof (IStep)); try { return (IStep) (from t in assembly.GetTypes() where t.Name == sName && t.GetInterface("IStep") != null select t ).First().GetConstructor(new Type[] {} ).Invoke(new object[] {}); } catch (InvalidOperationException e) { throw new ArgumentException("Action not supported: " + sName, e); } }
حسنًا، يبدو أن Assembly.CreateInstance هو الحل الأمثل - المشكلة الوحيدة في ذلك هي أنه يحتاج إلى اسم النوع المؤهل بالكامل، أي.بما في ذلك مساحة الاسم.