/// <summary> /// Generates code representing a set of Sitecore templates /// </summary> private void GenerateTemplateCode(CodeCompileUnit concreteUnit, CodeCompileUnit interfaceUnit) { CodeNamespace interfaceNamespace = interfaceUnit.CreateNamespace(Parameters.InterfaceNamespace); var templatesToGenerate = new List<TemplateGenerationInfo>(Templates); // as interface generation can modify the Templates collection, we need to make an immutable copy of the collection items before we iterate over it foreach (var template in templatesToGenerate) { // setup concrete model object CodeNamespace templateNamespace = GetTemplateNamespace(concreteUnit, template.Template.ID, Parameters.ItemNamespace); CodeTypeDeclaration concrete = templateNamespace.CreateType(MemberAttributes.Public, template.TypeName.AsIdentifier()); concrete.IsClass = true; concrete.IsPartial = true; concrete.BaseTypes.Add(new CodeTypeReference(Parameters.ItemBaseClass, CodeTypeReferenceOptions.GlobalReference)); // add the constructor (validates item template) concrete.Members.AddRange(CreateItemConstructors()); AddGeneratedCodeAttributeToType(concrete); AddTemplateIdPropertiesToEntity(concrete, template.Template); // adds static and dynamic template ID property AddCommentsToItem(concrete, template.Template); // adds XML comments based on Sitecore Help fields HashSet<string> fieldKeys = GetBaseFieldSet(); fieldKeys.Add(concrete.Name); // member names cannot be the same as their enclosing type so we add the type name to the fields collection foreach (var baseTemplate in template.AllNonstandardBaseTemplates) // similarly names can't be the same as any of their base templates' names (this would cause an incompletely implemented interface) fieldKeys.Add(baseTemplate.Template.Name.AsIdentifier()); // NOTE: you could break this if you have a base template called Foo and a field called Foo that IS NOT on the Foo template (but why would you have that?) // generate item properties foreach (var field in template.Template.Fields) { if (_templateInputProvider.IsFieldIncluded(field)) // query the template input provider and make sure we generate { string propertyName = field.Name.AsNovelIdentifier(fieldKeys); bool propertyAdded = CreateItemProperty(propertyName, field, concrete.Members); if (propertyAdded) { // record usage of the property name fieldKeys.Add(propertyName); } } } // generates interfaces to represent the Sitecore template inheritance hierarchy string baseInterface = GenerateInheritedInterfaces(template.Template, interfaceUnit, interfaceNamespace); if (!string.IsNullOrEmpty(baseInterface)) concrete.BaseTypes.Add(new CodeTypeReference(baseInterface, CodeTypeReferenceOptions.GlobalReference)); // implement the base type interface // create initializer class CreateInitializer(templateNamespace, concrete, template.Template.ID); } }