关于c#:动态创建模板的通用类型

关于c#:动态创建模板的通用类型

Dynamically Create a generic type for template

我正在使用ChannelFactory对WCF进行编程,该类需要一种类型才能调用CreateChannel方法。 例如:

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

就我而言,我正在做路由,所以我不知道我的通道工厂将使用哪种类型。 我可以解析消息标头以确定类型,但是我在那里碰到一堵砖墙,因为即使我有Type的实例,也无法在ChannelFactory期望泛型的地方传递它。

用非常简单的术语来重述此问题的另一种方式是,我正在尝试执行以下操作:

1
2
3
4
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

1
2
3
4
5
6
7
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,Mocking和IoC:天哪!底部附近的某个位置叫GetCreationDelegate的方法应该会有所帮助。它基本上是这样做的:

1
2
3
4
5
6
7
8
9
10
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]);


这是一个问题:在您的特定情况下,您是否真的需要创建具有确切合同类型的渠道?

由于您要进行布线,因此很有可能仅处理通用通道形状。例如,如果您要路由单向消息,则可以创建一个通道来发送消息,如下所示:

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

如果您需要发送到双向服务,只需使用IRequestChannel即可。

如果您要进行路由,则通常来说,处理通用的通道形状(与通用的通用服务合同到??外部)要容易得多,只需确保您发送的消息正确无误即可。标头和属性。


推荐阅读