我在WCF之外使用System.Runtime.Serialization命名空间,并想知道元素代表什么类型 - 是否有名称解析器?我真的很喜欢以下内容:
Type ResolveName(XmlQualifiedName typeName);
我看到WCF的内部工作方式有类似之处,但我似乎无法找到公开的工作。
谢谢!
答案 0 :(得分:1)
由于我仍然认为我需要这个功能,所以我已经去写了一个课程来获取信息。我使用Impromptu-Interface来加速反射位,但整个过程让我感到烦恼。
public class DataContractNameResolver
{
private Type TypeOfDataContract = null;
private Dictionary<System.Xml.XmlQualifiedName, Type> xmlNames = new Dictionary<System.Xml.XmlQualifiedName, Type>();
internal void PrecacheBaseTypes(IEnumberable<Type> types)
{
if (TypeOfDataContract == null)
{
TypeOfDataContract = Type.GetType("System.Runtime.Serialization.DataContract, System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
}
lock (xmlNames)
{
var remaining = new Queue<Type>(types.Except(xmlNames.Values));
while (remaining.Count > 0)
{
Type next = remaining.Dequeue();
var dc = Impromptu.InvokeMember(TypeOfDataContract.WithStaticContext(), "GetDataContract", next);
IDataContract result = Impromptu.ActLike<IDataContract>(dc);
xmlNames.Add(new System.Xml.XmlQualifiedName(result.Name.Value, result.Namespace.Value), next);
}
}
}
public Type ResolveName(System.Xml.XmlQualifiedName typeName)
{
if (xmlNames.ContainsKey(typeName))
{
return xmlNames[typeName];
}
return null;
}
}
使用这个类就像:
var nameResolver = new DataContractNameResolver();
nameResolver.PrecacheBaseTypes(new[] { typeof(SampleOne), typeof(SampleTwo) });
var resultType = nameResolver.ResolveName(...);
答案 1 :(得分:0)
基于合同的序列化的一部分ala DataContractSerialization是它与特定类型无关(注意:NetDataContractSerializer不共享此)。因此,可能存在零个,一个或多个候选类型。它会选择哪个?
所以没有;从根本上说不可能的AFAIK。 可能可能在所有已加载的程序集中使用反射,查找[DataContract]并手动应用测试。
通常,您有现有的类型信息(根类型或当前类型),因此您只需考虑一小组候选类型(KnownType等)。