質問
CreateChannel メソッドを呼び出すために型を必要とする ChannelFactory を使用して WCF をプログラミングしています。例えば:
IProxy proxy = ChannelFactory<IProxy>.CreateChannel(...);
私の場合はルーティングを行っているため、チャネルファクトリーがどのタイプを使用するかわかりません。メッセージ ヘッダーを解析して型を判断することはできますが、Type のインスタンスがあっても、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 を使用してください。
ルーティングを行っている場合、一般に、一般的なチャネル形状を (外部への一般的なキャッチオール サービス コントラクトを使用して) 処理し、送信するメッセージが適切であることを確認するだけの方がはるかに簡単です。ヘッダーとプロパティ。