DataContractSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / DataContractSet.cs / 2 / DataContractSet.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Xml; 
    using System.Xml.Schema;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Reflection;
    using DataContractDictionary = System.Collections.Generic.Dictionary;
    using System.Text; 

    internal class DataContractSet 
    { 
        Dictionary contracts;
        Dictionary processedContracts; 
        IDataContractSurrogate dataContractSurrogate;
        Hashtable surrogateDataTable;
        DataContractDictionary knownTypesForObject;
        ICollection referencedTypes; 
        ICollection referencedCollectionTypes;
        Dictionary referencedTypesDictionary; 
        Dictionary referencedCollectionTypesDictionary; 

 
        internal DataContractSet(IDataContractSurrogate dataContractSurrogate) : this(dataContractSurrogate, null, null) { }

        internal DataContractSet(IDataContractSurrogate dataContractSurrogate, ICollection referencedTypes, ICollection referencedCollectionTypes)
        { 
            this.dataContractSurrogate = dataContractSurrogate;
            this.referencedTypes = referencedTypes; 
            this.referencedCollectionTypes = referencedCollectionTypes; 
        }
 
        internal DataContractSet(DataContractSet dataContractSet)
        {
            if (dataContractSet == null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("dataContractSet")); 

            this.dataContractSurrogate = dataContractSet.dataContractSurrogate; 
            this.referencedTypes = dataContractSet.referencedTypes; 
            this.referencedCollectionTypes = dataContractSet.referencedCollectionTypes;
 
            foreach (KeyValuePair pair in dataContractSet)
            {
                Add(pair.Key, pair.Value);
            } 

            if (dataContractSet.processedContracts != null) 
            { 
                foreach (KeyValuePair pair in dataContractSet.processedContracts)
                { 
                    ProcessedContracts.Add(pair.Key, pair.Value);
                }
            }
        } 

        Dictionary Contracts 
        { 
            get
            { 
                if (contracts == null)
                {
                    contracts = new Dictionary();
                } 
                return contracts;
            } 
        } 

        Dictionary ProcessedContracts 
        {
            get
            {
                if (processedContracts == null) 
                {
                    processedContracts = new Dictionary(); 
                } 
                return processedContracts;
            } 
        }

        Hashtable SurrogateDataTable
        { 
            get
            { 
                if (surrogateDataTable == null) 
                    surrogateDataTable = new Hashtable();
                return surrogateDataTable; 
            }
        }

        internal DataContractDictionary KnownTypesForObject 
        {
            get { return knownTypesForObject; } 
            set { knownTypesForObject = value; } 
        }
 
        internal void Add(Type type)
        {
            DataContract dataContract = GetDataContract(type);
            EnsureTypeNotGeneric(dataContract.UnderlyingType); 
            Add(dataContract);
        } 
 
        internal static void EnsureTypeNotGeneric(Type type)
        { 
            if(type.ContainsGenericParameters)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericTypeNotExportable, type)));
        }
 
        void Add(DataContract dataContract)
        { 
            Add(dataContract.StableName, dataContract); 
        }
 
        public void Add(XmlQualifiedName name, DataContract dataContract)
        {
            if (dataContract.IsBuiltInDataContract)
                return; 
            DataContract dataContractInSet = null;
            if (Contracts.TryGetValue(name, out dataContractInSet)) 
            { 
                if (!dataContractInSet.Equals(dataContract))
                { 
                    if (dataContract.UnderlyingType == null || dataContractInSet.UnderlyingType == null)
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DupContractInDataContractSet, dataContract.StableName.Name, dataContract.StableName.Namespace)));
                    else
                    { 
                        bool typeNamesEqual = (DataContract.GetClrTypeFullName(dataContract.UnderlyingType) == DataContract.GetClrTypeFullName(dataContractInSet.UnderlyingType));
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DupTypeContractInDataContractSet, (typeNamesEqual ? dataContract.UnderlyingType.AssemblyQualifiedName : DataContract.GetClrTypeFullName(dataContract.UnderlyingType)), (typeNamesEqual ? dataContractInSet.UnderlyingType.AssemblyQualifiedName : DataContract.GetClrTypeFullName(dataContractInSet.UnderlyingType)), dataContract.StableName.Name, dataContract.StableName.Namespace))); 
                    } 
                }
            } 
            else
            {
                Contracts.Add(name, dataContract);
 
                if (dataContract is ClassDataContract)
                { 
                    AddClassDataContract((ClassDataContract)dataContract); 
                }
                else if (dataContract is CollectionDataContract) 
                {
                    AddCollectionDataContract((CollectionDataContract)dataContract);
                }
                else if (dataContract is XmlDataContract) 
                {
                    AddXmlDataContract((XmlDataContract)dataContract); 
                } 
            }
        } 

        void AddClassDataContract(ClassDataContract classDataContract)
        {
            if (classDataContract.BaseContract != null) 
            {
                Add(classDataContract.BaseContract.StableName, classDataContract.BaseContract); 
            } 
            if (!classDataContract.IsISerializable)
            { 
                if (classDataContract.Members != null)
                {
                    for (int i = 0; i < classDataContract.Members.Count; i++)
                    { 
                        DataMember dataMember = classDataContract.Members[i];
                        DataContract memberDataContract = GetMemberTypeDataContract(dataMember); 
                        if (dataContractSurrogate != null && dataMember.MemberInfo != null) 
                        {
                            object customData = DataContractSurrogateCaller.GetCustomDataToExport( 
                                                   dataContractSurrogate,
                                                   dataMember.MemberInfo,
                                                   memberDataContract.UnderlyingType);
                            if (customData != null) 
                                SurrogateDataTable.Add(dataMember, customData);
                        } 
                        Add(memberDataContract.StableName, memberDataContract); 
                    }
                } 
            }
            AddKnownDataContracts(classDataContract.KnownDataContracts);
        }
 
        void AddCollectionDataContract(CollectionDataContract collectionDataContract)
        { 
            if (collectionDataContract.IsDictionary) 
            {
                ClassDataContract keyValueContract = collectionDataContract.ItemContract as ClassDataContract; 
                AddClassDataContract(keyValueContract);
            }
            else
            { 
                DataContract itemContract = GetItemTypeDataContract(collectionDataContract);
                if (itemContract != null) 
                    Add(itemContract.StableName, itemContract); 
            }
            AddKnownDataContracts(collectionDataContract.KnownDataContracts); 
        }

        void AddXmlDataContract(XmlDataContract xmlDataContract)
        { 
            AddKnownDataContracts(xmlDataContract.KnownDataContracts);
        } 
 
        void AddKnownDataContracts(DataContractDictionary knownDataContracts)
        { 
            if (knownDataContracts != null)
            {
                foreach (DataContract knownDataContract in knownDataContracts.Values)
                { 
                    Add(knownDataContract);
                } 
            } 
        }
 
        internal XmlQualifiedName GetStableName(Type clrType)
        {
            if (dataContractSurrogate != null)
            { 
                Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, clrType);
 
                //if (clrType.IsValueType != dcType.IsValueType) 
                //    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.ValueTypeMismatchInSurrogatedType, dcType, clrType)));
                return DataContract.GetStableName(dcType); 
            }
            return DataContract.GetStableName(clrType);
        }
 
        internal DataContract GetDataContract(Type clrType)
        { 
            if (dataContractSurrogate == null) 
                return DataContract.GetDataContract(clrType);
            DataContract dataContract = DataContract.GetBuiltInDataContract(clrType); 
            if(dataContract != null)
                return dataContract;
            Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, clrType);
            //if (clrType.IsValueType != dcType.IsValueType) 
            //    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.ValueTypeMismatchInSurrogatedType, dcType, clrType)));
            dataContract = DataContract.GetDataContract(dcType); 
            if (!SurrogateDataTable.Contains(dataContract)) 
            {
                object customData = DataContractSurrogateCaller.GetCustomDataToExport( 
                                      dataContractSurrogate, clrType, dcType);
                if (customData != null)
                    SurrogateDataTable.Add(dataContract, customData);
            } 
            return dataContract;
        } 
 
        internal DataContract GetMemberTypeDataContract(DataMember dataMember)
        { 
            if (dataMember.MemberInfo != null)
            {
                Type dataMemberType = dataMember.MemberType;
                if (dataMember.IsGetOnlyCollection) 
                {
                    if (dataContractSurrogate != null) 
                    { 
                        Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, dataMemberType);
                        if (dcType != dataMemberType) 
                        {
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SurrogatesWithGetOnlyCollectionsNotSupported,
                                DataContract.GetClrTypeFullName(dataMemberType), DataContract.GetClrTypeFullName(dataMember.MemberInfo.DeclaringType), dataMember.MemberInfo.Name)));
                        } 
                    }
                    return DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(dataMemberType.TypeHandle), dataMemberType.TypeHandle, dataMemberType, SerializationMode.SharedContract); 
                } 
                else
                { 
                    return GetDataContract(dataMemberType);
                }
            }
            return dataMember.MemberTypeContract; 
        }
 
        internal DataContract GetItemTypeDataContract(CollectionDataContract collectionContract) 
        {
            if (collectionContract.ItemType != null) 
                return GetDataContract(collectionContract.ItemType);
            return collectionContract.ItemContract;
        }
 
        internal object GetSurrogateData(object key)
        { 
            return SurrogateDataTable[key]; 
        }
 
        internal void SetSurrogateData(object key, object surrogateData)
        {
            SurrogateDataTable[key] = surrogateData;
        } 

        public DataContract this[XmlQualifiedName key] 
        { 
            get
            { 
                DataContract dataContract = DataContract.GetBuiltInDataContract(key.Name, key.Namespace);
                if (dataContract == null)
                {
                    Contracts.TryGetValue(key, out dataContract); 
                }
                return dataContract; 
            } 
        }
 
        public IDataContractSurrogate DataContractSurrogate
        {
            get { return dataContractSurrogate;}
        } 

        public bool Remove(XmlQualifiedName key) 
        { 
            if (DataContract.GetBuiltInDataContract(key.Name, key.Namespace) != null)
                return false; 
            return Contracts.Remove(key);
        }

        public IEnumerator> GetEnumerator() 
        {
            return Contracts.GetEnumerator(); 
        } 

        internal bool IsContractProcessed(DataContract dataContract) 
        {
            return ProcessedContracts.ContainsKey(dataContract);
        }
 
        internal void SetContractProcessed(DataContract dataContract)
        { 
            ProcessedContracts.Add(dataContract, dataContract); 
        }
 
        internal ContractCodeDomInfo GetContractCodeDomInfo(DataContract dataContract)
        {
            object info;
            if (ProcessedContracts.TryGetValue(dataContract, out info)) 
                return (ContractCodeDomInfo)info;
            return null; 
        } 

        internal void SetContractCodeDomInfo(DataContract dataContract, ContractCodeDomInfo info) 
        {
            ProcessedContracts.Add(dataContract, info);
        }
        Dictionary GetReferencedTypes() 
        {
            if (referencedTypesDictionary == null) 
            { 
                referencedTypesDictionary = new Dictionary();
                //Always include Nullable as referenced type 
                //Do not allow surrogating Nullable
                referencedTypesDictionary.Add(DataContract.GetStableName(Globals.TypeOfNullable), Globals.TypeOfNullable);
                if (this.referencedTypes != null)
                { 
                    foreach (Type type in this.referencedTypes)
                    { 
                        if (type == null) 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypesCannotContainNull)));
                        AddReferencedType(referencedTypesDictionary, type); 
                    }
                }
            }
            return referencedTypesDictionary; 
        }
 
        Dictionary GetReferencedCollectionTypes() 
        {
            if (referencedCollectionTypesDictionary == null) 
            {
                referencedCollectionTypesDictionary = new Dictionary();
                if (this.referencedCollectionTypes != null)
                { 
                    foreach (Type type in this.referencedCollectionTypes)
                    { 
                        if (type == null) 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedCollectionTypesCannotContainNull)));
                        AddReferencedType(referencedCollectionTypesDictionary, type); 
                    }
                }
                XmlQualifiedName genericDictionaryName = DataContract.GetStableName(Globals.TypeOfDictionaryGeneric);
                if (!referencedCollectionTypesDictionary.ContainsKey(genericDictionaryName) && GetReferencedTypes().ContainsKey(genericDictionaryName)) 
                    AddReferencedType(referencedCollectionTypesDictionary, Globals.TypeOfDictionaryGeneric);
            } 
            return referencedCollectionTypesDictionary; 
        }
 
        void AddReferencedType(Dictionary referencedTypes, Type type)
        {
            if (IsTypeReferenceable(type))
            { 
                XmlQualifiedName stableName = this.GetStableName(type);
                object value; 
                if (referencedTypes.TryGetValue(stableName, out value)) 
                {
                    Type referencedType = value as Type; 
                    if (referencedType != null)
                    {
                        if (referencedType != type)
                        { 
                            referencedTypes.Remove(stableName);
                            List types = new List(); 
                            types.Add(referencedType); 
                            types.Add(type);
                            referencedTypes.Add(stableName, types); 
                        }
                    }
                    else
                    { 
                        List types = (List)value;
                        if (!types.Contains(type)) 
                            types.Add(type); 
                    }
                } 
                else
                    referencedTypes.Add(stableName, type);
            }
        } 
        internal bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
        { 
            return TryGetReferencedType(stableName, dataContract, false/*useReferencedCollectionTypes*/, out type); 
        }
 
        internal bool TryGetReferencedCollectionType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
        {
            return TryGetReferencedType(stableName, dataContract, true/*useReferencedCollectionTypes*/, out type);
        } 

        bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, bool useReferencedCollectionTypes, out Type type) 
        { 
            object value;
            Dictionary referencedTypes = useReferencedCollectionTypes ? GetReferencedCollectionTypes() : GetReferencedTypes(); 
            if (referencedTypes.TryGetValue(stableName, out value))
            {
                type = value as Type;
                if (type != null) 
                    return true;
                else 
                { 
                    // Throw ambiguous type match exception
                    List types = (List)value; 
                    StringBuilder errorMessage = new StringBuilder();
                    bool containsGenericType = false;
                    for (int i = 0; i < types.Count; i++)
                    { 
                        Type conflictingType = types[i];
                        if (!containsGenericType) 
                            containsGenericType = conflictingType.IsGenericTypeDefinition; 
                        errorMessage.AppendFormat("{0}\"{1}\" ", Environment.NewLine, conflictingType.AssemblyQualifiedName);
                        if (dataContract != null) 
                        {
                            DataContract other = this.GetDataContract(conflictingType);
                            errorMessage.Append(SR.GetString(((other != null && other.Equals(dataContract)) ? SR.ReferencedTypeMatchingMessage : SR.ReferencedTypeNotMatchingMessage)));
                        } 
                    }
                    if (containsGenericType) 
                    { 
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(
                            (useReferencedCollectionTypes ? SR.AmbiguousReferencedCollectionTypes1 : SR.AmbiguousReferencedTypes1), 
                            errorMessage.ToString())));
                    }
                    else
                    { 
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(
                            (useReferencedCollectionTypes ? SR.AmbiguousReferencedCollectionTypes3 : SR.AmbiguousReferencedTypes3), 
                            XmlConvert.DecodeName(stableName.Name), 
                            stableName.Namespace,
                            errorMessage.ToString()))); 
                    }
                }
            }
            type = null; 
            return false;
        } 
 
        static bool IsTypeReferenceable(Type type)
        { 
            Type itemType;
            return (type.IsSerializable ||
                    type.IsDefined(Globals.TypeOfDataContractAttribute, false) ||
                    (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type) && !type.IsGenericTypeDefinition) || 
                    CollectionDataContract.IsCollection(type, out itemType) ||
                    ClassDataContract.IsNonAttributedTypeValidForSerialization(type)); 
        } 
    }
} 




// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK