【问题标题】:Dynamically Create a generic type for template为模板动态创建泛型类型
【发布时间】:2008-09-15 21:52:15
【问题描述】:

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

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# 中利用这种方法吗?

【问题讨论】:

标签: c# generics


【解决方案1】:

你要找的是 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);

因此,您要做的是获取通用“模板”类的类型定义,然后使用运行时驱动类型构建该类型的特化。

【讨论】:

  • 我们实际上可以直接调用listType.MakeGenericType(elementType) - 这是params 参数。
【解决方案2】:

您应该看看来自 Ayende 的这篇帖子:WCF, Mocking and IoC: Oh MY!。靠近底部的某个地方是一个名为 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]);

【讨论】:

    【解决方案3】:

    这里有一个问题:您真的需要根据您的具体情况创建一个具有确切合同类型的渠道吗?

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

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

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

    如果您正在执行路由,通常只处理通用通道形状(与外部通用的包罗万象的服务合同)并确保您发送的消息具有所有正确的标题和属性。

    【讨论】:

    • 我在标记我的问题的“答案”时遇到了难题。在使用 WCF 方面,我能够使用您提到的这种技术,它就像一个魅力(谢谢!)。我之所以选择上述方法,是因为它在技术上确实回答了我提出的问题(即使这是一种更好的方法)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多