Pregunta

Estoy programando WCF usando ChannelFactory que espera un tipo para llamar al método CreateChannel.Por ejemplo:

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

En mi caso, estoy haciendo enrutamiento, por lo que no sé qué tipo utilizará mi fábrica de canales.Puedo analizar el encabezado de un mensaje para determinar el tipo, pero choqué contra una pared de ladrillos porque incluso si tengo una instancia de Type no puedo pasarla donde ChannelFactory espera un tipo genérico.

Otra forma de reformular este problema en términos muy simples sería intentar hacer algo como esto:

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?

¿Existe algún método para esto que pueda aprovechar en C#?

¿Fue útil?

Solución

Lo que estás buscando es 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);

Entonces, lo que está haciendo es obtener la definición de tipo de la clase genérica de "plantilla" y luego crear una especialización del tipo utilizando sus tipos de control de tiempo de ejecución.

Otros consejos

Deberías mirar esta publicación de Ayende: WCF, burla y COI:¡Oh mi!.En algún lugar cerca del final hay un método llamado GetCreationDelegate que debería ayudar.Básicamente hace esto:

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]);

Aquí hay una pregunta:Tú en realidad ¿Necesitas crear un canal con el tipo de contrato exacto en tu caso específico?

Dado que está haciendo enrutamiento, es muy probable que pueda simplemente manejar las formas genéricas del canal.Por ejemplo, si está enrutando un mensaje unidireccional, puede crear un canal para enviar el mensaje de esta manera:

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

Si necesitaba enviar a un servicio bidireccional, simplemente use IRequestChannel.

Si está haciendo enrutamiento, es, en general, mucho más fácil lidiar con formas de canal genéricas (con un contrato de servicio general genérico para el exterior) y simplemente asegurarse de que el mensaje que está enviando tenga todas las características correctas. encabezados y propiedades.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top