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; }
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; }