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; }
public bool ImplementsINotifyPropertyChanged() { return(ModelClass != null ? ModelClass.DoesImplementINotifyPropertyChanged() : NestedClass.DoesImplementINotifyPropertyChanged()); }
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); }
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; }