Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / Visual Basic

Template Based Code Generator

Rate me:
Please Sign up or sign in to vote.
4.67/5 (33 votes)
20 Nov 2007CPOL13 min read 93.2K   4.1K   116  
A template based, command-line oriented .NET code generator
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;

namespace Arebis.CodeGeneration.VisualStudio
{
	/// <summary>
	/// An IFileWriter implementation that will attempt to add new files
	/// to a Visual Studio project file.
	/// </summary>
	/// <remarks>
	/// The extensions of project files to look for, can be overriden by
	/// setting the "vsprojectextensions" setting to a semi-colon separated list
	/// of file extensions. I.e. ".csproj;.vbproj".
	/// </remarks>
	[System.Diagnostics.DebuggerStepThrough]
	public class ProjectManagerFileWriter : BaseFileWriter
	{
		private List<string> projectExtensions = new List<string>(new String[] {".csproj", ".vbproj"});

		public override IGenerationHost Host
		{
			get { return base.Host; }
			set
			{
				// Set host:
				base.Host = value;

				// Retrieve project extensions from settings (if set):
				string[] extensions = this.Host.Settings.GetValues("vsprojectextensions");
				if (extensions != null)
				{
					this.projectExtensions = new List<string>();
					foreach (string extlist in extensions)
					{
						foreach (string ext in extlist.Split(';'))
						{
							this.projectExtensions.Add(ext);
						}
					}
				}
			}
		}

		public override void WriteFile(string filename, string content)
		{
			// Get file info:
			FileInfo fileinfo = new FileInfo(filename);

			// Add file to project only if new file:
			if (fileinfo.Exists == false) this.AddFileToProject(fileinfo);

			// Write the project item file:
			base.WriteFile(filename, content);
		}

		public virtual void AddFileToProject(FileInfo fileinfo)
		{
			// Find project file:
			FileInfo projectinfo = this.FindProjectFile(fileinfo);
			if (projectinfo == null) return;

			// Decide on elementname to add:
			string elementName;
			switch (fileinfo.Extension.ToLower())
			{
				case ".cs":
					elementName = "Compile";
					break;
				case ".vb":
					elementName = "Compile";
					break;
				default:
					elementName = "Content";
					break;
			}

			// Load project file:
			XmlDocument projdoc = new XmlDocument();
			projdoc.Load(projectinfo.FullName);

			// Search for an ItemGroup in file:
			XmlElement itemGroup = null;
			foreach (XmlElement groupItem in projdoc.DocumentElement.GetElementsByTagName("ItemGroup"))
			{
				itemGroup = groupItem;
				break;
			}

			// If no ItemGroup found, create one:
			if (itemGroup == null)
			{
				itemGroup = projdoc.CreateElement("ItemGroup", projdoc.NamespaceURI);
				projdoc.AppendChild(itemGroup);
			}
			
			// Add file in itemgroup:
			XmlElement item = projdoc.CreateElement(elementName, itemGroup.NamespaceURI);
			XmlAttribute itemattr = projdoc.CreateAttribute("Include");
			itemattr.Value = fileinfo.FullName.Replace(projectinfo.Directory.FullName + "\\", "");
			item.Attributes.Append(itemattr);
			itemGroup.AppendChild(item);

			// Save the projectfile:
			this.Host.Log("Added file \"{0}\" to project \"{1}\".", fileinfo.FullName, projectinfo.FullName);
			this.Host.WriteFile(projectinfo.FullName, projdoc.OuterXml);
		}

		public virtual FileInfo FindProjectFile(FileInfo fileinfo)
		{ 
			// Search for project files in file directory and parent directories:
			FileInfo projectinfo = null;
			DirectoryInfo dir = fileinfo.Directory;
			while (dir != null)
			{
				// Search for a project file in dir:
				if (dir.Exists)
				{
					foreach (string projext in this.projectExtensions)
					{
						foreach (FileInfo proj in dir.GetFiles("*" + projext))
						{
							projectinfo = proj;
							goto found;
						}
					}
				}

				// Move to parent directory:
				dir = dir.Parent;
			}
		found:
			return projectinfo;
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect AREBIS
Belgium Belgium
Senior Software Architect and independent consultant.

Comments and Discussions