/// <summary> /// Generates a bare skeleton method implementation class. /// </summary> /// <param name="args">Generation arguments.</param> private static void ServicesEmit(XmlDocument doc, ToolGenerateArgs args) { #region Validations if (doc == null) { throw new ArgumentNullException(nameof(doc)); } #endregion /* * */ XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); manager.AddNamespace("zn", "urn:zinc"); manager.AddNamespace("vs", "http://schemas.microsoft.com/developer/msbuild/2003"); /* * */ foreach (XmlElement service in doc.SelectNodes(" /zn:services/zn:service ", manager)) { string serviceName = service.Attributes["name"].Value; string serviceFile = Path.Combine( Path.GetDirectoryName(args.FileName), serviceName + "Services.svc"); if (File.Exists(serviceFile) == true) { continue; } // <%@ ServiceHost Language="C#" Debug="true" Service="kaercher.Authentication.Endpoint.HandlerServices" CodeBehind="HandlerServices.svc.cs" %> StringBuilder sb = new StringBuilder(); sb.AppendFormat(@"<%@ ServiceHost Language=""C#"" Debug=""true"" Service=""{0}.{1}Services"" CodeBehind=""{1}Services.svc.cs"" %>", args.Namespace, serviceName); sb.AppendLine(); StringBuilder sb2 = new StringBuilder(); sb2.AppendLine("// autogenerated"); File.WriteAllText(serviceFile, sb.ToString(), Encoding.UTF8); File.WriteAllText(serviceFile + ".cs", sb2.ToString(), Encoding.UTF8); } }
/// <summary> /// Executes tool. /// </summary> protected override string Execute(ToolGenerateArgs args) { /* * #1. Apply XSLT */ IGenerator xsltTool = new PtXsltTool(); string outputContent = xsltTool.Generate(args); /* * */ XmlDocument doc = new XmlDocument(); doc.LoadXml(args.Content); /* * #2. For methods, conditionally generate $MethodImpl.cs skeleton file. * For services, conditionally generate all of the .svc files. */ if (doc.DocumentElement.NamespaceURI == "urn:zinc") { if (doc.DocumentElement.LocalName == "method") { MethodAddImpl(doc, args); } if (doc.DocumentElement.LocalName == "services") { ServicesEmit(doc, args); } } /* * */ return(outputContent); }
/// <summary> /// Generates a bare skeleton method implementation class. /// </summary> /// <param name="args">Generation arguments.</param> private static void MethodAddImpl(XmlDocument doc, ToolGenerateArgs args) { #region Validations if (doc == null) { throw new ArgumentNullException(nameof(doc)); } #endregion /* * */ XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); manager.AddNamespace("zn", "urn:zinc"); manager.AddNamespace("vs", "http://schemas.microsoft.com/developer/msbuild/2003"); /* * Already has implementation file? */ string impl = Path.Combine( Path.GetDirectoryName(args.FileName), Path.GetFileNameWithoutExtension(args.FileName) + "Impl.cs"); if (File.Exists(impl) == true) { return; } /* * Is it marked as zn:notImplemented? */ XmlElement notImpl = (XmlElement)doc.SelectSingleNode(" /zn:method/zn:notImplemented ", manager); if (notImpl != null) { return; } /* * Generate Impl.cs */ var xslt = X.LoadXslt("ZnMethod-ToCode.xslt"); /* * */ FileInfo inputFile = new FileInfo(args.FileName); Uri fileUri = new Uri(inputFile.FullName); Uri directoryUri = new Uri(inputFile.DirectoryName); string rawName = inputFile.Name.Substring(0, inputFile.Name.Length - inputFile.Extension.Length); XsltArgumentList xsltArgs = new XsltArgumentList(); xsltArgs.AddParam("ToolVersion", "", Assembly.GetExecutingAssembly().GetName(false).Version.ToString(4)); xsltArgs.AddParam("FileName", "", rawName); xsltArgs.AddParam("FullFileName", "", inputFile.FullName); xsltArgs.AddParam("UriFileName", "", fileUri.AbsoluteUri); xsltArgs.AddParam("UriDirectory", "", directoryUri.AbsoluteUri); xsltArgs.AddParam("Namespace", "", args.Namespace); xsltArgs.AddExtensionObject("urn:eo-util", new XsltExtensionObject()); string implContent = X.ToText(xslt, xsltArgs, doc); if (args.WhatIf == false) { try { File.WriteAllText(impl, implContent, Encoding.UTF8); } catch (Exception ex) { throw new ToolException($"Failed to write skeleton implementation to '{ impl }'.", ex); } } /* * Modify the .csproj */ FileInfo file = new FileInfo(args.FileName); FileInfo[] projs = file.Directory.Parent.GetFiles("*.csproj"); if (projs == null || projs.Length == 0) { throw new ToolException("No .csproj found in parent directory from zn:method."); } if (projs.Length != 1) { throw new ToolException("More than one .csproj found in parent directory from zn:method."); } string csproj = projs[0].FullName; XmlDocument projDoc = new XmlDocument(); projDoc.Load(csproj); /* * * * <Compile Include="OneService\MethodOne.cs"> * <AutoGen>True</AutoGen> * <DesignTime>True</DesignTime> * <DependentUpon>MethodOne.xml</DependentUpon> * </Compile> * <Compile Include="OneService\MethodOneImpl.cs" /> * * */ string find = file.Directory.Name + "\\" + Path.GetFileNameWithoutExtension(file.Name) + ".cs"; string addf = file.Directory.Name + "\\" + Path.GetFileNameWithoutExtension(file.Name) + "Impl.cs"; XmlElement findElem = (XmlElement)projDoc.SelectSingleNode($" /vs:Project//vs:Compile[ @Include = '{ find }' ] ", manager); XmlElement addfElem = (XmlElement)projDoc.SelectSingleNode($" /vs:Project//vs:Compile[ @Include = '{ addf }' ] ", manager); if (findElem != null && addfElem == null) { addfElem = projDoc.CreateElement("Compile", "http://schemas.microsoft.com/developer/msbuild/2003"); var include = projDoc.CreateAttribute("Include"); include.Value = addf; addfElem.Attributes.Append(include); findElem.ParentNode.InsertAfter(addfElem, findElem); if (args.WhatIf == false) { try { projDoc.Save(csproj); } catch (Exception ex) { throw new ToolException("Failed overwriting project file.", ex); } } } }