using System.Collections.Generic; using System.Text.RegularExpressions; using System.Threading.Tasks; using EnvDTE; using Microsoft.VisualStudio.Shell; using VberAdmin.Models; namespace VberAdmin.Generating { public class Generator { private DTE Dte { get; } public TemplateViewModel ViewModel { get; set; } private IFileCreate Creator { get; set; } public Generator(DTE dte, IFileCreate creator) { ThreadHelper.ThrowIfNotOnUIThread(); Dte = dte; ViewModel = GetViewModel(); Creator = creator; } /// /// 执行生成文件 /// public async Task ExecuteAsync() { await Creator.CreateAsync(ViewModel); } #region 获取模板模型 /// /// 获取模板模型 /// /// private TemplateViewModel GetViewModel() { ThreadHelper.ThrowIfNotOnUIThread(); Document doc = Dte.ActiveDocument; var projectItem = doc.ProjectItem; var project = projectItem.ContainingProject; TemplateViewModel model = new TemplateViewModel { ProjectName = project.Name.Replace(".Core", ""), BaseFolder = doc.Path }; TextSelection sel = (TextSelection)doc.Selection; // ReSharper disable once SuspiciousTypeConversion.Global if (sel.ActivePoint.CodeElement[vsCMElement.vsCMElementClass] is CodeClass codeClass) { model.ClassNamespace = codeClass.Namespace.Name; model.HtmlPageTitle = ConvertDocComment(codeClass.DocComment); model.HtmlModalTitle = model.HtmlPageTitle; model.ClassName = codeClass.Name; foreach (CodeElement element in codeClass.Bases) { string name = element.FullName ?? ""; string typeStr = Regex.Match(name, "(?<=<).*?(?=>)").Value; if (typeStr.Contains("System.Int32")) { model.IdType = "int"; } else if (typeStr.Contains("System.Int64")) { model.IdType = "long"; } else if (typeStr.Contains("System.String")) { model.IdType = "string"; } else if (typeStr.Contains("System.Guid")) { model.IdType = "Guid"; } if (!string.IsNullOrEmpty(model.IdType)) break; } model.Columns = new List(); foreach (CodeElement elem in codeClass.Members) { if (elem.Kind == vsCMElement.vsCMElementProperty) { // ReSharper disable once SuspiciousTypeConversion.Global if (elem is CodeProperty cp) { var attrType = cp.Type.AsString?.ToLower() ?? ""; if (attrType.Contains("string") || attrType.Contains("int") || attrType.Contains("datetime") || attrType.Contains("long") || attrType.Contains("bool") || attrType.Contains("decimal") || attrType.Contains("short") || attrType.Contains("double") || attrType.Contains("float") || attrType.Contains("guid")) { var column = new ColumnViewModel { ColumnName = cp.Name, Comment = ConvertDocComment(cp.DocComment), AttrType = cp.Type.AsString?.Replace("System.", ""), IsGenreated = cp.Name != "CreatorUser" && cp.Name != "LastModifierUser" && cp.Name != "DeleterUser" }; if (cp.Attributes != null) { foreach (CodeElement element in cp.Attributes) { // ReSharper disable once SuspiciousTypeConversion.Global CodeAttribute ca = element as CodeAttribute; if (ca?.Name == "Required") { column.IsRequired = true; } if (ca?.Name == "MaxLength" || ca?.Name == "StringLength") { column.MaxLengthStr = ca.Value; } } } model.Columns.Add(column); } } } //else if (elem.Kind == vsCMElement.vsCMElementVariable) //{ // CodeVariable cv = elem as CodeVariable; // if (cv != null && cv.Name == "ParentPath") // { // } // //} // Debug.WriteLine($"【CodeElement】 :value[{elem.Kind.ToString()}]"); } } return model; } /// /// 获取注释 /// /// /// private string ConvertDocComment(string docComment) { string newComment = docComment.Replace("\r\n\r\n", "").Replace("\r\n\r\n", ""); return newComment; } //private void CodeClass(CodeClass cls) //{ // string name = cls.Name; // string classNamespace = cls.Namespace.Name; // string comment = cls.Comment; // string docComment = cls.DocComment; // string infoLocation = cls.InfoLocation.ToString(); // Debug.WriteLine($"【CodeClass】--[Name:{name}]--[Namespace:{classNamespace}]--[Comment:{comment}]--[DocComment:{docComment}]--[InfoLocation:{infoLocation}]"); //} #endregion 获取模板模型 #region 创建文件 ///// ///// 生成DTO ///// //private void CreateDtos() //{ // ThreadHelper.ThrowIfNotOnUIThread(); // List dtoFiles = new List(); // if (ViewModel.IsCreateDto) // { // if (CreateT4(ViewModel.CreateDtoName)) // dtoFiles.Add(ViewModel.DtoFolder + ViewModel.CreateDtoName); // } // if (ViewModel.IsUpdateDto) // { // if (CreateT4(ViewModel.UpdateDtoName)) // dtoFiles.Add(ViewModel.DtoFolder + ViewModel.UpdateDtoName); // } // if (ViewModel.IsUpdateDto) // { // if (CreateT4(ViewModel.ListDtoName)) // dtoFiles.Add(ViewModel.DtoFolder + ViewModel.ListDtoName); // } // if (dtoFiles.Any()) // AddFilesToProject(ViewModel.ApplicationName, dtoFiles); //} ///// ///// 生成Application ///// //private void CreateApplications() //{ // ThreadHelper.ThrowIfNotOnUIThread(); // List applicationFileList = new List(); // if (ViewModel.IsApplicationService) // { // if (CreateT4(ViewModel.ServiceName, 1)) // applicationFileList.Add(ViewModel.ServiceFolder + ViewModel.ServiceName); // } // if (ViewModel.IsIApplicationService) // { // if (CreateT4(ViewModel.ServiceInterfaceName, 1)) // applicationFileList.Add(ViewModel.ServiceFolder + ViewModel.ServiceInterfaceName); // } // if (applicationFileList.Any()) // AddFilesToProject(ViewModel.ApplicationName, applicationFileList); //} ///// ///// 生成Web ///// //private void CreateWebs() //{ // ThreadHelper.ThrowIfNotOnUIThread(); // List webFileList = new List(); // if (ViewModel.IsController) // { // if (CreateT4(ViewModel.ControllerName, 2)) // webFileList.Add(ViewModel.ControllerFolder + ViewModel.ControllerName); // } // if (ViewModel.IsView) // { // if (CreateT4(ViewModel.ViewsName, 3)) // webFileList.Add(ViewModel.ViewsFolder + ViewModel.ViewsName); // } // if (webFileList.Any()) // AddFilesToProject(ViewModel.WebName, webFileList); //} ///// ///// 运用T4模板生成文件 ///// ///// ///// ///// //private bool CreateT4(string fileName, int fileType = 0) // where T : IT4CodeBase, new() //{ // ThreadHelper.ThrowIfNotOnUIThread(); // T t4 = new T { Model = ViewModel }; // string pageContent = t4.TransformText(); // string path = ViewModel.DtoFolder; // switch (fileType) // { // case 0: // path = ViewModel.DtoFolder; // break; // case 1: // path = ViewModel.ServiceFolder; // break; // case 2: // path = ViewModel.ControllerFolder; // break; // case 3: // path = ViewModel.ViewsFolder; // break; // } // return CreateFile(path, fileName, pageContent); //} ///// ///// 创建文件 ///// ///// ///// ///// //private bool CreateFile(string sourcePath, string fileName, string content) //{ // ThreadHelper.ThrowIfNotOnUIThread(); // string path = Path.GetTempPath(); // Directory.CreateDirectory(path); // string file = Path.Combine(path, fileName); // File.WriteAllText(file, content, Encoding.UTF8); // try // { // if (string.IsNullOrEmpty(sourcePath)) // sourcePath = @"..\..\"; // if (!File.Exists(sourcePath)) // Directory.CreateDirectory(sourcePath); // string sourceUrl = Path.Combine(sourcePath, fileName); // if (ViewModel.IsReplace) // File.Delete(sourceUrl); // if (!File.Exists(sourceUrl)) // { // File.Copy(file, sourceUrl); // Dte.StatusBar.Text = $"VberCode:{fileName}代码已生成。"; // return true; // } // } // finally // { // File.Delete(file); // } // return false; //} ///// ///// 添加文件到项目中 ///// ///// ///// //public void AddFilesToProject(string projectName, List files) //{ // ThreadHelper.ThrowIfNotOnUIThread(); // try // { // if (Dte != null) // { // foreach (EnvDTE.Project item in Dte.Solution.Projects) // { // if (item.Name == projectName) // { // foreach (string file in files) // { // Dte.StatusBar.Text = $"VberCode:添加文件[{file}]..."; // item.ProjectItems.AddFromFile(file); // } // item.Save(); // break; // } // if (item.ProjectItems != null) // { // foreach (ProjectItem childItem in item.ProjectItems) // { // if (childItem.Name == projectName) // { // foreach (string file in files) // { // Dte.StatusBar.Text = $"VberCode:添加文件[{file}]..."; // childItem.SubProject?.ProjectItems?.AddFromFile(file); // } // childItem.SubProject?.Save(); // break; // } // } // } // } // } // } // catch // { // //ignored // //Debug.WriteLine(e); // } //} #endregion 创建文件 } }