From 2c19eb730eb0f9e7bb6f72e5e10846a0fea4de89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 22:27:29 +0000 Subject: [PATCH] Improve XmlDocGenerator robustness and add documentation Co-authored-by: omegaleo <5655201+omegaleo@users.noreply.github.com> --- OmegaLeo.HelperLib.XmlDocGenerator/Program.cs | 36 +++-- OmegaLeo.HelperLib.XmlDocGenerator/README.md | 139 ++++++++++++++++++ 2 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 OmegaLeo.HelperLib.XmlDocGenerator/README.md diff --git a/OmegaLeo.HelperLib.XmlDocGenerator/Program.cs b/OmegaLeo.HelperLib.XmlDocGenerator/Program.cs index 9d32718..3697cf7 100644 --- a/OmegaLeo.HelperLib.XmlDocGenerator/Program.cs +++ b/OmegaLeo.HelperLib.XmlDocGenerator/Program.cs @@ -277,16 +277,11 @@ static string GetTypeName(Type type) static void AddOrUpdateMember(XElement membersElement, string memberName, object attribute, Type docAttrType) { - // Extract attribute values using reflection - var titleProp = docAttrType.GetField("Title"); - var descProp = docAttrType.GetField("Description"); - var argsProp = docAttrType.GetField("Args"); - var exampleProp = docAttrType.GetField("CodeExample"); - - var title = titleProp?.GetValue(attribute) as string ?? ""; - var description = descProp?.GetValue(attribute) as string ?? ""; - var args = argsProp?.GetValue(attribute) as string[] ?? Array.Empty(); - var codeExample = exampleProp?.GetValue(attribute) as string ?? ""; + // Extract attribute values using reflection - check both fields and properties + var title = GetMemberValue(docAttrType, attribute, "Title") ?? ""; + var description = GetMemberValue(docAttrType, attribute, "Description") ?? ""; + var args = GetMemberValue(docAttrType, attribute, "Args") ?? Array.Empty(); + var codeExample = GetMemberValue(docAttrType, attribute, "CodeExample") ?? ""; // Find or create the member element var existingMember = membersElement.Elements("member") @@ -314,7 +309,7 @@ static void AddOrUpdateMember(XElement membersElement, string memberName, object } // Add parameter descriptions as remarks - if (args != null && args.Length > 0) + if (args.Length > 0) { var remarksContent = new StringBuilder(); remarksContent.AppendLine(); @@ -332,3 +327,22 @@ static void AddOrUpdateMember(XElement membersElement, string memberName, object memberElement.Add(new XElement("example", new XCData(codeExample))); } } + +static T? GetMemberValue(Type type, object instance, string memberName) where T : class +{ + // Try as field first + var field = type.GetField(memberName); + if (field != null) + { + return field.GetValue(instance) as T; + } + + // Try as property + var property = type.GetProperty(memberName); + if (property != null) + { + return property.GetValue(instance) as T; + } + + return null; +} diff --git a/OmegaLeo.HelperLib.XmlDocGenerator/README.md b/OmegaLeo.HelperLib.XmlDocGenerator/README.md new file mode 100644 index 0000000..11871f8 --- /dev/null +++ b/OmegaLeo.HelperLib.XmlDocGenerator/README.md @@ -0,0 +1,139 @@ +# OmegaLeo.HelperLib.XmlDocGenerator + +A tool that automatically generates XML documentation from `DocumentationAttribute` custom attributes, making them visible in IDE tooltips. + +## What Problem Does This Solve? + +The `DocumentationAttribute` is a custom attribute that allows you to document classes, methods, and properties with rich information including descriptions, parameters, and code examples. However, custom attributes don't automatically appear in IDE hover tooltips. + +This tool solves that problem by: +1. Reading the compiled assemblies after build +2. Extracting information from `DocumentationAttribute` instances +3. Generating/augmenting the XML documentation file with this information +4. Making the documentation visible in IDEs like Visual Studio and JetBrains Rider + +## How It Works + +The tool is automatically run as a post-build step in projects that include the MSBuild target. It: + +1. **Loads the assembly** with proper dependency resolution +2. **Finds all types** with `DocumentationAttribute` +3. **Extracts documentation** information (Title, Description, Args, CodeExample) +4. **Generates XML** in the standard .NET XML documentation format: + - `` - from Description + - `` - from Args (parameters) + - `` - from CodeExample + +## Usage + +### In Your Code + +Use the `DocumentationAttribute` as usual: + +```csharp +[Documentation( + "MyMethod", + "This method does something important.", + new string[] { "param1: The first parameter.", "param2: The second parameter." }, + @"```csharp +MyMethod(param1, param2); +```" +)] +public void MyMethod(string param1, int param2) +{ + // Method implementation +} +``` + +### Build Integration + +The tool is automatically integrated into the build process for projects that include the MSBuild target. No manual action is required. + +When you build your project, you'll see a message like: +``` +[DocumentationAttribute] Augmenting XML documentation for YourProject from DocumentationAttribute +``` + +### Viewing in IDE + +Once built, hover over any method, class, or property with a `DocumentationAttribute` in your IDE: + +- **Visual Studio**: Hover tooltip will show the documentation +- **JetBrains Rider**: Quick Documentation (Ctrl+Q / F1) will show the documentation +- **VS Code**: IntelliSense will show the documentation + +## Configuration + +The tool runs automatically after the Build target with these settings: + +```xml + + + $(MSBuildThisFileDirectory)../OmegaLeo.HelperLib.XmlDocGenerator/bin/$(Configuration)/net8.0/OmegaLeo.HelperLib.XmlDocGenerator.dll + $(TargetDir)$(TargetFileName) + $(TargetDir)$(TargetName).xml + + + + +``` + +## Requirements + +- .NET 8.0 SDK (for building the tool) +- Projects must have `GenerateDocumentationFile` enabled (optional but recommended for best results) + +## Troubleshooting + +### Tool not running +- Ensure the XmlDocGenerator project is built first: `dotnet build OmegaLeo.HelperLib.XmlDocGenerator/OmegaLeo.HelperLib.XmlDocGenerator.csproj` +- Check that the path in the MSBuild target is correct relative to your project + +### Documentation not showing in IDE +- Ensure the XML file is generated in the output directory +- For consumed packages, ensure the XML file is included in the package +- Restart your IDE if it doesn't pick up changes + +### Assembly loading errors +- The tool uses `AssemblyLoadContext` to load assemblies and their dependencies +- Dependencies must be present in the same directory as the target assembly + +## Examples + +### Before (Custom Attribute Only) +```csharp +[Documentation("Calculate", "Calculates something", new[] { "x: First number", "y: Second number" })] +public int Calculate(int x, int y) => x + y; +``` + +**IDE shows**: No documentation (custom attributes don't appear in tooltips) + +### After (With XML Doc Generator) +The same code now generates: +```xml + + Calculates something + +Parameters: + - x: First number + - y: Second number + + +``` + +**IDE shows**: Full documentation with description and parameter information! + +## Technical Details + +- **Language**: C# (.NET 8.0) +- **Dependencies**: `System.Reflection.Metadata` +- **XML Format**: Standard .NET XML documentation format +- **Assembly Loading**: Uses `AssemblyLoadContext` for isolated loading +- **Performance**: Runs only during build, no runtime overhead + +## Contributing + +To modify the XML generation logic, see `Program.cs` in the XmlDocGenerator project.