예제 #1
0
        private CodeTypeDeclaration GetClassDeclaration(ModelClass cls, CodeNamespace nameSpace)
        {
            if (cls == null)
                throw new ArgumentException("Class not supplied.", "cls");
            if (String.IsNullOrEmpty(cls.Name))
                throw new ArgumentException("Class name cannot be blank.", "cls");

            CodeTypeDeclaration classDeclaration = CreateClass(cls.Name);

            if (cls.Model.UseBaseClass)
            {
                bool withValidator = cls.Properties.FindAll(delegate(ModelProperty property)
                {
                    return property.IsValidatorSet();
                }).Count > 0;

                CodeTypeReference type;
                // base class for every modelclass. If left empty then baseclass from model if left empty ...etc
                if (!string.IsNullOrEmpty(cls.BaseClassName))
                    type = new CodeTypeReference(cls.BaseClassName);
                else if (!string.IsNullOrEmpty(cls.Model.BaseClassName))
                    type = new CodeTypeReference(cls.Model.BaseClassName);
                else if (withValidator)
                    type = new CodeTypeReference(Common.DefaultValidationBaseClass);
                else
                    type = new CodeTypeReference(Common.DefaultBaseClass);

                if (cls.IsGeneric())
                    type.TypeArguments.Add(classDeclaration.Name);
                classDeclaration.BaseTypes.Add(type);
            }

            if (cls.DoesImplementINotifyPropertyChanged())
            {
                classDeclaration.BaseTypes.Add(new CodeTypeReference(Common.INotifyPropertyChangedType));
                AddINotifyPropertyChangedRegion(classDeclaration);
            }


            if (!String.IsNullOrEmpty(cls.Description))
                classDeclaration.Comments.AddRange(GetSummaryComment(cls.Description));

            classDeclaration.CustomAttributes.Add(cls.GetActiveRecordAttribute());
            if (cls.Model.UseGeneratedCodeAttribute)
                classDeclaration.CustomAttributes.Add(AttributeHelper.GetGeneratedCodeAttribute());
            // Make a note as "generated" to prevent recursive generation attempts
            CodeGenerationContext.AddClass(cls, classDeclaration);

            nameSpace.Types.Add(classDeclaration);
            return classDeclaration;
        }
예제 #2
0
 public bool ImplementsINotifyPropertyChanged()
 {
     return(ModelClass != null
                 ? ModelClass.DoesImplementINotifyPropertyChanged()
                 : NestedClass.DoesImplementINotifyPropertyChanged());
 }
예제 #3
0
        private CodeTypeDeclaration GenerateClass(ModelClass cls, CodeNamespace nameSpace)
        {
            if (cls == null)
                throw new ArgumentNullException("Class not supplied", "cls");
            if (nameSpace == null)
                throw new ArgumentNullException("Namespace not supplied", "namespace");
            if (String.IsNullOrEmpty(cls.Name))
                throw new ArgumentException("Class name cannot be blank", "cls");

            if (!CodeGenerationContext.IsClassGenerated(cls))
            {
                if (CodeGenerationContext.IsClassWithSameNameGenerated(cls.Name))
                    throw new ArgumentException(
                        "Ambiguous class name. Code for a class with the same name already generated. Please use a different name.",
                        cls.Name);

                CodeTypeDeclaration classDeclaration = GetClassDeclaration(cls, nameSpace);

                List<ModelProperty> compositeKeys = new List<ModelProperty>();

                // Properties and Fields
                foreach (ModelProperty property in cls.Properties)
                {
                    if (property.KeyType != KeyType.CompositeKey)
                    {
                        CodeMemberField memberField = GetMemberField(classDeclaration, property);

                        classDeclaration.Members.Add(memberField);

                        if (property.DebuggerDisplay)
                            classDeclaration.CustomAttributes.Add(property.GetDebuggerDisplayAttribute());
                        if (property.DefaultMember)
                            classDeclaration.CustomAttributes.Add(property.GetDefaultMemberAttribute());
                    }
                    else
                        compositeKeys.Add(property);
                }

                if (compositeKeys.Count > 0)
                {
                    CodeTypeDeclaration compositeClass =
                        GetCompositeClassDeclaration(nameSpace, classDeclaration, compositeKeys, cls.DoesImplementINotifyPropertyChanged());

                    // TODO: All access fields in a composite group assumed to be the same.
                    // We have a model validator for this case but the user may save anyway.
                    // Check if all access fields are the same.
                    CodeMemberField memberField = GetPrivateMemberFieldOfCompositeClass(compositeClass, PropertyAccess.Property);
                    classDeclaration.Members.Add(memberField);

                    classDeclaration.Members.Add(GetActiveRecordMemberCompositeKeyProperty(compositeClass, memberField, cls.DoesImplementINotifyPropertyChanged()));
                }

                //ManyToOne links where this class is the target (1-n)
                ReadOnlyCollection<ManyToOneRelation> manyToOneSources = ManyToOneRelation.GetLinksToSources(cls);
                foreach (ManyToOneRelation relationship in manyToOneSources)
                {
                    GenerateHasManyRelation(classDeclaration, nameSpace, relationship);
                }

                //ManyToOne links where this class is the source (n-1)
                ReadOnlyCollection<ManyToOneRelation> manyToOneTargets = ManyToOneRelation.GetLinksToTargets(cls);
                foreach (ManyToOneRelation relationship in manyToOneTargets)
                {
                    GenerateBelongsToRelation(classDeclaration, nameSpace, relationship);
                }

                //ManyToMany links where this class is the source
                ReadOnlyCollection<ManyToManyRelation> manyToManyTargets = ManyToManyRelation.GetLinksToManyToManyTargets(cls);
                foreach (ManyToManyRelation relationship in manyToManyTargets)
                {
                    GenerateHasAndBelongsToRelationFromTargets(classDeclaration, nameSpace, relationship);
                }

                //ManyToMany links where this class is the target
                ReadOnlyCollection<ManyToManyRelation> manyToManySources = ManyToManyRelation.GetLinksToManyToManySources(cls);
                foreach (ManyToManyRelation relationship in manyToManySources)
                {
                    GenerateHasAndBelongsToRelationFromSources(classDeclaration, nameSpace, relationship);
                }

                //OneToOne link where this class is the source
                OneToOneRelation oneToOneTarget = OneToOneRelation.GetLinkToOneToOneTarget(cls);
                if (oneToOneTarget != null)
                {
                    GenerateOneToOneRelationFromTarget(classDeclaration, nameSpace, oneToOneTarget);
                }

                //OneToOne links where this class is the target
                ReadOnlyCollection<OneToOneRelation> oneToOneSources = OneToOneRelation.GetLinksToOneToOneSources(cls);
                foreach (OneToOneRelation relationship in oneToOneSources)
                {
                    GenerateOneToOneRelationFromSources(classDeclaration, nameSpace, relationship);
                }

                //Nested links
                ReadOnlyCollection<NestedClassReferencesModelClasses> nestingTargets =
                    NestedClassReferencesModelClasses.GetLinksToNestedClasses(cls);
                foreach (NestedClassReferencesModelClasses relationship in nestingTargets)
                {
                    GenerateNestingRelationFromRelationship(classDeclaration, nameSpace, relationship);
                }

                // TODO: Other relation types (any etc)

                return classDeclaration;
            }
            else
                return CodeGenerationContext.GetTypeDeclaration(cls);
        }
예제 #4
0
        private CodeTypeDeclaration GetClassDeclaration(ModelClass cls, CodeNamespace nameSpace)
        {
            if (cls == null)
                throw new ArgumentException("Class not supplied.", "cls");
            if (String.IsNullOrEmpty(cls.Name))
                throw new ArgumentException("Class name cannot be blank.", "cls");

            string className = cls.Name;
            if (cls.Model.GeneratesDoubleDerived)
                className += cls.Model.DoubleDerivedNameSuffix;

            CodeTypeDeclaration classDeclaration = CreateClass(className);

            if (cls.Model.AutomaticAssociations)
                classDeclaration.CreateEmptyPublicConstructor();

            if (cls.Model.GeneratesDoubleDerived)
                classDeclaration.TypeAttributes |= TypeAttributes.Abstract;

            if (cls.ClassParent != null)
            {
                classDeclaration.BaseTypes.Add(new CodeTypeReference(cls.ClassParent.Name));
            }
            else if (cls.Model.UseBaseClass)
            {
                bool withValidator = cls.Properties.FindAll(delegate(ModelProperty property)
                {
                    return property.IsValidatorSet();
                }).Count > 0;

                CodeTypeReference type;
                // base class for every modelclass. If left empty then baseclass from model if left empty ...etc
                if (!string.IsNullOrEmpty(cls.BaseClassName))
                    type = new CodeTypeReference(cls.BaseClassName);
                else if (!string.IsNullOrEmpty(cls.Model.BaseClassName))
                    type = new CodeTypeReference(cls.Model.BaseClassName);
                else if (withValidator)
                    type = new CodeTypeReference(Common.DefaultValidationBaseClass);
                else
                    type = new CodeTypeReference(Common.DefaultBaseClass);

                if (cls.IsGeneric())
                    type.TypeArguments.Add(cls.Name);
                classDeclaration.BaseTypes.Add(type);
            }

            if (cls.DoesImplementINotifyPropertyChanged() && cls.ClassParent == null && !cls.Model.PropertyChangedDefinedInBaseClass)
            {
                classDeclaration.BaseTypes.Add(new CodeTypeReference(Common.INotifyPropertyChangedType));
                AddINotifyPropertyChangedRegion(classDeclaration, cls.Lazy | Context.Model.UseVirtualProperties);
            }
            if (cls.DoesImplementINotifyPropertyChanging() && cls.ClassParent == null && !cls.Model.PropertyChangingDefinedInBaseClass)
            {
                classDeclaration.BaseTypes.Add(new CodeTypeReference(Common.INotifyPropertyChangingType));
                AddINotifyPropertyChangingRegion(classDeclaration, cls.Lazy | Context.Model.UseVirtualProperties);
            }

            if (!String.IsNullOrEmpty(cls.Description))
                classDeclaration.Comments.AddRange(GetSummaryComment(cls.Description));

            if (!cls.Model.GeneratesDoubleDerived)
                cls.AddActiveRecordAttributes(classDeclaration);
            if (cls.Model.UseGeneratedCodeAttribute)
                classDeclaration.CustomAttributes.Add(AttributeHelper.GetGeneratedCodeAttribute());

            nameSpace.Types.Add(classDeclaration);
            return classDeclaration;
        }