Popular searches
//

C# – Creating an interface for a class automatically

3.10.2021 | 3 minutes reading time

The last few years have seen a huge proliferation of interfaces for C# classes. These interfaces are very useful for DI, testing and mocking. But they come at a cost: while extracting an interface is fairly easy, you now have to keep interface and class in sync. Especially in an evolving project, this can quickly become annoying. Change a parameter on the class? Edit the interface, too! Change to class-doc? Edit the interface, too. This is tedious, and smaller things like parameter names and documentation get out of sync quickly.

Luckily, C# Source Generators offer the ability to automatically generate these interfaces for us. I even wrote a post about this topic last year, but the birth of our second child prevented me from finishing my idea. Finally, I was able to complete the code and publish it as a NuGet Package: AutomaticInterface .

AutomaticInterface takes care of creating an interface for a class – it automatically copies all public properties, methods, events and the documentation to the interface. You can use it like a normal interface and every change to your class will be picked up by the interface in the next build.

How to use it

  1. Install the nuget: dotnet add package AutomaticInterface
  2. Create an attribute with the name [GenerateAutomaticInterface]. You can just copy the minimal code from the repo . It’s the easiest way to get that attribute because you cannot reference any code from the analyzer package.
  3. Let your class implement the interface, e.g. SomeClass: ISomeClass
  4. Build the solution, the interface should now be available.

1using AutomaticInterfaceAttribute;
2using System;
3 
4namespace AutomaticInterfaceExample
5{
6    /// <summary>
7    /// Class Documentation will be copied
8    /// </summary>
9    [GenerateAutomaticInterface]  // you need to create an attribute with exactly this name in your solution. You cannot reference code from the analyzer.
10    class DemoClass: IDemoClass // You Interface will get the Name I+classname, here IDemoclass. 
11    // Generics, including constraints are allowed, too. E.g. MyClass<T> where T: class
12    {
13 
14        /// <summary>
15        /// Property Documentation will be copied
16        /// </summary>
17        public string Hello { get; set; }  // included, get and set are copied to the interface when public
18 
19        public string OnlyGet { get; } // included, get and set are copied to the interface when public
20 
21        /// <summary>
22        /// Method Documentation will be copied
23        /// </summary>
24        public string AMethod(string x, string y) // included
25        {
26            return BMethod(x,y);
27        }
28 
29        private string BMethod(string x, string y) // ignored because not public
30        {
31            return x + y;
32        }
33 
34        public static string StaticProperty => "abc"; // static property, ignored
35 
36        public static string StaticMethod()  // static method, ignored
37        {
38            return "static" + DateTime.Now;
39        }
40 
41        /// <summary>
42        /// event Documentation will be copied
43        /// </summary>
44 
45        public event EventHandler ShapeChanged;  // included
46 
47        private event EventHandler ShapeChanged2; // ignored because not public
48 
49        private readonly int[] arr = new int[100];
50 
51        public int this[int index] // currently ignored
52        {
53            get => arr[index];
54            set => arr[index] = value;
55        }
56    }
57}

This will create this interface:

1using System.CodeDom.Compiler;
2using AutomaticInterfaceAttribute;
3using System;
4 
5/// <summary>
6/// Result of the generator
7/// </summary>
8namespace AutomaticInterfaceExample
9{
10    /// <summary>
11    /// Bla bla
12    /// </summary>
13    [GeneratedCode("AutomaticInterface", "")]
14    public partial interface IDemoClass
15    {
16        /// <summary>
17        /// Property Documentation will be copied
18        /// </summary> 
19        string Hello { get; set; }
20 
21        string OnlyGet { get; }
22 
23        /// <summary>
24        /// Method Documentation will be copied
25        /// </summary> 
26        string AMethod(string x, string y);
27 
28        /// <summary>
29        /// event Documentation will be copied
30        /// </summary> 
31        event System.EventHandler ShapeChanged;
32    }
33}

share post

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.