Skip to content

Chizaruu/InterfaceExtractor

Repository files navigation

Interface Extractor

A Visual Studio 2022 extension that extracts interfaces from C# classes and records with interactive member selection and customizable options.

Features

Right-click to extract - Works directly from Solution Explorer context menu
Interactive selection - Choose which methods, properties, events, and indexers to include
Preview before saving - Review generated interface before writing to disk
Smart defaults - Auto-suggests interface names with configurable prefix
Batch processing - Handle multiple files at once
Partial class support - Analyzes all parts of partial classes automatically
Record support - Works with both classes and records
Implementation stubs - Generate skeleton implementation classes
Internal members - Optionally include internal members
XML documentation - Preserves XML comments from original members
Generic support - Correctly handles generic methods with constraints
Read-only properties - Properly detects { get; } vs { get; set; }
Overwrite protection - Prompts before replacing existing files
Detailed logging - Progress tracking in Output Window
Customizable options - Configure behavior through Tools → Options
Operator overloads - Optional support for operator methods
Template system - Custom headers, sorting, and grouping

Supported Types

  • Public classes (including partial classes)
  • Public records
  • Internal classes/records (optional)

Supported Members

  • Public methods (including generic methods with constraints)
  • Public properties (with correct accessor detection)
  • Public events
  • Public indexers
  • Public operator overloads (optional - disabled by default)
  • Conversion operators (implicit/explicit)
  • Internal members (optional - disabled by default)

Note: Static members and private members are excluded by design.

Requirements

  • Visual Studio 2022 (Community, Professional, or Enterprise)
  • .NET Framework 4.8

Installation

Option 1: Build from Source

  1. Install the Visual Studio extension development workload via Visual Studio Installer
  2. Clone or download this repository
  3. Open InterfaceExtractor.sln in Visual Studio 2022
  4. Build the solution (Ctrl+Shift+B)
  5. Close all Visual Studio instances
  6. Run the generated .vsix file from bin/Debug/ or bin/Release/
  7. Restart Visual Studio

Option 2: From VSIX Package

  1. Download the .vsix file
  2. Close all Visual Studio instances
  3. Double-click the .vsix file
  4. Follow the installation wizard
  5. Restart Visual Studio

Configuration

Access settings through Tools → Options → Interface Extractor → General

General Settings

Setting Default Description
Interface Folder Name Interfaces Folder for generated interface files
Interface Prefix I Suggested prefix for interface names
Namespace Suffix .Interfaces Appended to original namespace

Behavior Settings

Setting Default Description
Automatically Update Class true Add interface to class declaration
Add Using Directive true Include using for interface namespace
Warn If No 'I' Prefix true Show warning if name lacks 'I' prefix
Include Operator Overloads false Extract operator overloads
Show Preview Before Saving true Display preview dialog before saving
Include Internal Members false Include internal members in extraction
Analyze Partial Classes true Scan all partial files for members

Code Generation Settings

Setting Default Description
Generate Implementation Stubs false Create skeleton implementation class
Implementation Stub Suffix Implementation Suffix for stub class names

Template Settings

Setting Default Description
Include File Header false Add header comment to files
File Header Template See below Template for file headers
Member Separator Lines 1 Blank lines between members (0-3)
Sort Members false Sort alphabetically by type/name
Group By Member Type false Group by Properties, Methods, etc.

Default File Header Template:

// Generated by Interface Extractor on {Date} at {Time}
// File: {FileName}

Placeholders: {FileName}, {Date}, {Time}

Usage

Quick Start

  1. Right-click any .cs file in Solution Explorer
  2. Select Extract Interface...
  3. Review/edit the interface name (defaults based on your prefix setting)
  4. Select members to include
  5. Click OK
  6. Preview the interface (if enabled)
  7. Click Save to create the file

The extension creates an interface file in your configured folder and optionally:

  • Updates the class/record declaration to implement the interface
  • Generates an implementation stub class (if enabled)

Preview Dialog

When Show Preview Before Saving is enabled:

  • Review the complete generated interface code
  • See the exact file path where it will be saved
  • Click Save to proceed or Cancel to abort

Member Selection Dialog

  • ✏️ Edit interface name - Modify the suggested name
  • ☑️ Select/deselect members - Pick which members to include
  • 🔘 Select All / Deselect All - Quick selection buttons
  • 👁️ Preview signatures - See exact interface signatures

View Progress

  1. Open Output Window (View → Output or Ctrl+Alt+O)
  2. Select Interface Extractor from the dropdown
  3. View detailed logs of the extraction process

Examples

Basic Class with Properties and Methods

Input (BookingData.cs):

namespace MyProject.Data
{
    /// <summary>
    /// Manages booking operations
    /// </summary>
    public class BookingData
    {
        /// <summary>
        /// Gets a booking by ID
        /// </summary>
        public async Task<Booking> GetBookingAsync(Guid id) { }
        
        /// <summary>
        /// Gets or sets the booking name
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// Gets the booking date (read-only)
        /// </summary>
        public DateTime BookingDate { get; }
        
        private void InternalMethod() { } // Excluded (private)
    }
}

Output (Interfaces/IBookingData.cs):

namespace MyProject.Data.Interfaces
{
    /// <summary>
    /// Manages booking operations
    /// </summary>
    public interface IBookingData
    {
        /// <summary>
        /// Gets a booking by ID
        /// </summary>
        Task<Booking> GetBookingAsync(Guid id);

        /// <summary>
        /// Gets or sets the booking name
        /// </summary>
        string Name { get; set; }

        /// <summary>
        /// Gets the booking date (read-only)
        /// </summary>
        DateTime BookingDate { get; }
    }
}

Record Types

Input:

public record Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    public DateTime BirthDate { get; init; }
    
    public int Age => (DateTime.Now - BirthDate).Days / 365;
    
    public string GetFullName() => $"{FirstName} {LastName}";
}

Output:

public interface IPerson
{
    string FirstName { get; }
    
    string LastName { get; }
    
    DateTime BirthDate { get; }
    
    int Age { get; }
    
    string GetFullName();
}

Note: init accessors are converted to get for broader compatibility. While init is valid in C# 9+ interface declarations, implementing types must also use init accessors, which may not always be desirable.

Partial Classes

Input - UserService.Part1.cs:

public partial class UserService
{
    public User GetUser(int id) { }
    public void UpdateUser(User user) { }
}

Input - UserService.Part2.cs:

public partial class UserService
{
    public List<User> GetAllUsers() { }
    public void DeleteUser(int id) { }
}

Output (combines both files):

public interface IUserService
{
    User GetUser(int id);
    
    void UpdateUser(User user);
    
    List<User> GetAllUsers();
    
    void DeleteUser(int id);
}

Implementation Stubs

When Generate Implementation Stubs is enabled:

Generated Interface (IBookingData.cs):

public interface IBookingData
{
    Task<Booking> GetBookingAsync(Guid id);
    string Name { get; set; }
}

Generated Stub (BookingDataImplementation.cs):

namespace MyProject.Data
{
    public class BookingDataImplementation : IBookingData
    {
        public Task<Booking> GetBookingAsync(Guid id)
        {
            throw new System.NotImplementedException();
        }
        
        public string Name { get; set; }
    }
}

Internal Members

With Include Internal Members enabled:

Input:

public class DataService
{
    public void PublicMethod() { }
    internal void InternalMethod() { }
    private void PrivateMethod() { } // Still excluded
}

Output:

public interface IDataService
{
    void PublicMethod();
    void InternalMethod(); // Included when option is enabled
}

Troubleshooting

Extension doesn't appear in context menu

  • Verify you're right-clicking .cs files
  • Check Extensions → Manage Extensions to confirm it's installed and enabled
  • Restart Visual Studio

Build errors

  • Ensure Visual Studio SDK is installed
  • Restore NuGet packages (right-click solution → Restore NuGet Packages)
  • Verify target framework is .NET Framework 4.8

Interface not generated correctly

  • Check Output Window (View → Output) and select "Interface Extractor"
  • Ensure the class/record is public (or internal if that option is enabled)
  • Verify the file contains valid C# syntax
  • Check that at least one accessible member exists

Partial class members missing

  • Ensure Analyze Partial Classes is enabled in options
  • Verify all partial files are in the same project
  • Check Output Window for partial file analysis logs

Options not taking effect

  • Close and reopen Visual Studio after changing options
  • Check Tools → Options → Interface Extractor → General
  • Verify settings were saved (they should persist between sessions)

Project Structure

InterfaceExtractor/
├── Commands/
│   └── ExtractInterfaceCommand.cs      # Command handler and orchestration
├── Services/
│   └── InterfaceExtractorService.cs    # Roslyn-based extraction logic
├── Options/
│   └── OptionsPage.cs                  # Settings/configuration page
├── UI/
│   ├── ExtractInterfaceDialog.xaml     # Member selection dialog
│   ├── ExtractInterfaceDialog.xaml.cs
│   ├── PreviewDialog.xaml              # Interface preview dialog
│   ├── PreviewDialog.xaml.cs
│   ├── OverwriteDialog.xaml            # File overwrite confirmation
│   ├── OverwriteDialog.xaml.cs
│   └── MemberSelectionItem.cs          # View model for members
├── Constants.cs                         # Configuration constants
├── InterfaceExtractorPackage.cs        # VS Package entry point
└── InterfaceExtractorPackage.vsct      # Command definitions

Development

Debugging

  1. Open InterfaceExtractor.sln in Visual Studio 2022
  2. Press F5 to launch experimental instance
  3. Open a test project in the experimental instance
  4. Test the extension
  5. Check Output Window → "Interface Extractor" for logs

Key Technologies

  • Roslyn (Microsoft.CodeAnalysis) - C# syntax parsing and analysis
  • Visual Studio SDK - IDE integration
  • WPF - User interface dialogs
  • VSIX - Extension packaging format

Known Limitations

  • Only processes public and optionally internal members (not private/protected)
  • Nested classes: only processes top-level classes/records
  • Operator overloads in interfaces: Only supported in C# 11+. Generated operator signatures in interfaces require manual addition of static abstract keywords, and the containing interface must support static abstract members.

Version History

See CHANGELOG.md for detailed version history and release notes.

License

MIT License

Copyright (c) 2025 Developer Chizaruu

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributing

Contributions welcome! Areas for improvement:

  • Custom template files (.tt or .scriban)
  • Extract interface from multiple classes at once
  • Integration with refactoring tools
  • Performance optimizations
  • Accessibility improvements

Support

For issues or questions:

  1. Check the Output Window (View → Output → "Interface Extractor") for detailed error messages
  2. Review the Troubleshooting section above
  3. Check Tools → Options → Interface Extractor for configuration options
  4. Verify Visual Studio 2022 and .NET Framework 4.8 compatibility
  5. Create an issue with:
    • Visual Studio version
    • Extension version
    • Steps to reproduce
    • Output Window logs
    • Sample code (if applicable)
    • Current option settings

Made with ❤️ for Visual Studio developers

Contributors 3

  •  
  •  
  •  

Languages