DataContractSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / DataContractSet.cs / 1305376 / 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; 
            InternalAdd(name, dataContract);
        } 
 
        internal void InternalAdd(XmlQualifiedName name, DataContract dataContract)
        { 
            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.
                        

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