从XElement确定数据契约类型
本文关键字:契约 类型 数据 XElement | 更新日期: 2023-09-27 18:01:33
我正在使用WCF之外的System.Runtime.Serialization名称空间,并想找出元素代表的类型-是否有名称解析器?我真的很喜欢这样的东西:
Type ResolveName(XmlQualifiedName typeName);
我看到在WCF的内部工作中有类似的东西,但我似乎找不到一个公开的
谢谢!
因为我仍然认为我需要这个功能,所以我已经编写了一个类来获取信息。为了加速反射,我使用了即兴界面,但整个过程让我很恼火。
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(...);
基于契约的序列化与DataContractSerialization的部分意义在于它不绑定到特定的类型(注意:NetDataContractSerializer不共享这一点)。因此,可能有零、一个或多个候选类型。它会选择哪一个?
所以没有;我想这基本上是不可能的。您可以也许在所有加载的程序集中对所有类型使用反射,当然要寻找[DataContract]并手动应用测试。
通常您有现有的类型信息(根类型或当前类型),因此您只需要考虑一小部分候选类型(KnownType等)。