2011-07-09 36 views
3

我正在使用WCF之外的System.Runtime.Serialization命名空間,並且想要了解某個元素所代表的類型 - 是否存在名稱解析程序?我真的很喜歡沿着線的東西:從XElement確定DataContract類型

Type ResolveName(XmlQualifiedName typeName); 

我看到有在WCF的內部工作類似的東西,但我似乎無法找到一個公共之一。

謝謝!

回答

0

基於合同的序列化ala DataContractSerialization的一部分是它沒有綁定到特定類型(注意:NetDataContractSerializer不共享這個)。因此,可能有零個,一個或多個候選類型。它會選擇哪個?

所以沒有; AFAIK從根本上不可能。你可能使用反映了所有加載的程序集中的所有類型,當然要查找[DataContract]並手動應用他的測試。

通常情況下,您有現有的類型信息(根類型或當前類型),因此您只有一小組候選類型(KnownType等)需要考慮。

+0

嗯,這是公平的 - 我不會介意它給我的候選類型的列表,甚至,或接受已知的」列表類型「,就像'DataContractSerializer'一樣。重點是我現在不想反序列化它,但是我想知道如果我這樣做會裝入什麼。 (懶惰加載的東西。)我正在研究一個使用Reflection(ugh)和內部DataContract類的解決方案。謝謝參觀! –

+0

@Matt如果你有消息...爲什麼懶惰?只是有興趣... –

+0

嗯,我期待在我正在處理的應用程序中有相當多的這些對象(可能有數十萬),並且我將簡單地存儲對象的路徑(序列化爲硬盤,而不是WCF合同),因爲我希望應用程序一次只能處理更小的(比如說數百個)子集。我們使用DataContract序列化,以便XPath可用於通過外部工具分析文件,並節省學習/編寫新的序列化程序。 –

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(...);