سؤال

أنا أقوم ببرمجة WCF باستخدام ChannelFactory الذي يتوقع نوعًا لاستدعاء طريقة CreateChannel.على سبيل المثال:

IProxy proxy = ChannelFactory<IProxy>.CreateChannel(...);

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

هناك طريقة أخرى لإعادة صياغة هذه المشكلة بعبارات بسيطة للغاية وهي أنني أحاول القيام بشيء مثل هذا:

string listtype = Console.ReadLine(); // say "System.Int32"
Type t = Type.GetType( listtype);
List<t> myIntegers = new List<>(); // does not compile, expects a "type"
List<typeof(t)> myIntegers = new List<typeof(t)>(); // interesting - type must resolve at compile time?

هل هناك نهج لهذا يمكنني الاستفادة منه داخل C#؟

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

المحلول

ما تبحث عنه هو MakeGenericType

string elementTypeName = Console.ReadLine();
Type elementType = Type.GetType(elementTypeName);
Type[] types = new Type[] { elementType };

Type listType = typeof(List<>);
Type genericType = listType.MakeGenericType(types);
IProxy  proxy = (IProxy)Activator.CreateInstance(genericType);

لذا فإن ما تفعله هو الحصول على تعريف النوع لفئة "القالب" العامة، ثم إنشاء تخصص للنوع باستخدام أنواع القيادة في وقت التشغيل.

نصائح أخرى

يجب عليك إلقاء نظرة على هذا المنشور من Ayende: WCF والسخرية وIoC:يا بلدي!.في مكان ما بالقرب من الأسفل توجد طريقة تسمى GetCreationDelegate والتي من شأنها أن تساعد.يقوم بهذا بشكل أساسي:

string typeName = ...;
Type proxyType = Type.GetType(typeName);

Type type = typeof (ChannelFactory<>).MakeGenericType(proxyType);

object target = Activator.CreateInstance(type);

MethodInfo methodInfo = type.GetMethod("CreateChannel", new Type[] {});

return methodInfo.Invoke(target, new object[0]);

وهنا سؤال:هل أنت حقًا هل تحتاج إلى إنشاء قناة بنوع العقد المحدد في حالتك المحددة؟

نظرًا لأنك تقوم بالتوجيه، فهناك فرصة جيدة جدًا للتعامل ببساطة مع أشكال القنوات العامة.على سبيل المثال، إذا كنت تقوم بتوجيه رسالة ذات اتجاه واحد فقط، فيمكنك إنشاء قناة لإرسال الرسالة على النحو التالي:

ChannelFactory<IOutputChannel> factory = new ChannelFactory<IOutputChannel>(binding, endpoint);
IOutputChannel channel = factory.CreateChannel();
...
channel.SendMessage(myRawMessage);

إذا كنت بحاجة إلى الإرسال إلى خدمة ثنائية الاتجاه، فما عليك سوى استخدام IRequestChannel بدلاً من ذلك.

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

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