コード例 #1
0
        /// <summary>
        /// This is a control function to delegate the creation of the
        /// setter statments to the correct code path
        /// </summary>
        /// <param name="statements">The collection that the setter statements should be added to.</param>
        /// <param name="additionalSetStatements">Additional statements to emit</param>
        private void EmitPropertySetterBody(CodeStatementCollection statements, List <CodeStatement> additionalSetStatements)
        {
            // Invoke the partial method "On[PropertyName]Changing();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangingPartialMethodName(PropertyName), new CodePropertySetValueReferenceExpression()));

            // ReportPropertyChanging( _piFieldName );
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    Utils.ReportPropertyChangingMethodName,
                    new CodePrimitiveExpression(PropertyName)));

            // insert additional statements following the PropertyChanging event
            if (additionalSetStatements != null && additionalSetStatements.Count > 0)
            {
                try
                {
                    statements.AddRange(additionalSetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            if (MetadataUtil.IsPrimitiveType(Item.TypeUsage.EdmType))
            {
                EmitScalarTypePropertySetStatements(statements, CollectionKind.None);
            }
            else if (MetadataUtil.IsComplexType(Item.TypeUsage.EdmType))
            {
                // ComplexTypes have a completely different set pattern:
                EmitComplexTypePropertySetStatements(statements, CollectionKind.None);
            }
            else if (MetadataUtil.IsCollectionType(Item.TypeUsage.EdmType))
            {
                if (MetadataUtil.IsComplexType(((CollectionType)Item.TypeUsage.EdmType).TypeUsage.EdmType))
                {
                    EmitComplexTypePropertySetStatements(statements, GetCollectionKind(Item.TypeUsage));
                }
                else
                {
                    Debug.Assert(MetadataUtil.IsPrimitiveType(((CollectionType)Item.TypeUsage.EdmType).TypeUsage.EdmType),
                                 "Collections should be of primitive types or complex types");
                    EmitScalarTypePropertySetStatements(statements, GetCollectionKind(Item.TypeUsage));
                }
            }
            else if (MetadataUtil.IsEnumerationType(Item.TypeUsage.EdmType))
            {
                // this.fieldName = value;
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef,
                        new CodePropertySetValueReferenceExpression()));
            }

            // ReportPropertyChanged( _piFieldName );
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    Utils.ReportPropertyChangedMethodName,
                    new CodePrimitiveExpression(PropertyName)));

            // Invoke the partial method "On[PropertyName]Changed();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangedPartialMethodName(PropertyName)));
        }
コード例 #2
0
        /// <summary>
        /// Generate a navigation property
        /// </summary>
        /// <param name="target">the other end</param>
        /// <param name="referenceProperty">True to emit Reference navigation property</param>
        /// <returns>the generated property</returns>
        private CodeMemberProperty EmitNavigationProperty(RelationshipEndMember target, bool referenceProperty)
        {
            CodeTypeReference typeRef = GetReturnType(target, referenceProperty);

            // raise the PropertyGenerated event
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(Item,
                                                                                  null, // no backing field
                                                                                  typeRef);

            this.Generator.RaisePropertyGeneratedEvent(eventArgs);

            // [System.ComponentModel.Browsable(false)]
            // public TargetType TargetName
            // public EntityReference<TargetType> TargetName
            // or
            // public EntityCollection<targetType> TargetNames
            CodeMemberProperty property = new CodeMemberProperty();

            if (referenceProperty)
            {
                AttributeEmitter.AddBrowsableAttribute(property);
                Generator.AttributeEmitter.EmitGeneratedCodeAttribute(property);
            }
            else
            {
                Generator.AttributeEmitter.EmitNavigationPropertyAttributes(Generator, target, property, eventArgs.AdditionalAttributes);

                // Only reference navigation properties are currently currently supported with XML serialization
                // and thus we should use the XmlIgnore and SoapIgnore attributes on other property types.
                AttributeEmitter.AddIgnoreAttributes(property);
            }

            AttributeEmitter.AddDataMemberAttribute(property);

            CommentEmitter.EmitSummaryComments(Item, property.Comments);

            property.Name = Item.Name;
            if (referenceProperty)
            {
                property.Name += "Reference";
                if (IsNameAlreadyAMemberName(Item.DeclaringType, property.Name, Generator.LanguageAppropriateStringComparer))
                {
                    Generator.AddError(Strings.GeneratedNavigationPropertyNameConflict(Item.Name, Item.DeclaringType.Name, property.Name),
                                       ModelBuilderErrorCode.GeneratedNavigationPropertyNameConflict,
                                       EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, property.Name);
                }
            }

            if (eventArgs.ReturnType != null && !eventArgs.ReturnType.Equals(typeRef))
            {
                property.Type = eventArgs.ReturnType;
            }
            else
            {
                property.Type = typeRef;
            }

            property.Attributes = MemberAttributes.Final;

            CodeMethodInvokeExpression getMethod = EmitGetMethod(target);
            CodeExpression             getReturnExpression;

            property.Attributes |= AccessibilityFromGettersAndSetters(Item);
            // setup the accessibility of the navigation property setter and getter
            MemberAttributes propertyAccessibility = property.Attributes & MemberAttributes.AccessMask;

            PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                 PropertyEmitter.GetGetterAccessibility(Item), propertyAccessibility, true);
            PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                 PropertyEmitter.GetSetterAccessibility(Item), propertyAccessibility, false);

            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            {
                // insert user-supplied Set code here, before the assignment
                //
                List <CodeStatement> additionalSetStatements = eventArgs.AdditionalSetStatements;
                if (additionalSetStatements != null && additionalSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalSetStatements.ToArray());
                    }
                    catch (ArgumentNullException ex)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           ex);
                    }
                }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();
                if (typeRef != eventArgs.ReturnType)
                {
                    // we need to cast to the actual type
                    valueRef = new CodeCastExpression(typeRef, valueRef);
                }

                if (referenceProperty)
                {
                    // get
                    //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                    getReturnExpression = getMethod;

                    // set
                    // if (value != null)
                    // {
                    //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<TTargetEntity>"CSpaceQualifiedRelationshipName", "TargetRoleName", value);
                    // }

                    CodeMethodReferenceExpression initReferenceMethod = new CodeMethodReferenceExpression();
                    initReferenceMethod.MethodName = "InitializeRelatedReference";

                    initReferenceMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)));
                    initReferenceMethod.TargetObject = new CodePropertyReferenceExpression(
                        new CodeCastExpression(TypeReference.IEntityWithRelationshipsTypeBaseClass, ThisRef),
                        "RelationshipManager");

                    // relationships aren't backed by types so we won't map the namespace
                    // or we can't find the relationship again later
                    string cspaceNamespaceNameQualifiedRelationshipName = target.DeclaringType.FullName;

                    property.SetStatements.Add(
                        new CodeConditionStatement(
                            EmitExpressionDoesNotEqualNull(valueRef),
                            new CodeExpressionStatement(
                                new CodeMethodInvokeExpression(
                                    initReferenceMethod, new CodeExpression[] {
                        new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name), valueRef
                    }))));
                }
                else
                {
                    CodePropertyReferenceExpression valueProperty = new CodePropertyReferenceExpression(getMethod, ValuePropertyName);

                    // get
                    //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value;
                    getReturnExpression = valueProperty;

                    // set
                    //     ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value = value;
                    property.SetStatements.Add(
                        new CodeAssignStatement(valueProperty, valueRef));
                }
            }
            else
            {
                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                getReturnExpression = getMethod;

                // set
                // if (value != null)
                // {
                //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<TTargetEntity>"CSpaceQualifiedRelationshipName", "TargetRoleName", value);
                // }
                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();

                CodeMethodReferenceExpression initCollectionMethod = new CodeMethodReferenceExpression();
                initCollectionMethod.MethodName = "InitializeRelatedCollection";

                initCollectionMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)));
                initCollectionMethod.TargetObject = new CodePropertyReferenceExpression(
                    new CodeCastExpression(TypeReference.IEntityWithRelationshipsTypeBaseClass, ThisRef),
                    "RelationshipManager");

                // relationships aren't backed by types so we won't map the namespace
                // or we can't find the relationship again later
                string cspaceNamespaceNameQualifiedRelationshipName = target.DeclaringType.FullName;

                property.SetStatements.Add(
                    new CodeConditionStatement(
                        EmitExpressionDoesNotEqualNull(valueRef),
                        new CodeExpressionStatement(
                            new CodeMethodInvokeExpression(
                                initCollectionMethod, new CodeExpression[] {
                    new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name), valueRef
                }))));
            }

            // if additional Get statements were specified by the event subscriber, insert them now
            //
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    property.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException ex)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       ex);
                }
            }

            property.GetStatements.Add(new CodeMethodReturnStatement(getReturnExpression));

            return(property);
        }
コード例 #3
0
        /// <summary>
        /// Generate a navigation property
        /// </summary>
        /// <param name="target">the other end</param>
        /// <param name="referenceProperty">True to emit Reference navigation property</param>
        /// <returns>the generated property</returns>
        private CodeMemberProperty EmitNavigationProperty(RelationshipEndMember target)
        {
            CodeTypeReference typeRef = GetReturnType(target);

            // raise the PropertyGenerated event
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(Item,
                                                                                  null, // no backing field
                                                                                  typeRef);

            this.Generator.RaisePropertyGeneratedEvent(eventArgs);

            // [System.ComponentModel.Browsable(false)]
            // public TargetType TargetName
            // public EntityReference<TargetType> TargetName
            // or
            // public EntityCollection<targetType> TargetNames
            CodeMemberProperty property = new CodeMemberProperty();

            // Only reference navigation properties are currently currently supported with XML serialization
            // and thus we should use the XmlIgnore and SoapIgnore attributes on other property types.
            AttributeEmitter.AddIgnoreAttributes(property);

            AttributeEmitter.AddBrowsableAttribute(property);

            AttributeEmitter.AddGeneratedCodeAttribute(property);

            CommentEmitter.EmitSummaryComments(Item, property.Comments);

            property.Name = Item.Name;

            if (eventArgs.ReturnType != null && !eventArgs.ReturnType.Equals(typeRef))
            {
                property.Type = eventArgs.ReturnType;
            }
            else
            {
                property.Type = typeRef;
            }

            property.Attributes = MemberAttributes.Final;

            CodeExpression getMethod = EmitGetMethod(target);
            CodeExpression getReturnExpression;

            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            {
                property.Attributes |= AccessibilityFromGettersAndSetters(Item);

                // insert user-supplied Set code here, before the assignment
                //
                List <CodeStatement> additionalSetStatements = eventArgs.AdditionalSetStatements;
                if (additionalSetStatements != null && additionalSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalSetStatements.ToArray());
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();
                if (typeRef != eventArgs.ReturnType)
                {
                    // we need to cast to the actual type
                    valueRef = new CodeCastExpression(typeRef, valueRef);
                }


                CodeExpression valueProperty = getMethod;

                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value;
                getReturnExpression = valueProperty;

                // set
                //     ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value = value;
                property.SetStatements.Add(
                    new CodeAssignStatement(valueProperty, valueRef));

                // setup the accessibility of the navigation property setter and getter
                MemberAttributes propertyAccessibility = property.Attributes & MemberAttributes.AccessMask;
                PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                     PropertyEmitter.GetGetterAccessibility(Item), propertyAccessibility, true);
                PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                     PropertyEmitter.GetSetterAccessibility(Item), propertyAccessibility, false);

                List <CodeStatement> additionalAfterSetStatements = eventArgs.AdditionalAfterSetStatements;
                if (additionalAfterSetStatements != null && additionalAfterSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalAfterSetStatements.ToArray());
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }
            }
            else
            {
                property.Attributes |= PropertyEmitter.GetGetterAccessibility(Item);
                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                getReturnExpression = getMethod;

                // set
                // if (value != null) ==> Only for non-binding scenario
                // {
                //    this =
                //    this.OnPropertyChanged("")
                // }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();

                CodeStatementCollection csc = null;

                if (this.Generator.UseDataServiceCollection == true)
                {
                    csc = property.SetStatements;
                }
                else
                {
                    CodeConditionStatement ccs = new CodeConditionStatement(EmitExpressionDoesNotEqualNull(valueRef));
                    property.SetStatements.Add(ccs);

                    csc = ccs.TrueStatements;
                }

                csc.Add(new CodeAssignStatement(getMethod, valueRef));

                if (eventArgs.AdditionalAfterSetStatements != null)
                {
                    try
                    {
                        foreach (CodeStatement s in eventArgs.AdditionalAfterSetStatements)
                        {
                            csc.Add(s);
                        }
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }
            }

            // if additional Get statements were specified by the event subscriber, insert them now
            //
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    property.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException ex)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       ex);
                }
            }

            property.GetStatements.Add(new CodeMethodReturnStatement(getReturnExpression));

            return(property);
        }
コード例 #4
0
        private CodeMemberProperty CreateEntitySetProperty(EntitySet set)
        {
            Debug.Assert(set != null, "Property is Null");

            // trying to get
            //
            // [System.ComponentModel.Browsable(false)]
            // public ObjectQuery<Customer> Customers
            // {
            //      get
            //      {
            //          if ((this._Customers == null))
            //          {
            //              this._Customers = base.CreateQuery<Customer>("[Customers]");
            //          }
            //          return this._Customers;
            //      }
            // }
            CodeMemberProperty codeProperty = new CodeMemberProperty();

            codeProperty.Attributes = MemberAttributes.Final | GetEntitySetPropertyAccessibility(set);
            codeProperty.Name       = set.Name;
            codeProperty.HasGet     = true;
            codeProperty.HasSet     = false;

            // SQLBUDT 598300: property to get query hides a property on base Context?
            if (null != TypeReference.ObjectContextBaseClassType.GetProperty(set.Name))
            {
                codeProperty.Attributes |= MemberAttributes.New;
            }

            AttributeEmitter.AddBrowsableAttribute(codeProperty);
            AttributeEmitter.AddGeneratedCodeAttribute(codeProperty);

            CodeTypeReference genericParameter = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType);

            codeProperty.Type = TypeReference.AdoFrameworkGenericClass("DataServiceQuery", genericParameter);
            string fieldName = Utils.FieldNameFromPropName(set.Name);

            // raise the PropertyGenerated event before proceeding further
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(set, fieldName, codeProperty.Type);

            Generator.RaisePropertyGeneratedEvent(eventArgs);

            if (eventArgs.ReturnType == null || !eventArgs.ReturnType.Equals(codeProperty.Type))
            {
                throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnType(set.Name, Item.Name));
            }

            List <CodeAttributeDeclaration> additionalAttributes = eventArgs.AdditionalAttributes;

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

            // we need to insert user-specified code before other/existing code, including
            // the return statement
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    codeProperty.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            codeProperty.GetStatements.Add(
                new CodeConditionStatement(
                    EmitExpressionEqualsNull(new CodeFieldReferenceExpression(ThisRef, fieldName)),
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, fieldName),
                        new CodeMethodInvokeExpression(
                            new CodeMethodReferenceExpression(
                                new CodeBaseReferenceExpression(),
                                "CreateQuery",
                                new CodeTypeReference[] { genericParameter }
                                ),
                            new CodePrimitiveExpression(set.Name)
                            )
                        )
                    )
                );

            codeProperty.GetStatements.Add(
                new CodeMethodReturnStatement(
                    new CodeFieldReferenceExpression(
                        ThisRef,
                        fieldName
                        )
                    )
                );

            // property summary
            CommentEmitter.EmitSummaryComments(set, codeProperty.Comments);

            return(codeProperty);
        }
コード例 #5
0
        /// <summary>
        /// Emit static factory method which creates an instance of the class and initializes
        /// non-nullable properties (taken as arguments)
        /// </summary>
        /// <param name="typeDecl"></param>
        protected virtual void EmitFactoryMethod(CodeTypeDeclaration typeDecl)
        {
            // build list of non-nullable properties
            ReadOnlyMetadataCollection <EdmProperty> properties = GetProperties();
            List <EdmProperty> parameters = new List <EdmProperty>(properties.Count);

            foreach (EdmProperty property in properties)
            {
                bool include = IncludeFieldInFactoryMethod(property);
                if (include)
                {
                    parameters.Add(property);
                }
            }

            // if there are no parameters, we don't emit anything (1 is for the null element)
            // nor do we emit everything if this is the Ref propertied ctor and the parameter list is the same as the many parametered ctor
            if (parameters.Count < 1)
            {
                return;
            }

            CodeMemberMethod        method  = new CodeMemberMethod();
            CodeTypeReference       typeRef = TypeReference.FromString(Item.Name);
            UniqueIdentifierService uniqueIdentifierService = new UniqueIdentifierService(Generator.IsLanguageCaseSensitive);
            string instanceName = uniqueIdentifierService.AdjustIdentifier(Utils.CamelCase(Item.Name));

            // public static Class CreateClass(...)
            method.Attributes = MemberAttributes.Static | MemberAttributes.Public;
            method.Name       = "Create" + Item.Name;
            if (NavigationPropertyEmitter.IsNameAlreadyAMemberName(Item, method.Name, Generator.LanguageAppropriateStringComparer))
            {
                Generator.AddError(Strings.GeneratedFactoryMethodNameConflict(method.Name, Item.Name),
                                   ModelBuilderErrorCode.GeneratedFactoryMethodNameConflict,
                                   EdmSchemaErrorSeverity.Error);
            }

            method.ReturnType = typeRef;
            AttributeEmitter.AddGeneratedCodeAttribute(method);

            // output method summary comments
            CommentEmitter.EmitSummaryComments(Strings.FactoryMethodSummaryComment(Item.Name), method.Comments);


            // Class class = new Class();
            CodeVariableDeclarationStatement createNewInstance = new CodeVariableDeclarationStatement(
                typeRef, instanceName, new CodeObjectCreateExpression(typeRef));

            method.Statements.Add(createNewInstance);
            CodeVariableReferenceExpression instanceRef = new CodeVariableReferenceExpression(instanceName);

            // iterate over the properties figuring out which need included in the factory method
            foreach (EdmProperty property in parameters)
            {
                // CreateClass( ... , propType propName ...)
                PropertyEmitter   propertyEmitter       = new PropertyEmitter(Generator, property, UsingStandardBaseClass);
                CodeTypeReference propertyTypeReference = propertyEmitter.PropertyType;
                String            parameterName         = uniqueIdentifierService.AdjustIdentifier(Utils.FixParameterName(propertyEmitter.PropertyName, "argument"));
                parameterName = Utils.SetSpecialCaseForFxCopOnPropertyName(parameterName);
                CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression(
                    propertyTypeReference, parameterName);
                CodeArgumentReferenceExpression paramRef = new CodeArgumentReferenceExpression(paramDecl.Name);
                method.Parameters.Add(paramDecl);

                // add comment describing the parameter
                CommentEmitter.EmitParamComments(paramDecl, Strings.FactoryParamCommentGeneral(propertyEmitter.PropertyName), method.Comments);

                CodeExpression newPropertyValue;
                if (TypeSemantics.IsComplexType(propertyEmitter.Item.TypeUsage))
                {
                    List <CodeExpression> complexVerifyParameters = new List <CodeExpression>();
                    complexVerifyParameters.Add(paramRef);
                    complexVerifyParameters.Add(new CodePrimitiveExpression(propertyEmitter.PropertyName));

                    // if (null == param) { throw new ArgumentNullException("PropertyName"); }
                    method.Statements.Add(
                        new CodeConditionStatement(
                            EmitExpressionEqualsNull(paramRef),
                            new CodeThrowExceptionStatement(
                                new CodeObjectCreateExpression(
                                    TypeReference.ForType(typeof(ArgumentNullException)),
                                    new CodePrimitiveExpression(parameterName)
                                    )
                                )
                            )
                        );

                    newPropertyValue = paramRef;
                }
                else
                {
                    newPropertyValue = paramRef;
                }

                // Scalar property:
                //     Property = param;
                // Complex property:
                //     Property = StructuralObject.VerifyComplexObjectIsNotNull(param, propertyName);

                method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(instanceRef, propertyEmitter.PropertyName), newPropertyValue));
            }

            // return class;
            method.Statements.Add(new CodeMethodReturnStatement(instanceRef));

            // actually add the method to the class
            typeDecl.Members.Add(method);
        }
コード例 #6
0
        /// <summary>
        /// This is a control function to delegate the creation of the
        /// setter statments to the correct code path
        /// </summary>
        /// <param name="statements">The collection that the setter statements should be added to.</param>
        /// <param name="additionalSetStatements">Additional statements to emit</param>
        private void EmitPropertySetterBody(CodeStatementCollection statements, List <CodeStatement> additionalSetStatements, List <CodeStatement> additionalAfterSetStatements)
        {
            // Invoke the partial method "On[PropertyName]Changing();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangingPartialMethodName(PropertyName), new CodePropertySetValueReferenceExpression()));

            // insert additional statements following the PropertyChanging event
            if (additionalSetStatements != null && additionalSetStatements.Count > 0)
            {
                try
                {
                    statements.AddRange(additionalSetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            // this.fieldName = value;
            statements.Add(
                new CodeAssignStatement(
                    FieldRef,
                    new CodePropertySetValueReferenceExpression()));

            if (Helper.IsComplexType(Item.TypeUsage.EdmType))
            {
                if (GetCollectionKind(Item.TypeUsage) == CollectionKind.None)
                {
                    // this._complexPropertyInitialized = true;
                    statements.Add(
                        new CodeAssignStatement(
                            ComplexPropertyInitializedFieldRef,
                            new CodePrimitiveExpression(true)));
                }
            }

            // Invoke the partial method "On[PropertyName]Changed();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangedPartialMethodName(PropertyName)));

            // insert additional statements following the PropertyChanged event
            if (additionalAfterSetStatements != null && additionalAfterSetStatements.Count > 0)
            {
                try
                {
                    statements.AddRange(additionalAfterSetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }
        }