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;
        }
Esempio n. 2
0
 public bool ImplementsINotifyPropertyChanging()
 {
     return(ModelClass != null
                 ? ModelClass.DoesImplementINotifyPropertyChanging()
                 : NestedClass.DoesImplementINotifyPropertyChanging());
 }
        private CodeTypeDeclaration GenerateClass(ModelClass cls, CodeNamespace nameSpace, TemplateMemberGenerator templateMemberGenerator)
        {
            if (cls == null)
                throw new ArgumentNullException("cls", "Class not supplied");
            if (nameSpace == null)
                throw new ArgumentNullException("nameSpace", "Namespace not supplied");
            if (String.IsNullOrEmpty(cls.Name))
                throw new ArgumentException("Class name cannot be blank", "cls");

            CodeTypeDeclaration classDeclaration = GetClassDeclaration(cls, nameSpace);

            GenerateCommonPrimaryKey(cls, classDeclaration);

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

            // Properties and Fields
            foreach (ModelProperty property in cls.Properties)
            {
                PropertyData propertyData = new PropertyData(property);

                if (property.KeyType != KeyType.CompositeKey)
                {
                    AddMemberField(classDeclaration, propertyData);

                    if (property.DebuggerDisplay)
                        classDeclaration.CustomAttributes.Add(propertyData.GetDebuggerDisplayAttribute());
                    if (property.DefaultMember)
                        classDeclaration.CustomAttributes.Add(propertyData.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(), cls.DoesImplementINotifyPropertyChanging()));
            }

            //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, relationship);
            }

            // TODO: Other relation types (any etc)

            GenerateDerivedClass(cls, nameSpace);

            templateMemberGenerator.AddTemplateMembers(cls, classDeclaration);

            return classDeclaration;
        }