NetAutomaticInterface by codecentric AG
Nuget / site data
Details
Info
Name: NetAutomaticInterface
Source Generator to create an Interface from a class definition
Author: codecentric AG
NuGet: https://www.nuget.org/packages/AutomaticInterface/
You can find more details at https://github.com/codecentric/net_automatic_interface
Source : https://github.com/codecentric/net_automatic_interface
Original Readme
Automatic Interface
A C# Source Generator to automatically create Interface from classes.
What does it do?
Not all .NET Interfaces are created equal. Some Interfaces are lovingly handcrafted, e.g. the public interface of your .NET package which is used by your customers. Other interfaces are far from lovingly crafted, they are birthed because you need an interface for testing or for the DI container. They are often implemented only once or twice: The class itself and a mock for testing. They are noise at best and often create lots of friction. Adding a new method / field? You have to edit the interface, too!. Change parameters? Edit the interface. Add documentation? Hopefully you add it to the interface, too!
This Source Generator aims to eliminate this cost by generating an interface from the class, without you needing to do anything. This interface will be generated on each subsequent build, eliminating the the friction.
Example
using AutomaticInterfaceAttribute;
using System;
namespace AutomaticInterfaceExample
{
/// <summary>
/// Class Documentation will be copied
/// </summary>
[GenerateAutomaticInterface] // you need to create an Attribute with exactly this name in your solution. You cannot reference Code from the Analyzer.
class DemoClass: IDemoClass // You Interface will get the Name I+classname, here IDemoclass.
// Generics, including constraints are allowed, too. E.g. MyClass<T> where T: class
{
/// <summary>
/// Property Documentation will be copied
/// </summary>
public string Hello { get; set; } // included, get and set are copied to the interface when public
public string OnlyGet { get; } // included, get and set are copied to the interface when public
/// <summary>
/// Method Documentation will be copied
/// </summary>
public string AMethod(string x, string y) // included
{
return BMethod(x,y);
}
private string BMethod(string x, string y) // ignored because not public
{
return x + y;
}
public string CMethod<T, T1, T2, T3, T4>(string? x, string y) // included
where T : class
where T1 : struct
where T3 : DemoClass
where T4 : IDemoClass
{
return "Ok";
}
public static string StaticProperty => "abc"; // static property, ignored
public static string StaticMethod() // static method, ignored
{
return "static" + DateTime.Now;
}
/// <summary>
/// event Documentation will be copied
/// </summary>
public event EventHandler ShapeChanged; // included
private event EventHandler ShapeChanged2; // ignored because not public
private readonly int[] arr = new int[100];
public int this[int index] // currently ignored
{
get => arr[index];
set => arr[index] = value;
}
}
}
This will create this interface:
#nullable enable
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
using System;
/// <summary>
/// Result of the generator
/// </summary>
namespace AutomaticInterfaceExample
{
/// <summary>
/// Bla bla
/// </summary>
[GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <summary>
/// Property Documentation will be copied
/// </summary>
string Hello { get; set; }
string OnlyGet { get; }
/// <summary>
/// Method Documentation will be copied
/// </summary>
string AMethod(string x, string y);
string CMethod<T, T1, T2, T3, T4>(string? x, string y) where T : class where T1 : struct where T3 : DemoClass where T4 : IDemoClass;
/// <summary>
/// event Documentation will be copied
/// </summary>
event System.EventHandler ShapeChanged;
}
}
#nullable restore
How to use it?
- Install the nuget:
dotnet add package AutomaticInterface
- Create an Attribute with the Name
[GenerateAutomaticInterface]
. You can just copy the minimal code from this Repo (see theAutomaticInterfaceAttribute
project). It's the easiest way to get that attribute because you cannot reference any code from the analyzer package. - Let your class implement the interface, e.g.
SomeClass: ISomeClass
- Build Solution, the Interface should now be available.
Any errors? Ping me at: christiian.sauer@codecentric.de
Troubleshooting
How can I see the Source code?
Newer Visual Studio Versions (2019+) can see the source code directly:
Alternatively, the Source Generator generates a log file - look out for a "logs" folder somewhere in bin/debug/... OR your temp folder /logs. The exact location is also reported on Diagnosticlevel Info.
I have an error
Please create an issue and a minimally reproducible test for the problem.
PRs are welcome! Please make sure that you run CSharpier on the code for formatting.
Contributors
- Thanks to dnf for creating some great extensions. I use them partially in this Generator. Unfortunately due to problems referencing packages I cannot depend on his packages directly.
- skarllot for PRs
- Frederik91 for PRs
- definitelyokay for PRs
Run tests
Should be simply a build and run Tests
Changelog
2.1.1
- Fix bug where multiple automatic interfaces caused issues
- Better support for nullable like Task<string?>, previously only top level generic where considered
2.0.0
- Major rework to Incremental Source generator
- Fixed some outstanding bugs
- Removed logging, b/c not really used
- Increased coverage
1.6.1
- Minor bug fixes
1.5.0
- Add support nullable context
1.4.0
- Add support for overloaded methods.
- Add support for optional parameters in method
void test(string x = null)
should now work.
About
GEnerating interface from class
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- Data.cs
- Person.cs
This is the CSharp Project that references NetAutomaticInterface
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutomaticInterface" Version="2.1.0" OutputItemType="Analyzer" >
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
This is the use of NetAutomaticInterface in Program.cs
// See https://aka.ms/new-console-template for more information
using Class2Interface;
Console.WriteLine("Hello, World!");
IPerson person=new Person();
person.FirstName="Andrei";
person.LastName="Ignat";
Console.WriteLine(person.FullName());
This is the use of NetAutomaticInterface in Data.cs
[AttributeUsage(AttributeTargets.Class)]
public class GenerateAutomaticInterfaceAttribute : Attribute
{
public GenerateAutomaticInterfaceAttribute(string namespaceName = "") { }
}
This is the use of NetAutomaticInterface in Person.cs
namespace Class2Interface;
[GenerateAutomaticInterface("Class2Interface")]
internal class Person:IPerson
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name
{
get
{
return $"{FirstName} {LastName}";
}
}
public string FullName()=>$"{FirstName} {LastName}";
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- Class2Interface.IPerson.cs
//--------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------------------------------
using System.CodeDom.Compiler;
namespace Class2Interface
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface IPerson
{
/// <inheritdoc />
int ID { get; set; }
/// <inheritdoc />
string FirstName { get; set; }
/// <inheritdoc />
string LastName { get; set; }
/// <inheritdoc />
string Name { get; }
/// <inheritdoc />
string FullName();
}
}
Usefull
Download Example (.NET C# )
Share NetAutomaticInterface
https://ignatandrei.github.io/RSCG_Examples/v2/docs/NetAutomaticInterface