public string GetFileNamespace(string fileFullPath, ProjectNode node) { if (node == null) { throw new ArgumentNullException("node"); } // Get base namespace from the project var namespce = node.GetProjectProperty("RootNamespace"); if (string.IsNullOrEmpty(namespce)) namespce = Path.GetFileNameWithoutExtension(fileFullPath); ; // If the item is added to a subfolder, the name space should reflect this. // This is done so that class names from 2 files with the same name but different // directories don't conflict. var relativePath = Path.GetDirectoryName(fileFullPath); var projectPath = Path.GetDirectoryName(node.GetMkDocument()); // Our project system only support adding files that are sibling of the project file or that are in subdirectories. if (string.Compare(projectPath, 0, relativePath, 0, projectPath.Length, true, CultureInfo.CurrentCulture) == 0) { relativePath = relativePath.Substring(projectPath.Length); } else { Debug.Fail("Adding an item to the project that is NOT under the project folder."); // We are going to use the full file path for generating the namespace } // Get the list of parts var index = 0; string[] pathParts; pathParts = relativePath.Split(Path.DirectorySeparatorChar); // Use a string builder with default size being the expected size var result = new StringBuilder(namespce, namespce.Length + relativePath.Length + 1); // For each path part while (index < pathParts.Length) { var part = pathParts[index]; ++index; // This could happen if the path had leading/trailing slash, we want to ignore empty pieces if (string.IsNullOrEmpty(part)) continue; // If we reach here, we will be adding something, so add a namespace separator '.' result.Append('.'); // Make sure it starts with a letter if (!char.IsLetter(part, 0)) result.Append('N'); // Filter invalid namespace characters foreach (var c in part) { if (char.IsLetterOrDigit(c)) result.Append(c); } } return result.ToString(); }