name: dotnet-serena-refactoring description: Symbol-level refactoring with automatic reference updates using Serena MCP metadata: short-description: .NET skill guidance for dotnet-serena-refactoring
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
# Manual refactoring issues:
1. Find all references manually (error-prone)
2. Edit each file individually (tedious)
3. Update imports/namespaces (easy to miss)
4. Verify no breaking changes (time-consuming)
5. Test everything (after the fact)
Serena Advantages
# Symbol-aware benefits:
1. Automatic reference discovery (complete)
2. Single precise edit (efficient)
3. Namespace handling (automatic)
4. Compile-time safety (pre-validated)
5. Integrated verification (built-in)
Core Refactoring Patterns
Pattern 1: Rename Symbol
Scenario: Rename a method
# Step 1: Find all references
serena_find_referencing_symbols: "OrderService/ProcessOrder"
# Step 2: Replace method body (includes signature)
serena_replace_symbol_body: "OrderService/ProcessOrder"
New body:
public async Task ProcessOrderAsync(Order order)
{
// ... implementation
}
# Step 3: References are automatically tracked
# Step 4: Verify all call sites updated
Key Point: References are found symbolically, not textually. No regex needed.
Pattern 2: Extract Method
Scenario: Extract logic into new method
# Step 1: Identify code to extract
Read: "src/Services/OrderService.cs" (lines 45-60)
# Step 2: Find insertion point
serena_get_symbols_overview: "src/Services/OrderService.cs"
# Locate method OrderService/ProcessOrder
# Step 3: Insert new method after existing
serena_insert_after_symbol: "OrderService/ProcessOrder"
New method:
private decimal CalculateDiscount(Order order)
{
// extracted logic
}
# Step 4: Replace original with call
serena_replace_content: "OrderService/ProcessOrder"
Pattern: "// lines 45-60"
Replacement: "CalculateDiscount(order)"
Pattern 3: Move Type to New File
Scenario: Move class to separate file
# Step 1: Get symbol info
serena_find_symbol: "OrderService"
# Step 2: Create new file
Write: src/Services/OrderService.cs
Content: (extracted class)
# Step 3: Remove from original
serena_replace_content: "src/Services/OrderProcessing.cs"
Pattern: "class OrderService.*?^}"
Replacement: ""
# Step 4: Verify namespace imports
serena_get_symbols_overview: "src/Services/OrderService.cs"
Pattern 4: Change Method Signature
Scenario: Add parameter to method
# Step 1: Find references
serena_find_referencing_symbols: "OrderService/CreateOrder"
# Step 2: Update signature
serena_replace_symbol_body: "OrderService/CreateOrder"
New signature:
public async Task<Order> CreateOrderAsync(
OrderRequest request,
CancellationToken cancellationToken = default)
# Step 3: Update all callers
# Each reference location needs parameter added
serena_replace_content: "Caller1/CreateOrder"
Pattern: "CreateOrder(request)"
Replacement: "CreateOrder(request, CancellationToken.None)"
Common Refactoring Scenarios
Scenario 1: Interface Extraction
# Goal: Extract interface from concrete class
# Step 1: Analyze class
serena_get_symbols_overview: "src/Services/OrderService.cs"
# Step 2: Create interface
Write: src/Interfaces/IOrderService.cs
Content: Interface with public methods
# Step 3: Update class to implement interface
serena_replace_content: "OrderService"
Pattern: "class OrderService"
Replacement: "class OrderService : IOrderService"
# Step 4: Find all usages
serena_find_referencing_symbols: "OrderService"
# Step 5: Update to use interface where appropriate
# Manual review: which references should use interface?
Scenario 2: Base Class Creation
# Goal: Extract common code into base class
# Step 1: Find similar classes
serena_find_symbol: "UserService"
serena_find_symbol: "OrderService"
# Step 2: Compare structures
serena_get_symbols_overview: "UserService"
serena_get_symbols_overview: "OrderService"
# Step 3: Create base class
Write: src/Services/BaseService.cs
# Step 4: Update derived classes
serena_replace_content: "UserService"
Pattern: "class UserService"
Replacement: "class UserService : BaseService"
Scenario 3: Namespace Reorganization
# Goal: Move types to new namespace
# Step 1: Find all types in namespace
serena_find_symbol: "MyApp.Services.*"
# Step 2: Update namespace declarations
serena_replace_content: "OrderService"
Pattern: "namespace MyApp.Services"
Replacement: "namespace MyApp.Application.Services"
# Step 3: Update using statements
# Find all files referencing old namespace
serena_find_referencing_symbols: "MyApp.Services"
Safety Guidelines
Always Do These Steps
-
Find references first
serena_find_referencing_symbols: "TargetSymbol" # Review before modifying -
Make backup or use git
Bash: git stash # Or work on branch -
Verify compilable after changes
Bash: dotnet build -
Run tests
Bash: dotnet test
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
Performance Considerations
Large Codebases
# For very large refactors:
1. **Batch operations**
- Group related changes
- Apply in single commit
2. **Incremental approach**
- Refactor one subsystem at a time
- Verify between steps
3. **Use branches**
- Feature branches for major refactors
- Easy rollback if issues
Complex Dependencies
# When dependencies are complex:
1. **Map dependency graph first**
serena_find_referencing_symbols: "TargetType"
# Multiple levels deep
2. **Identify breaking changes**
- Public API surface
- Cross-project dependencies
- External consumers
3. **Plan migration strategy**
- Deprecation periods
- Adapter patterns
- 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:
# Search for string references
Grep: "OrderService"
# Review matches carefully
# May need manual updates
Issue: Compilation Errors After Refactor
Cause: Symbol operations succeeded but broke dependencies
Solution:
# Step 1: Review error messages
Bash: dotnet build 2>&1 | head -20
# Step 2: Fix each error
# May need traditional Edit for complex cases
# Step 3: Re-verify
Bash: dotnet build
Issue: Partial Refactoring Applied
Cause: Network error or process interruption
Solution:
# Check git status
Bash: git status
# Either:
# a) Complete manually with remaining references
# b) Revert and retry
Bash: 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
Rename: serena_replace_symbol_body
Extract: serena_insert_after_symbol + serena_replace_content
Move: Write + serena_replace_content
Signature: serena_replace_symbol_body + update callers
Find refs: serena_find_referencing_symbols
Navigate: serena_find_symbol + serena_get_symbols_overview
Example: Complete Refactoring Session
User: "Extract validation logic from OrderService into Validator class"
Agent:
1. serena_get_symbols_overview: "src/Services/OrderService.cs"
2. Read: identify validation methods (lines 30-45)
3. Write: src/Validators/OrderValidator.cs
4. serena_insert_after_symbol: "OrderService/ProcessOrder"
Insert: call to new validator
5. serena_replace_content: remove old validation
6. Bash: dotnet build
7. Bash: dotnet test
Result: Clean extraction with working code