/// <summary>
 /// Initializes a new instance of the <see cref="DataContractProxyGenerator"/> class.
 /// </summary>
 /// <param name="proxyGenerator">The client proxy generator against which this will generate code.  Cannot be <c>null</c>.</param>
 /// <param name="type">The type to generate.  Cannot be null.</param>
 /// <param name="typeMapping">A dictionary of <see cref="Entity"/> and related types that maps to their corresponding client-side <see cref="CodeTypeReference"/> representations.</param>
 protected DataContractProxyGenerator(CodeDomClientCodeGenerator proxyGenerator, Type type, IDictionary <Type, CodeTypeDeclaration> typeMapping)
     : base(proxyGenerator)
 {
     Type                  = type;
     _typeMapping          = typeMapping;
     NotificationMethodGen = new NotificationMethodGenerator(proxyGenerator);
 }
Exemple #2
0
        /// <summary>
        /// Generates code for the given custom attributes and adds them to the given <see cref="CodeAttributeDeclarationCollection"/>
        /// </summary>
        /// <param name="proxyGenerator">Root client proxy generator</param>
        /// <param name="referencingType">The referencing type</param>
        /// <param name="getLogWarningMessage">The function to call to get the warning message to be logged</param>
        /// <param name="attributes">Collection of attributes to generate</param>
        /// <param name="outputCollection">The collection to which the generated attributes will be added</param>
        /// <param name="comments">Collection of comments that should be updated if errors are discovered.</param>
        /// <param name="customCommentHeader">A custom comment header that will be displayed for any generated comment errors.</param>
        /// <param name="forcePropagation">Indicates whether or not to force attribute propagation.</param>
        public static void GenerateCustomAttributes(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, Func <AttributeBuilderException, string> getLogWarningMessage, IEnumerable <Attribute> attributes, CodeAttributeDeclarationCollection outputCollection, CodeCommentStatementCollection comments, string customCommentHeader, bool forcePropagation)
        {
            IEnumerable <CodeAttributeDeclaration> cads = GenerateCustomAttributes(proxyGenerator, referencingType, getLogWarningMessage, attributes, comments, customCommentHeader, forcePropagation);

            foreach (var cad in cads)
            {
                outputCollection.Add(cad);
            }
        }
Exemple #3
0
        /// <summary>
        /// Creates the CodeDom CodeExpression for the given value.  Returns null if unable to generate a CodeExpression.
        /// </summary>
        /// <remarks>This method exists solely to help generate code for all object types that can appear in an
        /// attribute declaration, such as typeof()</remarks>
        /// <param name="proxyGenerator">The context for generating code.  It cannot be null.</param>
        /// <param name="referencingType">The referencing type</param>
        /// <param name="value">The value.  Null is permitted.</param>
        /// <returns>The code expression</returns>
        private static CodeExpression CreateCodeExpression(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, object value)
        {
            Type typeOfValue = value == null ? null : value.GetType();

            if (value == null || typeOfValue.IsPrimitive || value is string)
            {
                CodeExpression e = new CodePrimitiveExpression(value);

                // Workaround CodeDom issue -- it looks like CodePrimitiveExpression is fooled and generates double
                // literals as integers when there is no fraction.  We take a general strategy of forcing an explicit
                // compile time cast to ensure we recompile the same type.
                if (value != null && (value is double || value is float))
                {
                    e = new CodeCastExpression(value.GetType(), e);
                }
                return(e);
            }

            // typeof(T) requires special handling
            Type valueAsType = value as Type;

            if (valueAsType != null)
            {
                // Verify the type is shared
                // Don't know counts as not shared
                CodeMemberShareKind shareKind = proxyGenerator.GetTypeShareKind(valueAsType);
                if ((shareKind & CodeMemberShareKind.Shared) == 0)
                {
                    // Here we return a fully-qualified type name to ensure we don't cause compilation
                    // errors by adding invalid 'using' statements into our codedom graph.
                    CodeTypeReference valueTypeReference = CodeGenUtilities.GetTypeReference(valueAsType, proxyGenerator, referencingType, false, /*Use fully qualified name*/ true);
                    valueTypeReference.Options = CodeTypeReferenceOptions.GlobalReference;
                    return(new CodeTypeOfExpression(valueTypeReference));
                }

                return(new CodeTypeOfExpression(CodeGenUtilities.GetTypeReference(valueAsType, proxyGenerator, referencingType)));
            }

            // Enum values need special handling
            if (typeOfValue.IsEnum)
            {
                string enumValueName = Enum.GetName(typeOfValue, value);
                string enumTypeName;
                if (proxyGenerator.ClientProxyCodeGenerationOptions.UseFullTypeNames)
                {
                    enumTypeName = typeOfValue.FullName;
                }
                else
                {
                    enumTypeName = typeOfValue.Name;
                }
                return(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(enumTypeName), enumValueName));
            }

            return(null);
        }
Exemple #4
0
 /// <summary>
 /// Generates code for the given custom attributes and adds them to the given <see cref="CodeAttributeDeclarationCollection"/>
 /// </summary>
 /// <param name="proxyGenerator">Root client proxy generator</param>
 /// <param name="referencingType">The referencing type</param>
 /// <param name="getLogWarningMessage">The function to call to get the warning message to be logged</param>
 /// <param name="attributes">Collection of attributes to generate</param>
 /// <param name="outputCollection">The collection to which the generated attributes will be added</param>
 /// <param name="comments">Collection of comments that should be updated if errors are discovered.</param>
 public static void GenerateCustomAttributes(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, Func <AttributeBuilderException, string> getLogWarningMessage, IEnumerable <Attribute> attributes, CodeAttributeDeclarationCollection outputCollection, CodeCommentStatementCollection comments)
 {
     GenerateCustomAttributes(
         proxyGenerator,
         referencingType,
         getLogWarningMessage,
         attributes,
         outputCollection,
         comments,
         Resource.ClientCodeGen_Attribute_FailedToGenerate);
 }
Exemple #5
0
 /// <summary>
 /// Generates code for the given custom attributes and adds them to the given <see cref="CodeAttributeDeclarationCollection"/>
 /// </summary>
 /// <param name="proxyGenerator">Root client proxy generator</param>
 /// <param name="referencingType">The referencing type</param>
 /// <param name="attributes">Collection of attributes to generate</param>
 /// <param name="outputCollection">The collection to which the generated attributes will be added</param>
 /// <param name="comments">Collection of comments that should be updated if errors are discovered.</param>
 /// <param name="forcePropagation">Indicates whether or not to force attribute propagation.</param>
 public static void GenerateCustomAttributes(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, IEnumerable <Attribute> attributes, CodeAttributeDeclarationCollection outputCollection, CodeCommentStatementCollection comments, bool forcePropagation)
 {
     GenerateCustomAttributes(
         proxyGenerator,
         referencingType,
         null,
         attributes,
         outputCollection,
         comments,
         Resource.ClientCodeGen_Attribute_FailedToGenerate,
         forcePropagation);
 }
        private static CodeDomClientCodeGenerator CreateProxyGenerator(bool isCSharp)
        {
            MockCodeGenerationHost     host      = new MockCodeGenerationHost();
            CodeDomClientCodeGenerator generator = isCSharp
                                                        ? (CodeDomClientCodeGenerator) new CSharpCodeDomClientCodeGenerator()
                                                        : (CodeDomClientCodeGenerator) new VisualBasicCodeDomClientCodeGenerator();
            ClientCodeGenerationOptions options = new ClientCodeGenerationOptions()
            {
                Language = isCSharp ? "C#" : "VB",
            };

            generator.Initialize(host, new DomainServiceDescription[] { DomainServiceDescription.GetDescription(typeof(MockOrder_DomainService)) }, options);
            return(generator);
        }
        private static CodeDomClientCodeGenerator CreateProxyGenerator(bool isCSharp)
        {
            MockCodeGenerationHost     host      = new MockCodeGenerationHost();
            CodeDomClientCodeGenerator generator = isCSharp
                                                        ? (CodeDomClientCodeGenerator) new CSharpCodeDomClientCodeGenerator()
                                                        : (CodeDomClientCodeGenerator) new VisualBasicCodeDomClientCodeGenerator();
            ClientCodeGenerationOptions options = new ClientCodeGenerationOptions()
            {
                Language = isCSharp ? "C#" : "VB",
            };

            var entityDescription = new EntityDescription();

            generator.Initialize(host, new EntityDescription[] { entityDescription }, options);

            return(generator);
        }
Exemple #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NotificationMethodGenerator"/> class.
        /// </summary>
        /// <param name="proxyGenerator">The current <see cref="CodeDomClientCodeGenerator"/>.</param>
        /// <param name="indentLevel">The indentation level for the code to write.</param>
        public NotificationMethodGenerator(CodeDomClientCodeGenerator proxyGenerator, IndentationLevel indentLevel)
        {
            this.proxyGenerator = proxyGenerator;
            this.isCSharp       = proxyGenerator.IsCSharp;
            int level = (int)indentLevel;

            if (level < 0)
            {
                level = (int)DefaultIndentLevel;
            }

            while (level-- > 0)
            {
                this.indent += IndentString;
            }

            this.AddMethodFor("Created", Resource.CommentOnCreated); // add default partial method.
        }
Exemple #9
0
        /// <summary>
        /// Creates a <see cref="CodeAttributeDeclaration"/> for the given <see cref="AttributeDeclaration"/>.
        /// </summary>
        /// <param name="proxyGenerator">The context for generating code.  It cannot be null.</param>
        /// <param name="referencingType">The referencing type.</param>
        /// <param name="attributeDeclaration">The <see cref="AttributeDeclaration"/> to build.</param>
        /// <returns>A <see cref="CodeAttributeDeclaration"/>.</returns>
        private static CodeAttributeDeclaration CreateCodeAttributeDeclaration(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, AttributeDeclaration attributeDeclaration)
        {
            CodeAttributeDeclaration codeAttributeDeclaration = CodeGenUtilities.CreateAttributeDeclaration(attributeDeclaration.AttributeType, proxyGenerator, referencingType);

            // Add ctor args
            foreach (object arg in attributeDeclaration.ConstructorArguments)
            {
                CodeExpression expression = CreateCodeExpression(proxyGenerator, referencingType, arg);
                codeAttributeDeclaration.Arguments.Add(new CodeAttributeArgument(expression));
            }

            // Add named params
            foreach (KeyValuePair <string, object> pair in attributeDeclaration.NamedParameters)
            {
                CodeExpression expression = CreateCodeExpression(proxyGenerator, referencingType, pair.Value);
                codeAttributeDeclaration.Arguments.Add(new CodeAttributeArgument(pair.Key, expression));
            }

            return(codeAttributeDeclaration);
        }
Exemple #10
0
        /// <summary>
        /// Generates an attribute declaration string.  This is used in scenarios where an attribute declaration is needed
        /// in the form of a comment.  CodeDOM does not support generation of standalone attributes.
        /// </summary>
        /// <param name="proxyGenerator">The context for generating code.  It cannot be null.</param>
        /// <param name="attributeDeclaration">The <see cref="AttributeDeclaration"/> to represent.</param>
        /// <returns>An attribute declaration.</returns>
        private static string GenerateCodeAttribute(CodeDomClientCodeGenerator proxyGenerator, AttributeDeclaration attributeDeclaration)
        {
            StringBuilder result   = new StringBuilder();
            bool          isCSharp = proxyGenerator.IsCSharp;

            result.Append(isCSharp ? '[' : '<');
            result.Append(attributeDeclaration.AttributeType.Name);
            result.Append('(');

            // Add ctor args
            if (attributeDeclaration.ConstructorArguments.Count > 0)
            {
                foreach (object value in attributeDeclaration.ConstructorArguments)
                {
                    result.Append(ConvertValueToCode(value, isCSharp));
                    result.Append(", ");
                }
            }

            // Add named params
            if (attributeDeclaration.NamedParameters.Count > 0)
            {
                foreach (KeyValuePair <string, object> pair in attributeDeclaration.NamedParameters)
                {
                    result.Append(pair.Key);
                    result.Append(isCSharp ? " = " : " := ");
                    result.Append(ConvertValueToCode(pair.Value, isCSharp));
                    result.Append(", ");
                }
            }

            if (attributeDeclaration.ConstructorArguments.Count > 0 || attributeDeclaration.NamedParameters.Count > 0)
            {
                result.Remove(result.Length - 2, 2);
            }

            result.Append(')');
            result.Append(isCSharp ? "]" : "> _");

            return(result.ToString());
        }
        private string GenerateCode()
        {
            ClientCodeGenerationOptions options = new ClientCodeGenerationOptions()
            {
                Language            = this._isCSharp ? "C#" : "VisualBasic",
                ClientProjectPath   = "MockProject.proj",
                ClientRootNamespace = "TestRootNS",
                UseFullTypeNames    = this._useFullTypeNames
            };

            MockCodeGenerationHost     host      = TestHelper.CreateMockCodeGenerationHost(this.ConsoleLogger, this.MockSharedCodeService);
            CodeDomClientCodeGenerator generator = (this._isCSharp)
                                                        ? (CodeDomClientCodeGenerator) new CSharpCodeDomClientCodeGenerator()
                                                        : (CodeDomClientCodeGenerator) new VisualBasicCodeDomClientCodeGenerator();

            this._domainServiceCatalog = new DomainServiceCatalog(this._domainServiceTypes, this.ConsoleLogger);

            string generatedCode = generator.GenerateCode(host, this._domainServiceCatalog.DomainServiceDescriptions, options);

            return(generatedCode);
        }
Exemple #12
0
        /// <summary>
        /// Verifies that a <see cref="AttributeDeclaration"/>'s shared type requirements are met.
        /// </summary>
        /// <param name="proxyGenerator">The context for code generation</param>
        /// <param name="attributeDeclaration">The <see cref="AttributeDeclaration"/> to verify.</param>
        private static void ValidateAttributeDeclarationRequirements(CodeDomClientCodeGenerator proxyGenerator, AttributeDeclaration attributeDeclaration)
        {
            // Verify the attribute itself is shared.
            CodeMemberShareKind shareKind = proxyGenerator.GetTypeShareKind(attributeDeclaration.AttributeType);

            // If there is no PDB or this type has no human-authored code, we cannot determine
            // whether it is shared and get a null value.  This requires a special message to
            // explain why we treat the type as not shared.
            if (shareKind == CodeMemberShareKind.Unknown)
            {
                attributeDeclaration.Errors.Add(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resource.ClientCodeGen_Attribute_RequiresShared_NoPDB,
                        attributeDeclaration.AttributeType,
                        attributeDeclaration.AttributeType.Assembly.GetName().Name,
                        proxyGenerator.ClientProjectName));
            }
            else if (shareKind == CodeMemberShareKind.NotShared)
            {
                attributeDeclaration.Errors.Add(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resource.ClientCodeGen_Attribute_RequiresShared,
                        attributeDeclaration.AttributeType,
                        proxyGenerator.ClientProjectName));
            }

            // Verify shared types.  Here, we order by type name so that any generated errors
            // are presented in a consistent order.
            foreach (var type in attributeDeclaration.RequiredTypes.OrderBy(t => t.FullName))
            {
                shareKind = proxyGenerator.GetTypeShareKind(type);

                // Missing PDB or lack of user code means we cannot know -- issue special warning
                if (shareKind == CodeMemberShareKind.Unknown)
                {
                    attributeDeclaration.Errors.Add(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resource.ClientCodeGen_Attribute_RequiresShared_Type_NoPDB,
                            attributeDeclaration.AttributeType,
                            type,
                            type.Assembly.GetName().Name,
                            proxyGenerator.ClientProjectName));
                }
                else if (shareKind == CodeMemberShareKind.NotShared)
                {
                    attributeDeclaration.Errors.Add(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resource.ClientCodeGen_Attribute_RequiresShared_Type,
                            attributeDeclaration.AttributeType,
                            type,
                            proxyGenerator.ClientProjectName));
                }
            }

            // Verify shared methods.  Here, we order by method name so that any generated errors
            // are presented in a consistent order.
            foreach (var method in attributeDeclaration.RequiredMethods.OrderBy(p => p.Name))
            {
                shareKind = proxyGenerator.GetMethodShareKind(method);
                if (shareKind == CodeMemberShareKind.NotShared)
                {
                    attributeDeclaration.Errors.Add(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resource.ClientCodeGen_Attribute_RequiresShared_Method,
                            attributeDeclaration.AttributeType,
                            method.Name,
                            method.DeclaringType,
                            proxyGenerator.ClientProjectName));
                }
            }

            // Verify shared properties.  Here, we order by property name so that any generated errors
            // are presented in a consistent order.
            foreach (var property in attributeDeclaration.RequiredProperties.OrderBy(p => p.Name))
            {
                shareKind = proxyGenerator.GetPropertyShareKind(property.DeclaringType, property.Name);
                if (shareKind == CodeMemberShareKind.NotShared)
                {
                    attributeDeclaration.Errors.Add(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resource.ClientCodeGen_Attribute_RequiresShared_Property,
                            attributeDeclaration.AttributeType,
                            property.Name,
                            property.DeclaringType,
                            proxyGenerator.ClientProjectName));
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ProxyGenerator"/> class.
 /// </summary>
 /// <param name="proxyGenerator">Our root client proxy generator holding the compilation context.  Cannot be null.</param>
 protected ProxyGenerator(CodeDomClientCodeGenerator proxyGenerator)
 {
     _proxyGenerator = proxyGenerator;
 }
Exemple #14
0
        /// <summary>
        /// Generates code for the given set of custom attributes
        /// </summary>
        /// <param name="proxyGenerator">Root client proxy generator</param>
        /// <param name="referencingType">The referencing type</param>
        /// <param name="getLogWarningMessage">The function to call to get the warning message to be logged</param>
        /// <param name="attributes">Collection of attributes for which to generate code</param>
        /// <param name="comments">Collection of comments that should be updated if errors are discovered.</param>
        /// <param name="customCommentHeader">A custom comment header that will be displayed for any generated comment errors.</param>
        /// <param name="forcePropagation">Indicates whether or not to force attribute propagation.</param>
        /// <returns>The collection of generated attribute declarations corresponding to <paramref name="attributes"/></returns>
        private static IEnumerable <CodeAttributeDeclaration> GenerateCustomAttributes(CodeDomClientCodeGenerator proxyGenerator, CodeTypeDeclaration referencingType, Func <AttributeBuilderException, string> getLogWarningMessage, IEnumerable <Attribute> attributes, CodeCommentStatementCollection comments, string customCommentHeader, bool forcePropagation)
        {
            var emittedErrorCommentHeader = false;
            var result = new List <CodeAttributeDeclaration>(attributes.Count());

            // Enumerate over attributes sorted by name.  Here, we sort by name to ensure that our
            // generated baselines (including possible error comments!) are ordered consistently.
            foreach (Attribute attribute in attributes.OrderBy(a => a.GetType().Name))
            {
                Type attributeType = attribute.GetType();

                // Check if this attribute should be blocked
                if (IsAttributeBlocked(attributeType))
                {
                    continue;
                }

                bool attributePropagated        = false;
                bool isDataAnnotationsAttribute = string.Equals(attributeType.Namespace, typeof(ValidationAttribute).Namespace, StringComparison.Ordinal);

                ICustomAttributeBuilder cab = GetCustomAttributeBuilder(attributeType);

                if (cab != null)
                {
                    AttributeDeclaration attributeDeclaration = null;
                    // If the attempt to build the attribute fails, log a clean error.
                    // One common exception path is InvalidOperationException arising from
                    // attributes that have been improperly constructed (see DisplayAttribute)
                    try
                    {
                        attributeDeclaration = cab.GetAttributeDeclaration(attribute);
                    }
                    catch (AttributeBuilderException attributeBuilderException)
                    {
                        // Ensure we've generated the attribute generation failure error header
                        GenerateCustomAttributesErrorCommentHeader(comments, customCommentHeader, ref emittedErrorCommentHeader);

                        // Generate comments stating the attribute couldn't be generated
                        comments.AddRange(ConstructCodeAttributeFailureComments(attributeBuilderException.Message));

                        // Log the build warning if a method was specified to get the warning message
                        if (getLogWarningMessage != null)
                        {
                            string warningMessage = getLogWarningMessage(attributeBuilderException);
                            proxyGenerator.LogWarning(warningMessage);
                        }

                        // Move on to the next attribute
                        continue;
                    }

                    // Null is acceptable indicator that code-gen was not possible.
                    if (attributeDeclaration != null)
                    {
                        if (!forcePropagation)
                        {
                            // Verify attribute's shared type|property|method requirements are met
                            ValidateAttributeDeclarationRequirements(proxyGenerator, attributeDeclaration);
                        }

                        if (attributeDeclaration.HasErrors)
                        {
                            // Only generate comments if the attribute is a DataAnnotations attribute
                            //if (isDataAnnotationsAttribute)
                            {
                                // Ensure we've generated the attribute generation failure error header
                                GenerateCustomAttributesErrorCommentHeader(comments, customCommentHeader, ref emittedErrorCommentHeader);

                                // Generate attribute and an error message as comments
                                comments.AddRange(ConstructCodeAttributeFailureComments(proxyGenerator, attributeDeclaration));
                            }
                        }
                        else
                        {
                            // Generate the attribute declaration
                            CodeAttributeDeclaration codeAttributeDeclaration = CreateCodeAttributeDeclaration(proxyGenerator, referencingType, attributeDeclaration);
                            result.Add(codeAttributeDeclaration);
                            attributePropagated = true;
                        }
                    }
                }

                // We generate VS warnings in certain scenarios:
                //  - A DataAnnotation attribute type was not available on the client, user needs to add a reference.
                //  - An attribute subclassed ValidationAttribute (custom or framework) and we couldn't build it.
                if (!attributePropagated)
                {
                    // Was it a DA attribute that wasn't available?  If so, log a warning.
                    if (isDataAnnotationsAttribute)
                    {
                        CodeMemberShareKind shareKind = proxyGenerator.GetTypeShareKind(attributeType);
                        if (shareKind == CodeMemberShareKind.NotShared)
                        {
                            // Indicate that a reference to 'System.ComponentModel.DataAnnotations' is required.
                            proxyGenerator.LogWarning(
                                string.Format(
                                    CultureInfo.CurrentCulture,
                                    Resource.ClientCodeGen_Attribute_RequiresDataAnnotations,
                                    attributeType,
                                    proxyGenerator.ClientProjectName));
                        }
                    }
                    // Was it a validation attribute that we couldn't build?  If so, log a warning.
                    else if (cab == null && typeof(ValidationAttribute).IsAssignableFrom(attributeType))
                    {
                        // Indicate that a builder was not found, attribute does not meet heuristics.
                        proxyGenerator.LogWarning(
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Resource.ClientCodeGen_Attribute_RequiresBuilder,
                                attributeType));
                    }
                }
            }

            // Issue -- CodeDom outputs the attributes in the order they are generated.
            // To allow consistent output for easy baseline comparisons, sort the list.
            result.Sort(new Comparison <CodeAttributeDeclaration>((x, y) => string.Compare(x.Name, y.Name, StringComparison.Ordinal)));
            return(result);
        }
Exemple #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NotificationMethodGenerator"/> class.
 /// </summary>
 /// <param name="proxyGenerator">The current <see cref="CodeDomClientCodeGenerator"/>.</param>
 public NotificationMethodGenerator(CodeDomClientCodeGenerator proxyGenerator) :
     this(proxyGenerator, DefaultIndentLevel)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ProxyGenerator"/> class.
 /// </summary>
 /// <param name="proxyGenerator">Our root client proxy generator holding the compilation context.  Cannot be null.</param>
 protected ProxyGenerator(CodeDomClientCodeGenerator proxyGenerator)
 {
     this._proxyGenerator = proxyGenerator;
 }
Exemple #17
0
        /// <summary>
        /// Generate comments indicating attribute propagation failure.
        /// </summary>
        /// <param name="proxyGenerator">The context for generating code.  It cannot be <c>null</c>.</param>
        /// <param name="attributeDeclaration">The attribute declaration to generate as a comment.</param>
        /// <returns>A collection of comments.</returns>
        private static CodeCommentStatementCollection ConstructCodeAttributeFailureComments(CodeDomClientCodeGenerator proxyGenerator, AttributeDeclaration attributeDeclaration)
        {
            // We are generating failure comments in the following example form:
            //
            //    // Unable to generate the following attribute(s) due to the following error(s):
            //    // - The attribute 'System.ComponentModel.DataAnnotations.CustomValidationAttribute' references type 'ServerOnlyValidator'. This is not accessible in the client project.
            //    // [CustomValidationAttribute(typeof(ServerOnlyValidator), "IsObjectValid")]
            var comments = new CodeCommentStatementCollection();

            foreach (string error in attributeDeclaration.Errors)
            {
                comments.Add(new CodeCommentStatement(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_FailedToGenerate_ErrorTemplate, error)));
            }
            comments.Add(new CodeCommentStatement(GenerateCodeAttribute(proxyGenerator, attributeDeclaration)));
            comments.Add(new CodeCommentStatement(string.Empty /* blank comment */));
            return(comments);
        }