{"id":13629660,"url":"https://github.com/StefH/ProxyInterfaceSourceGenerator","last_synced_at":"2025-04-17T09:35:30.594Z","repository":{"id":40419868,"uuid":"388820696","full_name":"StefH/ProxyInterfaceSourceGenerator","owner":"StefH","description":"This project uses Source Generation to generate an interface and a Proxy class for classes. This makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use Dependency Injection.","archived":false,"fork":false,"pushed_at":"2024-10-07T18:33:17.000Z","size":315,"stargazers_count":38,"open_issues_count":5,"forks_count":5,"subscribers_count":9,"default_branch":"main","last_synced_at":"2024-10-29T18:44:39.610Z","etag":null,"topics":["code-generation"],"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/StefH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"publiccode":null,"codemeta":null},"funding":{"github":["StefH"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":"https://www.paypal.me/stefheyenrath"}},"created_at":"2021-07-23T14:02:27.000Z","updated_at":"2024-10-05T08:50:04.000Z","dependencies_parsed_at":"2024-11-06T03:34:16.215Z","dependency_job_id":"c321a779-ba0a-48d8-80f1-aed520d47127","html_url":"https://github.com/StefH/ProxyInterfaceSourceGenerator","commit_stats":{"total_commits":135,"total_committers":3,"mean_commits":45.0,"dds":0.4,"last_synced_commit":"ae53932e6b976f92fa9c747322ffd3e305e31c7f"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefH%2FProxyInterfaceSourceGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefH%2FProxyInterfaceSourceGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefH%2FProxyInterfaceSourceGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefH%2FProxyInterfaceSourceGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StefH","download_url":"https://codeload.github.com/StefH/ProxyInterfaceSourceGenerator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223751344,"owners_count":17196618,"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":["code-generation"],"created_at":"2024-08-01T22:01:15.931Z","updated_at":"2025-04-17T09:35:30.584Z","avatar_url":"https://github.com/StefH.png","language":"C#","readme":"# ProxyInterfaceGenerator\r\nThis project uses Source Generation to generate an interface and a Proxy class for classes.\r\nThis makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use DI.\r\n\r\nIt supports:\r\n- properties\r\n- methods\r\n- events\r\n- implicit and explicit operators\r\n\r\n## NuGet\r\n[![NuGet Badge](https://img.shields.io/nuget/v/ProxyInterfaceGenerator)](https://www.nuget.org/packages/ProxyInterfaceGenerator)\r\n\r\n## Usage\r\n### Given: an external existing class which does not implement an interface\r\n``` c#\r\npublic sealed class Person\r\n{\r\n    public string Name { get; set; }\r\n\r\n    public string HelloWorld(string name)\r\n    {\r\n        return $\"Hello {name} !\";\r\n    }\r\n}\r\n```\r\n\r\n### Create a partial interface\r\n\r\n#### Annotate with `[ProxyInterfaceGenerator.Proxy(typeof(...)]`\r\nAnd annotate this partial interface with `[ProxyInterfaceGenerator.Proxy(typeof(...))]` and with the Type which needs to be wrapped:\r\n\r\n``` c#\r\n[ProxyInterfaceGenerator.Proxy(typeof(Person))]\r\npublic partial interface IPerson\r\n{\r\n}\r\n```\r\n\r\n#### Annotate with `[ProxyInterfaceGenerator.Proxy\u003c...\u003e]`\r\nSince version 0.5.0 it's also possible to use the generic version of the attribute:\r\n``` c#\r\n[ProxyInterfaceGenerator.Proxy\u003cPerson\u003e()]\r\npublic partial interface IPerson\r\n{\r\n}\r\n```\r\n\r\n\r\n#### ProxyBaseClasses\r\nIn case also want to proxy the properties/methods/events from the base class(es), use this:\r\n\r\n``` c#\r\n[ProxyInterfaceGenerator.Proxy(typeof(Person), true)] // 👈 Provide `true` as second parameter.\r\npublic partial interface IPerson\r\n{\r\n}\r\n```\r\n\r\n#### ProxyClassAccessibility\r\nBy default, the generated Proxy class is `public`. If you want to create the Proxy class as `internal`, use the following:\r\n\r\n``` c#\r\n[ProxyInterfaceGenerator.Proxy(typeof(Person), ProxyClassAccessibility.Internal)] // 👈 Provide `ProxyClassAccessibility.Internal` as second parameter.\r\npublic partial interface IPerson\r\n{\r\n}\r\n```\r\n\r\n### When the code is compiled, this source generator creates the following\r\n\r\n#### :one: An additional partial interface\r\nWhich defines the same properties and methods as in the external class.\r\n``` c#\r\npublic partial interface IPerson\r\n{\r\n    string Name { get; set; }\r\n\r\n    string HelloWorld(string name);\r\n}\r\n```\r\n\r\n#### :two: A Proxy class\r\nWhich takes the external class in the constructor and wraps all public properties, events and methods.\r\n\r\n``` c#\r\n// ⭐\r\npublic class PersonProxy : IPerson\r\n{\r\n    public Person _Instance { get; }\r\n\r\n    public PersonProxy(Person instance)\r\n    {\r\n        _Instance = instance;\r\n    }\r\n\r\n    public string Name { get =\u003e _Instance.Name; set =\u003e _Instance.Name = value; }\r\n\r\n    public string HelloWorld(string name)\r\n    {\r\n        string name_ = name;\r\n        var result_19479959 = _Instance.HelloWorld(name_);\r\n        return result_19479959;\r\n    }\r\n}\r\n```\r\n\r\n:star: By default the accessibility from the generated Proxy class is `public`.\r\n\r\n### :three: Use it\r\n``` c#\r\nIPerson p = new PersonProxy(new Person());\r\np.Name = \"test\";\r\np.HelloWorld(\"stef\");\r\n```\r\n\r\n### Extra functionality\r\n\r\n#### Ignore members\r\nYou can ignore members by adding a property to the membersToIgnore string array.\r\n\r\nExample when you want to ignore the `Postcode` property:\r\n\r\n``` c#\r\n[Proxy(typeof(Address), [\"Postcode\"])]\r\npublic partial interface IAddress\r\n{\r\n}\r\n```\r\n\r\nNote that's also possible to use wildcard matching to ignore multiple members at once.\r\n``` c#\r\n[Proxy(typeof(Address), [\"Post*\"])]\r\npublic partial interface IAddress\r\n{\r\n}\r\n```\r\n\r\n# References\r\n- https://route2roslyn.netlify.app/symbols-for-dummies/\r\n","funding_links":["https://github.com/sponsors/StefH","https://www.paypal.me/stefheyenrath"],"categories":["Source Generators","Do not want to test 112 ( old ISourceGenerator )"],"sub_categories":["Testing","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"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStefH%2FProxyInterfaceSourceGenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStefH%2FProxyInterfaceSourceGenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStefH%2FProxyInterfaceSourceGenerator/lists"}