{"id":13629159,"url":"https://github.com/codecentric/net_automatic_interface","last_synced_at":"2025-04-19T21:22:14.936Z","repository":{"id":40656172,"uuid":"293085765","full_name":"codecentric/net_automatic_interface","owner":"codecentric","description":".Net Source Generator for Automatic Interfaces","archived":false,"fork":false,"pushed_at":"2024-03-19T11:55:55.000Z","size":162,"stargazers_count":41,"open_issues_count":6,"forks_count":10,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-03-20T09:57:10.781Z","etag":null,"topics":["csharp-sourcegenerator"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codecentric.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-09-05T13:54:33.000Z","updated_at":"2024-08-11T08:41:25.437Z","dependencies_parsed_at":"2024-01-06T09:54:19.957Z","dependency_job_id":"8f29592f-47dc-4b0d-aaad-056739924bef","html_url":"https://github.com/codecentric/net_automatic_interface","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecentric%2Fnet_automatic_interface","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecentric%2Fnet_automatic_interface/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecentric%2Fnet_automatic_interface/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecentric%2Fnet_automatic_interface/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codecentric","download_url":"https://codeload.github.com/codecentric/net_automatic_interface/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249807776,"owners_count":21328119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp-sourcegenerator"],"created_at":"2024-08-01T22:01:03.510Z","updated_at":"2025-04-19T21:22:14.907Z","avatar_url":"https://github.com/codecentric.png","language":"C#","readme":"# Automatic Interface\n\nA C# Source Generator to automatically create Interfaces from classes.\n\n[![NuGet version (sourcedepend)](https://img.shields.io/nuget/v/AutomaticInterface?color=blue)](https://www.nuget.org/packages/AutomaticInterface/)\n\n## What does it do?\n\nNot 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!\n\nThis Source Generator aims to eliminate this cost by generating an interface from the class, without you needing to do anything.\nThis interface will be generated on each subsequent build, eliminating the friction.\n\n## Example\n\n```c#\nusing AutomaticInterface;\nusing System;\n\nnamespace AutomaticInterfaceExample\n{\n    /// \u003csummary\u003e\n    /// Class Documentation will be copied\n    /// \u003c/summary\u003e\n    [GenerateAutomaticInterface]\n    class DemoClass: IDemoClass // Your interface will get the Name I+classname, here IDemoclass. \n    // Generics, including constraints are allowed, too. E.g. MyClass\u003cT\u003e where T: class\n    {\n        /// \u003csummary\u003e\n        /// Property Documentation will be copied\n        /// \u003c/summary\u003e\n        public string Hello { get; set; } // included, get and set are copied to the interface when public\n\n        public string OnlyGet { get; } // included, get and set are copied to the interface when public\n\n        [IgnoreAutomaticInterface]\n        public string? AnotherGet { get; } // ignored with help of attribute\n\n        /// \u003csummary\u003e\n        /// Method Documentation will be copied\n        /// \u003c/summary\u003e\n        public string AMethod(string x, string y) // included\n        {\n            return BMethod(x, y);\n        }\n\n        private string BMethod(string x, string y) // ignored because not public\n        {\n            return x + y;\n        }\n\n        public string CMethod\u003cT, T1, T2, T3, T4\u003e(string? x, string y) // included\n            where T : class\n            where T1 : struct\n            where T3 : DemoClass\n            where T4 : IDemoClass\n        {\n            return \"Ok\";\n        }\n\n        public Task\u003cstring\u003e ASync(string x, string y)\n        {\n            return Task.FromResult(\"\");\n        }\n\n        public static string StaticProperty =\u003e \"abc\"; // static property, ignored\n\n        public static string StaticMethod() // static method, ignored\n        {\n            return \"static\" + DateTime.Now;\n        }\n\n        /// \u003csummary\u003e\n        /// event Documentation will be copied\n        /// \u003c/summary\u003e\n\n        public event EventHandler ShapeChanged;  // included\n\n        private event EventHandler ShapeChanged2; // ignored because not public\n\n        private readonly int[] arr = new int[100];\n\n        public int this[int index] // currently ignored\n        {\n            get =\u003e arr[index];\n            set =\u003e arr[index] = value;\n        }\n    }\n}\n```\n\nThis will create this interface:\n\n```C#\n#nullable enable\n\n/// \u003csummary\u003e\n/// Result of the generator\n/// \u003c/summary\u003e\nnamespace AutomaticInterfaceExample\n{\n    /// \u003csummary\u003e\n    /// Class documentation will be copied\n    /// \u003c/summary\u003e\n    [global::System.CodeDom.Compiler.GeneratedCode(\"AutomaticInterface\", \"\")]\n    public partial interface IDemoClass\n    {\n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.Hello\" /\u003e\n        string Hello { get; set; }\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.OnlyGet\" /\u003e\n        string OnlyGet { get; }\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.AMethod(string, string)\" /\u003e\n        string AMethod(string x, string y);\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.CMethod{T, T1, T2, T3, T4}(string?, string)\" /\u003e\n        string CMethod\u003cT, T1, T2, T3, T4\u003e(string? x, string y) where T : class where T1 : struct where T3 : global::AutomaticInterfaceExample.DemoClass where T4 : IDemoClass;\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.ASync(string, string)\" /\u003e\n        global::System.Threading.Tasks.Task\u003cstring\u003e ASync(string x, string y);\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.ShapeChanged\" /\u003e\n        event global::System.EventHandler ShapeChanged;\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.ShapeChangedNullable\" /\u003e\n        event global::System.EventHandler? ShapeChangedNullable;\n        \n        /// \u003cinheritdoc cref=\"AutomaticInterfaceExample.DemoClass.ShapeChangedNullable2\" /\u003e\n        event global::System.EventHandler\u003cstring?\u003e ShapeChangedNullable2;\n        \n    }\n}\n#nullable restore\n```\n\n## How to use it?\n\n1. Install the nuget: `dotnet add package AutomaticInterface`.\n2. Add `using AutomaticInterface;` or (Pro-tip) add `global using AutomaticInterface;` to your GlobalUsings.\n3. Tag your class with the `[GenerateAutomaticInterface]` attribute.\n4. The Interface should now be available.\n\nTo validate or use the interface:\n\n1. Let your class implement the interface, e.g. `SomeClass: ISomeClass`\n2. 'Go to definition' to see the generated interface.\n3. Build Solution to compile the interface.\n\nAny errors? Ping me at: christiian.sauer@codecentric.de\n\n## Troubleshooting\n\n### How can I see the Source code?\n\nNewer Visual Studio Versions (2019+) can see the source code directly:\n\n![alt text](sg_example.png \"Example\")\n\nAlternatively, 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.\n\n### I have an error\n\nPlease create an issue and a minimally reproducible test for the problem. \n\nPRs are welcome!\nPlease make sure that you run [CSharpier](https://csharpier.com/) on the code for formatting.\n\n## Contributors\n\n- Thanks to [dnf](https://dominikjeske.github.io/) 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.\n- skarllot for PRs\n- Frederik91 for PRs\n- definitelyokay for PRs\n- roflmuffin for PRs\n- mohummedibrahim  for code and idea\n- simonmckenzie for PRs\n- avtc for PR\n- crwsolutions for PRs\n- FinnAngelo for PR\n\n## Run tests\n\nShould be simply a build and run Tests\nNote that we use [Verify](https://github.com/VerifyTests/Verify) for testing. It's recommended that you use te Verify plugin for your UI.\n\n## Changelog\n\n### 5.1.4\n\n- Emit fully qualified type constraints on generic interfaces\n\n### 5.1.3\n\n- Emit `notnull` type constraints on generic type parameters\n\n### 5.1.2\n\n- Fixing enums in method signatures\n  \n### 5.1.1\n\n- Emit `new()` type constraints on generic type parameters; emit `params` keyword for method parameters. Thanks, @simonmckenzie!\n\n### 5.1.0\n\n- Improves inheritdoc so that developer documentation is properly referenced on the autogenerated interfaces. Thanks, CFlorell!\n\n### 5.0.3\n\n- Query members only once. Small optimization. Thanks, @crwsolutions!\n\n### 5.0.2\n\n- Fully qualify type references; remove usings. Thanks, @simonmckenzie!\n\n### 5.0.1\n\n- Sync DemoClass and actual generated code with README. Thanks, @crwsolutions!\n- Removed manual attribute in TestNuget project. Thanks, @crwsolutions!\n\n### 5.0.0\n\n- 4.0.0 changed how parameters where qualified - this PR changes it to using qualified names everywhere because 4.0.0 broke lots of stuff. Thanks for your contributions! Especially simonmckenzie for the hard work and realbart for bringing it up\n\n### 4.1.0\n\n- Adds ability to use `init` in property setters\n\n### 4.0.0\n\n- Breaking change in how generated code qualifies parameters, e.g. `async Task` should no longer generated as `System.Threading.Task`. I hope this does not break things\n- Completely overhauled test suite - fixed lots of code issues and tightened checks so that errors now surface when testing-\n- Applied fixes for overriding and shadowing also for events. Thanks FinnAngelo!\n\n### 3.0.1\n\n- Maintenance update. Use of `ForAttributeWithMetadataName` to improve performance. Thanks crwsolutions!\n\n### 3.0.0\n\n- You can remove the manually created `GenerateAutomaticInterfaceAttribute`, as it is generated automatically now. Thanks crwsolutions!\n- You can remove the manually created `IgnoreAutomaticInterfaceAttribute`, as it is generated automatically now. Thanks crwsolutions!\n\n### 2.50.\n- Now can ignore class members with [IgnoreAutomaticInterface] attribute. Thanks avtc!\n\n### 2.40.\n- Now prevents duplicates when overriding or shadowing methods (`new void DoSomething()`). Thanks simonmckenzie!\n\n### 2.3.0\n\n- Now supports methods with `ref / in / out` parameters. Thanks mohummedibrahim\n- Handles default values for `true / false` correctly. Thanks simonmckenzie!\n\n### 2.2.1\n\n- Now supports Interfaces containing `new`, previously duplicates entries where created\n- Now supports `ref` parameters\n- Now supports properties with reserved names like `@event`\n\n### 2.1.1\n\n- Fix bug where multiple automatic interfaces caused issues\n- Better support for nullable like Task\u003cstring?\u003e, previously only top level generic where considered\n\n### 2.0.0\n\n- Major rework to Incremental Source generator\n- Fixed some outstanding bugs\n- Removed logging, b/c not really used\n- Increased coverage\n\n### 1.6.1\n\n - Minor bug fixes\n\n### 1.5.0\n\n - Add support nullable context\n\n### 1.4.0\n\n - Add support for overloaded methods.\n - Add support for optional parameters in method `void test(string x = null)` should now work.\n","funding_links":[],"categories":["Do not want to test 112 ( old ISourceGenerator )","Source Generators"],"sub_categories":["1. [ThisAssembly](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category","Other"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodecentric%2Fnet_automatic_interface","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodecentric%2Fnet_automatic_interface","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodecentric%2Fnet_automatic_interface/lists"}