/// <summary> /// Builds a code representation of an <see cref="EntityType"/>. /// </summary> /// <param name="type">The <see cref="EntityType"/> from which to generate code.</param> /// <returns>A <see cref="CodeTypeDeclaration"/> which represents the <see cref="EntityType"/>.</returns> protected virtual CodeTypeDeclaration BuildType(EntityType type) { var codeClass = new CodeTypeDeclaration(type.Name); var defaultConstructor = codeClass.AddConstructor(); ApplyTypeAccessModifier(codeClass, type.Annotations.OfType<TypeAccessModifierAnnotation>().SingleOrDefault()); if (type.Annotations.Any(a => a is SerializableAnnotation)) { codeClass.AddCustomAttribute(typeof(SerializableAttribute)); } if (type.Annotations.Any(a => a is CodeAttributeAnnotation)) { this.AddCodeAttributeAnnotationAsCustomAttribute(codeClass, type.Annotations.OfType<CodeAttributeAnnotation>()); } var genericTypeAnnotation = type.Annotations.OfType<GenericTypeAnnotation>().FirstOrDefault(); if (genericTypeAnnotation != null) { foreach (var typeParameter in genericTypeAnnotation.TypeParameters) { codeClass.TypeParameters.Add(new CodeTypeParameter(typeParameter)); } } if (type.BaseType != null) { var baseType = new CodeTypeReference(type.BaseType.FullName); var baseGenericTypeAnnotation = type.BaseType.Annotations.OfType<GenericTypeAnnotation>().SingleOrDefault(); var genericArgumentsAnnotation = type.Annotations.OfType<GenericArgumentsAnnotation>().SingleOrDefault(); if (genericArgumentsAnnotation != null) { foreach (var typeParameter in baseGenericTypeAnnotation.TypeParameters) { var typeRef = Code.TypeRef(typeParameter); var argument = genericArgumentsAnnotation.GenericArguments.SingleOrDefault(g => g.TypeParameterName == typeParameter); if (argument != null) { typeRef = codeTypeReferenceResolver.Resolve(argument.DataType); } else { if (genericTypeAnnotation == null || !genericTypeAnnotation.TypeParameters.Contains(typeParameter)) { throw new TaupoArgumentException( string.Format( CultureInfo.InvariantCulture, "Entity type {0} cannot derive from entity type {1} because it does not specify a {2} or {3} to fill in {1}'s generic parameter {4}.", type.Name, type.BaseType.Name, typeof(GenericTypeAnnotation).Name, typeof(GenericArgumentsAnnotation).Name, typeParameter)); } } baseType.TypeArguments.Add(typeRef); } } else { if (baseGenericTypeAnnotation != null) { throw new TaupoArgumentException( string.Format( CultureInfo.InvariantCulture, "Entity type {0} cannot derive from entity type {1} because it does not specify a {2} or {3} to fill in {1}'s generic parameter {4}.", type.Name, type.BaseType.Name, typeof(GenericTypeAnnotation).Name, typeof(GenericArgumentsAnnotation).Name, baseGenericTypeAnnotation.TypeParameters.First())); } } codeClass.InheritsFrom(baseType); } if (type.IsAbstract) { codeClass.SetAbstract(); } this.AddProperties(codeClass, type); this.AddNavigationProperties(codeClass, type, defaultConstructor); return codeClass; }