AttributeEmitter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntityDesign / Design / System / Data / EntityModel / Emitters / AttributeEmitter.cs / 1305376 / AttributeEmitter.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.CodeDom; 

using System.Diagnostics;
using System.Data.SqlTypes;
using System.Data.Metadata.Edm; 
using System.Collections.Generic;
using System.Data.Entity.Design; 
using System.Data.Entity.Design.Common; 
using System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity.Design.SsdlGenerator; 
using System.Globalization;


namespace System.Data.EntityModel.Emitters 
{
    ///  
    /// Summary description for AttributeEmitter. 
    /// 
    internal sealed class AttributeEmitter 
    {
        TypeReference _typeReference;

        internal TypeReference TypeReference 
        {
            get { return _typeReference; } 
        } 

        static readonly string AdoAttributeDataClassesNamespace = "System.Data.Objects.DataClasses"; 
        internal AttributeEmitter(TypeReference typeReference)
        {
            _typeReference = typeReference;
        } 

        ///  
        /// The method to be called to create the type level attributes for the ItemTypeEmitter 
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(EntityTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        {
            Debug.Assert(emitter != null, "emitter should not be null"); 
            Debug.Assert(typeDecl != null, "typeDecl should not be null");
 
            EmitSchemaTypeAttribute(FQAdoFrameworkDataClassesName("EdmEntityTypeAttribute"), emitter, typeDecl); 

            CodeAttributeDeclaration attribute2 = EmitSimpleAttribute("System.Runtime.Serialization.DataContractAttribute"); 
            AttributeEmitter.AddNamedAttributeArguments(attribute2,
                    "IsReference", true);
            typeDecl.CustomAttributes.Add(attribute2);
 
            CodeAttributeDeclaration attribute3 = EmitSimpleAttribute("System.Serializable");
            typeDecl.CustomAttributes.Add(attribute3); 
 
            EmitKnownTypeAttributes(emitter.Item, emitter.Generator, typeDecl);
        } 

        private void EmitKnownTypeAttributes(EdmType baseType, ClientApiGenerator generator, CodeTypeDeclaration typeDecl)
        {
            foreach (EdmType edmType in generator.GetDirectSubTypes(baseType)) 
            {
                Debug.Assert(edmType.BaseType == baseType, "The types must be directly derived from basetype"); 
 
                CodeTypeReference subTypeRef;
                if (generator.Language == LanguageOption.GenerateCSharpCode) 
                {
                    bool useGlobalPrefix = true;
                    subTypeRef = generator.GetFullyQualifiedTypeReference(edmType, useGlobalPrefix);
                } 
                else
                { 
                    Debug.Assert(generator.Language == LanguageOption.GenerateVBCode, "Did you add a new language?"); 
                    subTypeRef = generator.GetLeastPossibleQualifiedTypeReference(edmType);
                } 
                CodeAttributeDeclaration attribute = EmitSimpleAttribute("System.Runtime.Serialization.KnownTypeAttribute", new CodeTypeOfExpression(subTypeRef));
                typeDecl.CustomAttributes.Add(attribute);
            }
        } 

        ///  
        /// The method to be called to create the type level attributes for the StructuredTypeEmitter 
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(StructuredTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        {
            Debug.Assert(emitter != null, "emitter should not be null"); 
            Debug.Assert(typeDecl != null, "typeDecl should not be null");
 
            // nothing to do here yet 
        }
 
        /// 
        /// The method to be called to create the type level attributes for the SchemaTypeEmitter
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(SchemaTypeEmitter emitter, CodeTypeDeclaration typeDecl) 
        { 
            Debug.Assert(emitter != null, "emitter should not be null");
            Debug.Assert(typeDecl != null, "typeDecl should not be null"); 
        }

        /// 
        /// Common way to fill out EdmTypeAttribute derived attributes 
        /// 
        /// Unqualified name of the attribute 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitSchemaTypeAttribute(string attributeName, SchemaTypeEmitter emitter, CodeTypeDeclaration typeDecl) 
        {
            // call the shared static version
            EdmType type = emitter.Item as EdmType;
            Debug.Assert(type != null, "type is not an EdmType"); 
            EmitSchemaTypeAttribute(attributeName, type, typeDecl as CodeTypeMember);
        } 
 
        /// 
        /// Shared code for adding a EdmTypeAttribute derived attribute including parameters to a type or property 
        /// 
        /// Unqualified name of the attribute
        /// The type or property type of the code that is having the attribute attached.
        /// The type declaration to add the attribues to. 
        public void EmitSchemaTypeAttribute(string attributeName, EdmType type, CodeTypeMember member)
        { 
            Debug.Assert(attributeName != null, "attributeName should not be null"); 
            Debug.Assert(type != null, "type should not be null");
            Debug.Assert(member != null, "typeDecl should not be null"); 

            // [mappingattribute(SchemaName="namespace",TypeName="classname")
            CodeAttributeDeclaration attribute = EmitSimpleAttribute(attributeName);
            AttributeEmitter.AddNamedAttributeArguments(attribute, 
                    "NamespaceName", type.NamespaceName,
                    "Name", type.Name); 
 
            member.CustomAttributes.Add(attribute);
        } 

        /// 
        /// Emit the attributes for the new navigation property
        ///  
        /// The ClientApiGenerator instance
        /// The relationship end that is being targeted 
        /// The property declaration to attach the attribute to. 
        /// Additional attributes
        public void EmitNavigationPropertyAttributes(ClientApiGenerator generator, 
                                                     RelationshipEndMember targetRelationshipEnd,
                                                     CodeMemberProperty propertyDecl,
                                                     List additionalAttributes)
        { 
            CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmRelationshipNavigationPropertyAttribute"),
                targetRelationshipEnd.DeclaringType.NamespaceName, 
                targetRelationshipEnd.DeclaringType.Name, 
                targetRelationshipEnd.Name);
 
            propertyDecl.CustomAttributes.Add(attribute);
            EmitGeneratedCodeAttribute(propertyDecl);
            if (additionalAttributes != null && additionalAttributes.Count > 0)
            { 
                try
                { 
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray()); 
                }
                catch (ArgumentNullException e) 
                {
                    generator.AddError(Strings.InvalidAttributeSuppliedForProperty(propertyDecl.Name),
                                       ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error, 
                                       e);
                } 
            } 
        }
 
        //
        //
        // Emit
        //     [global::System.CodeDom.Compiler.GeneratedCode("System.Data.Entity.Design.EntityClassGenerator", "4.0.0.0")] 
        //
        // this allows FxCop to skip analysis of these methods and types, it should not be applied to partial types, only the 
        // generated members of partial types 
        //
        CodeAttributeDeclaration _GeneratedCodeAttribute; 
        internal void EmitGeneratedCodeAttribute(CodeTypeMember member)
        {
            if(_GeneratedCodeAttribute == null)
            { 
                _GeneratedCodeAttribute = EmitSimpleAttribute("System.CodeDom.Compiler.GeneratedCode",
                    "System.Data.Entity.Design.EntityClassGenerator", 
                    typeof(EntityClassGenerator).Assembly.GetName().Version.ToString()); 

            } 

            member.CustomAttributes.Add(_GeneratedCodeAttribute);
        }
 
        /// 
        /// The method to be called to create the property level attributes for the PropertyEmitter 
        ///  
        /// The strongly typed emitter
        /// The type declaration to add the attribues to. 
        /// Additional attributes to emit
        public void EmitPropertyAttributes(PropertyEmitter emitter,
                                           CodeMemberProperty propertyDecl,
                                           List additionalAttributes) 
        {
            if (MetadataUtil.IsPrimitiveType(emitter.Item.TypeUsage.EdmType) || MetadataUtil.IsEnumerationType(emitter.Item.TypeUsage.EdmType)) 
            { 
                CodeAttributeDeclaration scalarPropertyAttribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmScalarPropertyAttribute"));
 
                if (emitter.IsKeyProperty)
                {
                    Debug.Assert(emitter.Item.Nullable == false, "An EntityKeyProperty cannot be nullable.");
 
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "EntityKeyProperty", true);
                } 
 
                if (!emitter.Item.Nullable)
                { 
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "IsNullable", false);
                }

                propertyDecl.CustomAttributes.Add(scalarPropertyAttribute); 
            }
            else //Complex property 
            { 
                Debug.Assert(MetadataUtil.IsComplexType(emitter.Item.TypeUsage.EdmType) ||
                             (MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)), 
                             "not a complex type or a collection type");
                CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmComplexPropertyAttribute"));
                propertyDecl.CustomAttributes.Add(attribute);
 
                // Have CodeDOM serialization set the properties on the ComplexObject, not the ComplexObject instance.
                attribute = EmitSimpleAttribute("System.ComponentModel.DesignerSerializationVisibility"); 
                AttributeEmitter.AddAttributeArguments(attribute, 
                    new object[] { new CodePropertyReferenceExpression(
                        new CodeTypeReferenceExpression(TypeReference.ForType( 
                            typeof(System.ComponentModel.DesignerSerializationVisibility))),"Content") });
                propertyDecl.CustomAttributes.Add(attribute);

                if (!MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)) 
                {
                    // Non-collection complex properties also need additional serialization attributes to force them to be explicitly serialized if they are null 
                    // If this is omitted, null complex properties do not get explicitly set to null during deserialization, which causes 
                    // them to be lazily constructed once the property is accessed after the entity is deserialized. If the property is
                    // actually null during serialiation, that means the user has explicitly set it, so we need to maintain that during serialization. 
                    // This doesn't apply to collection types because they aren't lazily constructed and don't need this extra information.
                    attribute = EmitSimpleAttribute("System.Xml.Serialization.XmlElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute); 

                    attribute = EmitSimpleAttribute("System.Xml.Serialization.SoapElement"); 
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true); 
                    propertyDecl.CustomAttributes.Add(attribute);
                } 

            }

            // serialization attribute 
            AddDataMemberAttribute(propertyDecl);
 
            if (additionalAttributes != null && additionalAttributes.Count > 0) 
            {
                try 
                {
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray());
                }
                catch (ArgumentNullException e) 
                {
                    emitter.Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(emitter.Item.Name), 
                                               ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty, 
                                               EdmSchemaErrorSeverity.Error,
                                               e); 
                }
            }

            EmitGeneratedCodeAttribute(propertyDecl); 
        }
 
        ///  
        /// The method to be called to create the type level attributes for the NestedTypeEmitter
        ///  
        /// The strongly typed emitter
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(ComplexTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        { 
            Debug.Assert(emitter != null, "emitter should not be null");
            Debug.Assert(typeDecl != null, "typeDecl should not be null"); 
 
            EmitSchemaTypeAttribute(FQAdoFrameworkDataClassesName("EdmComplexTypeAttribute"),
                emitter, typeDecl); 

            CodeAttributeDeclaration attribute = EmitSimpleAttribute("System.Runtime.Serialization.DataContractAttribute");
            AttributeEmitter.AddNamedAttributeArguments(attribute,
                    "IsReference", true); 
            typeDecl.CustomAttributes.Add(attribute);
 
            CodeAttributeDeclaration attribute2 = EmitSimpleAttribute("System.Serializable"); 
            typeDecl.CustomAttributes.Add(attribute2);
 
            EmitKnownTypeAttributes(emitter.Item, emitter.Generator, typeDecl);
        }

        #region Static Methods 
        /// 
        /// Returns the name qualified with the Ado.Net EDM DataClasses Attribute namespace 
        ///  
        /// 
        ///  
        public static string FQAdoFrameworkDataClassesName(string unqualifiedName)
        {
            return AdoAttributeDataClassesNamespace + "." + unqualifiedName;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        public CodeAttributeDeclaration EmitSimpleAttribute(string attributeType, params object[] arguments)
        { 
            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(TypeReference.FromString(attributeType, true));
 
            AddAttributeArguments(attribute, arguments); 

            return attribute; 
        }

        /// 
        /// 
        /// 
        ///  
        ///  
        public static void AddAttributeArguments(CodeAttributeDeclaration attribute, object[] arguments)
        { 
            foreach (object argument in arguments)
            {
                CodeExpression expression = argument as CodeExpression;
                if (expression == null) 
                    expression = new CodePrimitiveExpression(argument);
                attribute.Arguments.Add(new CodeAttributeArgument(expression)); 
            } 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        public static void AddNamedAttributeArguments(CodeAttributeDeclaration attribute, params object[] arguments) 
        { 
            for (int i = 1; i < arguments.Length; i += 2)
            { 
                CodeExpression expression = arguments[i] as CodeExpression;
                if (expression == null)
                    expression = new CodePrimitiveExpression(arguments[i]);
                attribute.Arguments.Add(new CodeAttributeArgument(arguments[i - 1].ToString(), expression)); 
            }
        } 
 
        /// 
        /// Adds an XmlIgnore attribute to the given property declaration.  This is 
        /// used to explicitly skip certain properties during XML serialization.
        /// 
        /// the property to mark with XmlIgnore
        public void AddIgnoreAttributes(CodeMemberProperty propertyDecl) 
        {
            CodeAttributeDeclaration xmlIgnoreAttribute = EmitSimpleAttribute(typeof(System.Xml.Serialization.XmlIgnoreAttribute).FullName); 
            CodeAttributeDeclaration soapIgnoreAttribute = EmitSimpleAttribute(typeof(System.Xml.Serialization.SoapIgnoreAttribute).FullName); 
            propertyDecl.CustomAttributes.Add(xmlIgnoreAttribute);
            propertyDecl.CustomAttributes.Add(soapIgnoreAttribute); 

        }

        ///  
        /// Adds an Browsable(false) attribute to the given property declaration.
        /// This is used to explicitly avoid display property in the PropertyGrid. 
        ///  
        /// the property to mark with XmlIgnore
        public void AddBrowsableAttribute(CodeMemberProperty propertyDecl) 
        {
            CodeAttributeDeclaration browsableAttribute = EmitSimpleAttribute(typeof(System.ComponentModel.BrowsableAttribute).FullName, false);
            propertyDecl.CustomAttributes.Add(browsableAttribute);
        } 

        public void AddDataMemberAttribute(CodeMemberProperty propertyDecl) 
        { 
            CodeAttributeDeclaration browsableAttribute = EmitSimpleAttribute("System.Runtime.Serialization.DataMemberAttribute");
            propertyDecl.CustomAttributes.Add(browsableAttribute); 
        }

        #endregion
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.CodeDom; 

using System.Diagnostics;
using System.Data.SqlTypes;
using System.Data.Metadata.Edm; 
using System.Collections.Generic;
using System.Data.Entity.Design; 
using System.Data.Entity.Design.Common; 
using System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity.Design.SsdlGenerator; 
using System.Globalization;


namespace System.Data.EntityModel.Emitters 
{
    ///  
    /// Summary description for AttributeEmitter. 
    /// 
    internal sealed class AttributeEmitter 
    {
        TypeReference _typeReference;

        internal TypeReference TypeReference 
        {
            get { return _typeReference; } 
        } 

        static readonly string AdoAttributeDataClassesNamespace = "System.Data.Objects.DataClasses"; 
        internal AttributeEmitter(TypeReference typeReference)
        {
            _typeReference = typeReference;
        } 

        ///  
        /// The method to be called to create the type level attributes for the ItemTypeEmitter 
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(EntityTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        {
            Debug.Assert(emitter != null, "emitter should not be null"); 
            Debug.Assert(typeDecl != null, "typeDecl should not be null");
 
            EmitSchemaTypeAttribute(FQAdoFrameworkDataClassesName("EdmEntityTypeAttribute"), emitter, typeDecl); 

            CodeAttributeDeclaration attribute2 = EmitSimpleAttribute("System.Runtime.Serialization.DataContractAttribute"); 
            AttributeEmitter.AddNamedAttributeArguments(attribute2,
                    "IsReference", true);
            typeDecl.CustomAttributes.Add(attribute2);
 
            CodeAttributeDeclaration attribute3 = EmitSimpleAttribute("System.Serializable");
            typeDecl.CustomAttributes.Add(attribute3); 
 
            EmitKnownTypeAttributes(emitter.Item, emitter.Generator, typeDecl);
        } 

        private void EmitKnownTypeAttributes(EdmType baseType, ClientApiGenerator generator, CodeTypeDeclaration typeDecl)
        {
            foreach (EdmType edmType in generator.GetDirectSubTypes(baseType)) 
            {
                Debug.Assert(edmType.BaseType == baseType, "The types must be directly derived from basetype"); 
 
                CodeTypeReference subTypeRef;
                if (generator.Language == LanguageOption.GenerateCSharpCode) 
                {
                    bool useGlobalPrefix = true;
                    subTypeRef = generator.GetFullyQualifiedTypeReference(edmType, useGlobalPrefix);
                } 
                else
                { 
                    Debug.Assert(generator.Language == LanguageOption.GenerateVBCode, "Did you add a new language?"); 
                    subTypeRef = generator.GetLeastPossibleQualifiedTypeReference(edmType);
                } 
                CodeAttributeDeclaration attribute = EmitSimpleAttribute("System.Runtime.Serialization.KnownTypeAttribute", new CodeTypeOfExpression(subTypeRef));
                typeDecl.CustomAttributes.Add(attribute);
            }
        } 

        ///  
        /// The method to be called to create the type level attributes for the StructuredTypeEmitter 
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(StructuredTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        {
            Debug.Assert(emitter != null, "emitter should not be null"); 
            Debug.Assert(typeDecl != null, "typeDecl should not be null");
 
            // nothing to do here yet 
        }
 
        /// 
        /// The method to be called to create the type level attributes for the SchemaTypeEmitter
        /// 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(SchemaTypeEmitter emitter, CodeTypeDeclaration typeDecl) 
        { 
            Debug.Assert(emitter != null, "emitter should not be null");
            Debug.Assert(typeDecl != null, "typeDecl should not be null"); 
        }

        /// 
        /// Common way to fill out EdmTypeAttribute derived attributes 
        /// 
        /// Unqualified name of the attribute 
        /// The strongly typed emitter 
        /// The type declaration to add the attribues to.
        public void EmitSchemaTypeAttribute(string attributeName, SchemaTypeEmitter emitter, CodeTypeDeclaration typeDecl) 
        {
            // call the shared static version
            EdmType type = emitter.Item as EdmType;
            Debug.Assert(type != null, "type is not an EdmType"); 
            EmitSchemaTypeAttribute(attributeName, type, typeDecl as CodeTypeMember);
        } 
 
        /// 
        /// Shared code for adding a EdmTypeAttribute derived attribute including parameters to a type or property 
        /// 
        /// Unqualified name of the attribute
        /// The type or property type of the code that is having the attribute attached.
        /// The type declaration to add the attribues to. 
        public void EmitSchemaTypeAttribute(string attributeName, EdmType type, CodeTypeMember member)
        { 
            Debug.Assert(attributeName != null, "attributeName should not be null"); 
            Debug.Assert(type != null, "type should not be null");
            Debug.Assert(member != null, "typeDecl should not be null"); 

            // [mappingattribute(SchemaName="namespace",TypeName="classname")
            CodeAttributeDeclaration attribute = EmitSimpleAttribute(attributeName);
            AttributeEmitter.AddNamedAttributeArguments(attribute, 
                    "NamespaceName", type.NamespaceName,
                    "Name", type.Name); 
 
            member.CustomAttributes.Add(attribute);
        } 

        /// 
        /// Emit the attributes for the new navigation property
        ///  
        /// The ClientApiGenerator instance
        /// The relationship end that is being targeted 
        /// The property declaration to attach the attribute to. 
        /// Additional attributes
        public void EmitNavigationPropertyAttributes(ClientApiGenerator generator, 
                                                     RelationshipEndMember targetRelationshipEnd,
                                                     CodeMemberProperty propertyDecl,
                                                     List additionalAttributes)
        { 
            CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmRelationshipNavigationPropertyAttribute"),
                targetRelationshipEnd.DeclaringType.NamespaceName, 
                targetRelationshipEnd.DeclaringType.Name, 
                targetRelationshipEnd.Name);
 
            propertyDecl.CustomAttributes.Add(attribute);
            EmitGeneratedCodeAttribute(propertyDecl);
            if (additionalAttributes != null && additionalAttributes.Count > 0)
            { 
                try
                { 
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray()); 
                }
                catch (ArgumentNullException e) 
                {
                    generator.AddError(Strings.InvalidAttributeSuppliedForProperty(propertyDecl.Name),
                                       ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error, 
                                       e);
                } 
            } 
        }
 
        //
        //
        // Emit
        //     [global::System.CodeDom.Compiler.GeneratedCode("System.Data.Entity.Design.EntityClassGenerator", "4.0.0.0")] 
        //
        // this allows FxCop to skip analysis of these methods and types, it should not be applied to partial types, only the 
        // generated members of partial types 
        //
        CodeAttributeDeclaration _GeneratedCodeAttribute; 
        internal void EmitGeneratedCodeAttribute(CodeTypeMember member)
        {
            if(_GeneratedCodeAttribute == null)
            { 
                _GeneratedCodeAttribute = EmitSimpleAttribute("System.CodeDom.Compiler.GeneratedCode",
                    "System.Data.Entity.Design.EntityClassGenerator", 
                    typeof(EntityClassGenerator).Assembly.GetName().Version.ToString()); 

            } 

            member.CustomAttributes.Add(_GeneratedCodeAttribute);
        }
 
        /// 
        /// The method to be called to create the property level attributes for the PropertyEmitter 
        ///  
        /// The strongly typed emitter
        /// The type declaration to add the attribues to. 
        /// Additional attributes to emit
        public void EmitPropertyAttributes(PropertyEmitter emitter,
                                           CodeMemberProperty propertyDecl,
                                           List additionalAttributes) 
        {
            if (MetadataUtil.IsPrimitiveType(emitter.Item.TypeUsage.EdmType) || MetadataUtil.IsEnumerationType(emitter.Item.TypeUsage.EdmType)) 
            { 
                CodeAttributeDeclaration scalarPropertyAttribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmScalarPropertyAttribute"));
 
                if (emitter.IsKeyProperty)
                {
                    Debug.Assert(emitter.Item.Nullable == false, "An EntityKeyProperty cannot be nullable.");
 
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "EntityKeyProperty", true);
                } 
 
                if (!emitter.Item.Nullable)
                { 
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "IsNullable", false);
                }

                propertyDecl.CustomAttributes.Add(scalarPropertyAttribute); 
            }
            else //Complex property 
            { 
                Debug.Assert(MetadataUtil.IsComplexType(emitter.Item.TypeUsage.EdmType) ||
                             (MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)), 
                             "not a complex type or a collection type");
                CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmComplexPropertyAttribute"));
                propertyDecl.CustomAttributes.Add(attribute);
 
                // Have CodeDOM serialization set the properties on the ComplexObject, not the ComplexObject instance.
                attribute = EmitSimpleAttribute("System.ComponentModel.DesignerSerializationVisibility"); 
                AttributeEmitter.AddAttributeArguments(attribute, 
                    new object[] { new CodePropertyReferenceExpression(
                        new CodeTypeReferenceExpression(TypeReference.ForType( 
                            typeof(System.ComponentModel.DesignerSerializationVisibility))),"Content") });
                propertyDecl.CustomAttributes.Add(attribute);

                if (!MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)) 
                {
                    // Non-collection complex properties also need additional serialization attributes to force them to be explicitly serialized if they are null 
                    // If this is omitted, null complex properties do not get explicitly set to null during deserialization, which causes 
                    // them to be lazily constructed once the property is accessed after the entity is deserialized. If the property is
                    // actually null during serialiation, that means the user has explicitly set it, so we need to maintain that during serialization. 
                    // This doesn't apply to collection types because they aren't lazily constructed and don't need this extra information.
                    attribute = EmitSimpleAttribute("System.Xml.Serialization.XmlElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute); 

                    attribute = EmitSimpleAttribute("System.Xml.Serialization.SoapElement"); 
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true); 
                    propertyDecl.CustomAttributes.Add(attribute);
                } 

            }

            // serialization attribute 
            AddDataMemberAttribute(propertyDecl);
 
            if (additionalAttributes != null && additionalAttributes.Count > 0) 
            {
                try 
                {
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray());
                }
                catch (ArgumentNullException e) 
                {
                    emitter.Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(emitter.Item.Name), 
                                               ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty, 
                                               EdmSchemaErrorSeverity.Error,
                                               e); 
                }
            }

            EmitGeneratedCodeAttribute(propertyDecl); 
        }
 
        ///  
        /// The method to be called to create the type level attributes for the NestedTypeEmitter
        ///  
        /// The strongly typed emitter
        /// The type declaration to add the attribues to.
        public void EmitTypeAttributes(ComplexTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        { 
            Debug.Assert(emitter != null, "emitter should not be null");
            Debug.Assert(typeDecl != null, "typeDecl should not be null"); 
 
            EmitSchemaTypeAttribute(FQAdoFrameworkDataClassesName("EdmComplexTypeAttribute"),
                emitter, typeDecl); 

            CodeAttributeDeclaration attribute = EmitSimpleAttribute("System.Runtime.Serialization.DataContractAttribute");
            AttributeEmitter.AddNamedAttributeArguments(attribute,
                    "IsReference", true); 
            typeDecl.CustomAttributes.Add(attribute);
 
            CodeAttributeDeclaration attribute2 = EmitSimpleAttribute("System.Serializable"); 
            typeDecl.CustomAttributes.Add(attribute2);
 
            EmitKnownTypeAttributes(emitter.Item, emitter.Generator, typeDecl);
        }

        #region Static Methods 
        /// 
        /// Returns the name qualified with the Ado.Net EDM DataClasses Attribute namespace 
        ///  
        /// 
        ///  
        public static string FQAdoFrameworkDataClassesName(string unqualifiedName)
        {
            return AdoAttributeDataClassesNamespace + "." + unqualifiedName;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        public CodeAttributeDeclaration EmitSimpleAttribute(string attributeType, params object[] arguments)
        { 
            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(TypeReference.FromString(attributeType, true));
 
            AddAttributeArguments(attribute, arguments); 

            return attribute; 
        }

        /// 
        /// 
        /// 
        ///  
        ///  
        public static void AddAttributeArguments(CodeAttributeDeclaration attribute, object[] arguments)
        { 
            foreach (object argument in arguments)
            {
                CodeExpression expression = argument as CodeExpression;
                if (expression == null) 
                    expression = new CodePrimitiveExpression(argument);
                attribute.Arguments.Add(new CodeAttributeArgument(expression)); 
            } 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        public static void AddNamedAttributeArguments(CodeAttributeDeclaration attribute, params object[] arguments) 
        { 
            for (int i = 1; i < arguments.Length; i += 2)
            { 
                CodeExpression expression = arguments[i] as CodeExpression;
                if (expression == null)
                    expression = new CodePrimitiveExpression(arguments[i]);
                attribute.Arguments.Add(new CodeAttributeArgument(arguments[i - 1].ToString(), expression)); 
            }
        } 
 
        /// 
        /// Adds an XmlIgnore attribute to the given property declaration.  This is 
        /// used to explicitly skip certain properties during XML serialization.
        /// 
        /// the property to mark with XmlIgnore
        public void AddIgnoreAttributes(CodeMemberProperty propertyDecl) 
        {
            CodeAttributeDeclaration xmlIgnoreAttribute = EmitSimpleAttribute(typeof(System.Xml.Serialization.XmlIgnoreAttribute).FullName); 
            CodeAttributeDeclaration soapIgnoreAttribute = EmitSimpleAttribute(typeof(System.Xml.Serialization.SoapIgnoreAttribute).FullName); 
            propertyDecl.CustomAttributes.Add(xmlIgnoreAttribute);
            propertyDecl.CustomAttributes.Add(soapIgnoreAttribute); 

        }

        ///  
        /// Adds an Browsable(false) attribute to the given property declaration.
        /// This is used to explicitly avoid display property in the PropertyGrid. 
        ///  
        /// the property to mark with XmlIgnore
        public void AddBrowsableAttribute(CodeMemberProperty propertyDecl) 
        {
            CodeAttributeDeclaration browsableAttribute = EmitSimpleAttribute(typeof(System.ComponentModel.BrowsableAttribute).FullName, false);
            propertyDecl.CustomAttributes.Add(browsableAttribute);
        } 

        public void AddDataMemberAttribute(CodeMemberProperty propertyDecl) 
        { 
            CodeAttributeDeclaration browsableAttribute = EmitSimpleAttribute("System.Runtime.Serialization.DataMemberAttribute");
            propertyDecl.CustomAttributes.Add(browsableAttribute); 
        }

        #endregion
 
    }
} 

// 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