/// <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); 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.AsIdentifier()); // 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); } }
public TemplateGenerationMetadata GenerateMetadata() { var timer = new Stopwatch(); timer.Start(); // load the templates we'll be generating into a state storage collection var templateData = CreateTemplateData(); foreach (var template in templateData.Templates) { HashSet <string> fieldKeys = GetBaseFieldSet(); // get fields on base type fieldKeys.Add(template.TypeName); // 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.Template.AllNonstandardBaseTemplates) // similarly names can't be the same as any of their base templates' names (this would cause an incompletely implemented interface) { if (templateData.Contains(baseTemplate.TemplateId)) { fieldKeys.Add(templateData[baseTemplate.TemplateId].TypeName); } else { fieldKeys.Add(baseTemplate.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.Id)) // query the template input provider and make sure the field is included { string propertyName = field.Name.AsNovelIdentifier(fieldKeys); var fieldInfo = new FieldPropertyInfo(field); fieldInfo.FieldPropertyName = propertyName; if (_parameters.EnableContentSearch) { fieldInfo.SearchFieldName = _indexFieldNameMapper.MapToSearchField(field); } fieldInfo.FieldType = _fieldMappingProvider.GetFieldType(field); if (fieldInfo.FieldType == null) { Log.Warn("Synthesis: Field type resolution for " + field.Template.Name + "::" + field.Name + " failed; no mapping found for field type " + field.Type, this); continue; // skip adding the field for generation } // record usage of the property name fieldKeys.Add(propertyName); // add the field to the metadata template.FieldsToGenerate.Add(fieldInfo); } } // generates interfaces to represent the Sitecore template inheritance hierarchy TemplateInfo baseInterface = GenerateInheritedInterfaces(template.Template, templateData); if (baseInterface != null) { template.InterfacesImplemented.Add(baseInterface); } } timer.Stop(); Log.Info($"Synthesis: Generated metadata for {templateData.Templates.Count} concrete templates and {templateData.Interfaces.Count} interface templates in {timer.ElapsedMilliseconds} ms", this); return(templateData); }