dotnet-serena-refactoring
Refactor .NET code safely and efficiently using Serena MCP's symbol-aware operations. Automatic reference updates,
precise targeting, and safe transformations.
Trigger
Use when needing to:
- Rename methods, classes, or properties
- Extract methods or classes
- Move types between files
- Change method signatures
- Update inheritance hierarchies
Why Symbol-Level Refactoring?
Traditional Approach Problems
text
1# Manual refactoring issues:
21. Find all references manually (error-prone)
32. Edit each file individually (tedious)
43. Update imports/namespaces (easy to miss)
54. Verify no breaking changes (time-consuming)
65. Test everything (after the fact)
Serena Advantages
text
1# Symbol-aware benefits:
21. Automatic reference discovery (complete)
32. Single precise edit (efficient)
43. Namespace handling (automatic)
54. Compile-time safety (pre-validated)
65. Integrated verification (built-in)
Core Refactoring Patterns
Pattern 1: Rename Symbol
Scenario: Rename a method
text
1# Step 1: Find all references
2serena_find_referencing_symbols: "OrderService/ProcessOrder"
3
4# Step 2: Replace method body (includes signature)
5serena_replace_symbol_body: "OrderService/ProcessOrder"
6New body:
7 public async Task ProcessOrderAsync(Order order)
8 {
9 // ... implementation
10 }
11
12# Step 3: References are automatically tracked
13# Step 4: Verify all call sites updated
Key Point: References are found symbolically, not textually. No regex needed.
Scenario: Extract logic into new method
text
1# Step 1: Identify code to extract
2Read: "src/Services/OrderService.cs" (lines 45-60)
3
4# Step 2: Find insertion point
5serena_get_symbols_overview: "src/Services/OrderService.cs"
6# Locate method OrderService/ProcessOrder
7
8# Step 3: Insert new method after existing
9serena_insert_after_symbol: "OrderService/ProcessOrder"
10New method:
11 private decimal CalculateDiscount(Order order)
12 {
13 // extracted logic
14 }
15
16# Step 4: Replace original with call
17serena_replace_content: "OrderService/ProcessOrder"
18Pattern: "// lines 45-60"
19Replacement: "CalculateDiscount(order)"
Pattern 3: Move Type to New File
Scenario: Move class to separate file
text
1# Step 1: Get symbol info
2serena_find_symbol: "OrderService"
3
4# Step 2: Create new file
5Write: src/Services/OrderService.cs
6Content: (extracted class)
7
8# Step 3: Remove from original
9serena_replace_content: "src/Services/OrderProcessing.cs"
10Pattern: "class OrderService.*?^}"
11Replacement: ""
12
13# Step 4: Verify namespace imports
14serena_get_symbols_overview: "src/Services/OrderService.cs"
Pattern 4: Change Method Signature
Scenario: Add parameter to method
text
1# Step 1: Find references
2serena_find_referencing_symbols: "OrderService/CreateOrder"
3
4# Step 2: Update signature
5serena_replace_symbol_body: "OrderService/CreateOrder"
6New signature:
7 public async Task<Order> CreateOrderAsync(
8 OrderRequest request,
9 CancellationToken cancellationToken = default)
10
11# Step 3: Update all callers
12# Each reference location needs parameter added
13serena_replace_content: "Caller1/CreateOrder"
14Pattern: "CreateOrder(request)"
15Replacement: "CreateOrder(request, CancellationToken.None)"
Common Refactoring Scenarios
text
1# Goal: Extract interface from concrete class
2
3# Step 1: Analyze class
4serena_get_symbols_overview: "src/Services/OrderService.cs"
5
6# Step 2: Create interface
7Write: src/Interfaces/IOrderService.cs
8Content: Interface with public methods
9
10# Step 3: Update class to implement interface
11serena_replace_content: "OrderService"
12Pattern: "class OrderService"
13Replacement: "class OrderService : IOrderService"
14
15# Step 4: Find all usages
16serena_find_referencing_symbols: "OrderService"
17
18# Step 5: Update to use interface where appropriate
19# Manual review: which references should use interface?
Scenario 2: Base Class Creation
text
1# Goal: Extract common code into base class
2
3# Step 1: Find similar classes
4serena_find_symbol: "UserService"
5serena_find_symbol: "OrderService"
6
7# Step 2: Compare structures
8serena_get_symbols_overview: "UserService"
9serena_get_symbols_overview: "OrderService"
10
11# Step 3: Create base class
12Write: src/Services/BaseService.cs
13
14# Step 4: Update derived classes
15serena_replace_content: "UserService"
16Pattern: "class UserService"
17Replacement: "class UserService : BaseService"
Scenario 3: Namespace Reorganization
text
1# Goal: Move types to new namespace
2
3# Step 1: Find all types in namespace
4serena_find_symbol: "MyApp.Services.*"
5
6# Step 2: Update namespace declarations
7serena_replace_content: "OrderService"
8Pattern: "namespace MyApp.Services"
9Replacement: "namespace MyApp.Application.Services"
10
11# Step 3: Update using statements
12# Find all files referencing old namespace
13serena_find_referencing_symbols: "MyApp.Services"
Safety Guidelines
Always Do These Steps
-
Find references first
text
1serena_find_referencing_symbols: "TargetSymbol"
2# Review before modifying
-
Make backup or use git
text
1Bash: git stash
2# Or work on branch
-
Verify compilable after changes
-
Run tests
Avoid These Mistakes
-
Don't rename without checking references
- May break external consumers
- Could miss string-based references
-
Don't change public API without versioning consideration
- Breaking changes require major version bump
- Consider backward compatibility
-
Don't ignore compile errors
- Serena helps but doesn't guarantee correctness
- Always verify with compiler
Large Codebases
text
1# For very large refactors:
2
31. **Batch operations**
4 - Group related changes
5 - Apply in single commit
6
72. **Incremental approach**
8 - Refactor one subsystem at a time
9 - Verify between steps
10
113. **Use branches**
12 - Feature branches for major refactors
13 - Easy rollback if issues
Complex Dependencies
text
1# When dependencies are complex:
2
31. **Map dependency graph first**
4 serena_find_referencing_symbols: "TargetType"
5 # Multiple levels deep
6
72. **Identify breaking changes**
8 - Public API surface
9 - Cross-project dependencies
10 - External consumers
11
123. **Plan migration strategy**
13 - Deprecation periods
14 - Adapter patterns
15 - Feature flags
Integration with Other Skills
- [skill:dotnet-serena-code-navigation] - Navigate before refactoring
- [skill:dotnet-solid-principles] - Apply during refactoring
- [skill:dotnet-csharp-coding-standards] - Maintain conventions
- [skill:dotnet-testing-strategy] - Verify after refactoring
- [skill:dotnet-version-detection] - Handle framework differences
Troubleshooting
Issue: References Not Found
Cause: Dynamic/runtime references (reflection, DI containers)
Solution:
text
1# Search for string references
2Grep: "OrderService"
3# Review matches carefully
4# May need manual updates
Issue: Compilation Errors After Refactor
Cause: Symbol operations succeeded but broke dependencies
Solution:
text
1# Step 1: Review error messages
2Bash: dotnet build 2>&1 | head -20
3
4# Step 2: Fix each error
5# May need traditional Edit for complex cases
6
7# Step 3: Re-verify
8Bash: dotnet build
Issue: Partial Refactoring Applied
Cause: Network error or process interruption
Solution:
text
1# Check git status
2Bash: git status
3
4# Either:
5# a) Complete manually with remaining references
6# b) Revert and retry
7Bash: git checkout -- .
Best Practices Summary
- Plan before acting - Understand the full scope
- Start small - Practice on private methods first
- Test immediately - Don't wait to verify
- Commit often - Small, focused commits
- Document changes - Update XML docs, comments
- Review impact - Consider downstream consumers
Quick Reference Card
text
1Rename: serena_replace_symbol_body
2Extract: serena_insert_after_symbol + serena_replace_content
3Move: Write + serena_replace_content
4Signature: serena_replace_symbol_body + update callers
5Find refs: serena_find_referencing_symbols
6Navigate: serena_find_symbol + serena_get_symbols_overview
Example: Complete Refactoring Session
text
1User: "Extract validation logic from OrderService into Validator class"
2
3Agent:
41. serena_get_symbols_overview: "src/Services/OrderService.cs"
52. Read: identify validation methods (lines 30-45)
63. Write: src/Validators/OrderValidator.cs
74. serena_insert_after_symbol: "OrderService/ProcessOrder"
8 Insert: call to new validator
95. serena_replace_content: remove old validation
106. Bash: dotnet build
117. Bash: dotnet test
12
13Result: Clean extraction with working code