Question

Je programme WCF en utilisant ChannelFactory qui attend un type pour appeler la méthode CreateChannel. Par exemple:

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

Dans mon cas, je suis en train de faire du routage, donc je ne sais pas quel type sera utilisé par ma fabrique de chaînes. Je peux analyser un en-tête de message pour déterminer le type, mais je me suis heurté à un mur de briques car même si j'ai une instance de type, je ne peux pas transmettre celle où ChannelFactory attend un type générique.

Une autre façon de reformuler ce problème en termes très simples serait que j'essaie de faire quelque chose comme ceci:

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-t-il une approche à cet égard que je pourrais utiliser au sein de C #?

Était-ce utile?

La solution

Ce que vous recherchez est 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);

Vous obtenez donc la définition du type du "modèle" générique " classe, puis en construisant une spécialisation du type en utilisant vos types d’exécution.

Autres conseils

Vous devriez consulter ce message d’Ayende: WCF, Mocking et IoC: Oh MY! . Quelque part vers le bas se trouve une méthode appelée GetCreationDelegate qui devrait aider. Il fait essentiellement ceci:

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

Voici une question: avez-vous vraiment besoin de créer un canal avec le type de contrat exact dans votre cas particulier?

Puisque vous faites du routage, il y a de fortes chances que vous puissiez simplement gérer les formes de canaux génériques. Par exemple, si vous acheminez un message à sens unique, vous pouvez créer un canal pour envoyer le message comme suit:

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

Si vous deviez envoyer vers un service bidirectionnel, utilisez plutôt IRequestChannel.

Si vous faites du routage, il est généralement beaucoup plus facile de gérer des formes de canaux génériques (avec un contrat de service générique à l'extérieur) et de vous assurer que le message que vous envoyez est bien tous les bons en-têtes et propriétés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top