5f42d8c9b2
Co-authored-by: omegaleo <5655201+omegaleo@users.noreply.github.com>
173 lines
4.8 KiB
Markdown
173 lines
4.8 KiB
Markdown
# Why Rider Shows Documentation Attribute Instead of XML Documentation
|
|
|
|
## The Problem
|
|
|
|
When working in the HelperLib repository, hovering over methods in Rider shows:
|
|
|
|
```csharp
|
|
[Documentation("TryGetValue", "Tries to get the value...", null, "")]
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
```
|
|
|
|
Instead of rich IntelliSense documentation.
|
|
|
|
## Root Cause: Source Code Takes Priority
|
|
|
|
### How IDEs Resolve Documentation
|
|
|
|
IDEs like Rider, Visual Studio, and VS Code follow this priority order:
|
|
|
|
1. **Triple-slash comments (`///`) in source code** ← HIGHEST PRIORITY
|
|
2. XML documentation files (`.xml`)
|
|
3. Decompiled/reflected information
|
|
4. Raw signature
|
|
|
|
### What's Happening in HelperLib
|
|
|
|
Current state:
|
|
```csharp
|
|
[Documentation("TryGetValue", "Tries to get the value...")]
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
{
|
|
// No /// comments here!
|
|
}
|
|
```
|
|
|
|
**The test project uses `<ProjectReference>`:**
|
|
- Rider can access the source code directly
|
|
- No `///` comments exist in source
|
|
- Rider shows the raw source code (including the attribute)
|
|
- XML file is ignored because source is available
|
|
|
|
## The Solution: Add Triple-Slash Comments
|
|
|
|
### Option 1: Minimal Comments (Recommended)
|
|
|
|
Add simple `/// <summary>` that references the documentation:
|
|
|
|
```csharp
|
|
[Documentation("TryGetValue", "Tries to get the value from the NeoDictionary for the given key.")]
|
|
/// <summary>
|
|
/// Tries to get the value from the NeoDictionary for the given key.
|
|
/// </summary>
|
|
public bool TryGetValue(TKey key, out TValue value)
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Rider shows documentation immediately
|
|
- ✅ Works for developers with source access
|
|
- ✅ XML generator can still augment with additional info
|
|
- ✅ Standard .NET practice
|
|
|
|
### Option 2: Generated Comments (Advanced)
|
|
|
|
Create a Source Generator that reads `DocumentationAttribute` and generates `/// <summary>` comments automatically.
|
|
|
|
**Benefits:**
|
|
- ✅ Single source of truth (the attribute)
|
|
- ✅ No duplication
|
|
|
|
**Drawbacks:**
|
|
- ❌ More complex
|
|
- ❌ Requires Source Generator infrastructure
|
|
- ❌ Comments generated at compile-time (not visible in source)
|
|
|
|
### Option 3: Accept Current Behavior
|
|
|
|
Keep as-is and document that developers see attributes, consumers see XML.
|
|
|
|
**Benefits:**
|
|
- ✅ No code changes needed
|
|
- ✅ XML documentation works perfectly for NuGet consumers
|
|
|
|
**Drawbacks:**
|
|
- ❌ Poor developer experience in IDE
|
|
- ❌ Makes development harder
|
|
|
|
## Why This Matters
|
|
|
|
### For Library Developers (Us)
|
|
|
|
Working on HelperLib with ProjectReference:
|
|
- ❌ **Without `///`:** See raw attributes, no IntelliSense
|
|
- ✅ **With `///`:** See rich documentation in IDE
|
|
|
|
### For Library Consumers
|
|
|
|
Installing HelperLib NuGet package:
|
|
- ✅ Only have DLL + XML
|
|
- ✅ Always see rich documentation
|
|
- ✅ Not affected by source code
|
|
|
|
## Recommendation
|
|
|
|
**Add `/// <summary>` comments to all public APIs.**
|
|
|
|
This is standard practice in .NET libraries:
|
|
- Microsoft does this (see .NET source code)
|
|
- Popular libraries do this (Newtonsoft.Json, etc.)
|
|
- Provides best developer experience
|
|
|
|
The DocumentationAttribute can still provide additional metadata:
|
|
- Code examples
|
|
- Extended remarks
|
|
- Structured argument descriptions
|
|
|
|
The XmlDocGenerator augments the XML with this additional content.
|
|
|
|
## Implementation Plan
|
|
|
|
1. Add `/// <summary>` to all public types and members
|
|
2. Keep DocumentationAttribute for extended metadata
|
|
3. XmlDocGenerator augments XML with attribute data
|
|
4. Best of both worlds:
|
|
- Developers see documentation in IDE
|
|
- XML files have rich content from attributes
|
|
- Consumers get full documentation
|
|
|
|
## Example
|
|
|
|
**Before:**
|
|
```csharp
|
|
[Documentation("BenchmarkUtility", "Utility class for benchmarking code execution time.")]
|
|
public class BenchmarkUtility
|
|
{
|
|
[Documentation("Start", "Starts or restarts the stopwatch for the given key.")]
|
|
public static void Start(string key)
|
|
```
|
|
|
|
**After:**
|
|
```csharp
|
|
[Documentation("BenchmarkUtility", "Utility class for benchmarking code execution time.", null, @"```csharp
|
|
BenchmarkUtility.Start(""MyBenchmark"");
|
|
// Code to benchmark
|
|
BenchmarkUtility.Stop(""MyBenchmark"");
|
|
```")]
|
|
/// <summary>
|
|
/// Utility class for benchmarking code execution time.
|
|
/// </summary>
|
|
public class BenchmarkUtility
|
|
{
|
|
[Documentation("Start", "Starts or restarts the stopwatch for the given key.")]
|
|
/// <summary>
|
|
/// Starts or restarts the stopwatch for the given key.
|
|
/// </summary>
|
|
/// <param name="key">The benchmark identifier</param>
|
|
public static void Start(string key)
|
|
```
|
|
|
|
Result:
|
|
- ✅ Rider shows documentation immediately
|
|
- ✅ XML file has base documentation
|
|
- ✅ XmlDocGenerator adds code examples from attribute
|
|
- ✅ Perfect IDE experience for everyone
|
|
|
|
## Automated Solution
|
|
|
|
Could create a tool or analyzer that:
|
|
1. Reads DocumentationAttribute
|
|
2. Warns if no `/// <summary>` exists
|
|
3. Suggests adding the summary from the attribute
|
|
|
|
This enforces the pattern and maintains single source of truth.
|