{"id":19553933,"url":"https://github.com/borisdj/cscodegenerator","last_synced_at":"2025-05-16T15:05:49.247Z","repository":{"id":144630200,"uuid":"82320174","full_name":"borisdj/CsCodeGenerator","owner":"borisdj","description":"Easy C# class and code generation, POCO object and Methods creation","archived":false,"fork":false,"pushed_at":"2025-03-17T15:18:16.000Z","size":376,"stargazers_count":86,"open_issues_count":2,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-03T18:11:57.885Z","etag":null,"topics":["class","code","codecreator","codegenerator","generator","poco"],"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/borisdj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2017-02-17T17:14:19.000Z","updated_at":"2025-03-22T16:25:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"c7be551a-4b86-4dd0-8edb-84455766f42f","html_url":"https://github.com/borisdj/CsCodeGenerator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borisdj%2FCsCodeGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borisdj%2FCsCodeGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borisdj%2FCsCodeGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borisdj%2FCsCodeGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/borisdj","download_url":"https://codeload.github.com/borisdj/CsCodeGenerator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248565014,"owners_count":21125414,"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":["class","code","codecreator","codegenerator","generator","poco"],"created_at":"2024-11-11T04:25:19.435Z","updated_at":"2025-04-12T11:52:09.500Z","avatar_url":"https://github.com/borisdj.png","language":"C#","funding_links":["https://www.buymeacoffee.com/boris.dj"],"categories":[],"sub_categories":[],"readme":"## CodeGenerator\nThis is a small .NET library that enables easy C# code generation based on Classes and its elements.  \nIt has ability to create `ClassModels` (POCO object generator) and Methods and write it to .cs files.  \nCan specify their Members (`Constructor`, `Field`, `Property`, `Method`) including `Attributes` and `Parameters`.  \nDefining `namespace` and `using` Directives is supported as well.  \nLibrary can also generate `Enums` and `Interfaces`, and create `NestedClasses` inside parent class.  \n\n**BaseElement** has Config for: `IndentSize, Comment, CommentHasSummaryTag(df:true), AccessModifier, BuiltInDataType, CustomDataType, Name`  \n**Property** more Config: `IsGetOnly, IsAutoImplemented, GetterBody, SetterBody`  \n**CsGenerator** Settings are: `DefaultTabSize`: *4* | `OutputDirectory`: \"*Output*\" |  \n-- List of components --  \n**AccessModifier**: `public, private, protected, internal, protected_internal`  \n**BuiltInDataType**: `void, bool, byte, int, long, decimal, float, double, char, string, object`  \n**CommonDataType**: `DateTime, Guid`  \n**KeyWord**: `this, abstract, partial, static, new, virtual, override, sealed, const, async, readOnly`  \n***IndentType***: `None, Single, Double, Triple, Quadruple`  \n\nFor more complex code with indented segments specific Indent value should be set (prepend in a loop) for all internal lines/elements.  \n\nPackage targets .NET Standard 2.0 so can be used both with .NetFramework and .NetCore / .Net (new unified)  \n\nLogo: \u003cimg src=\"CSCodeGeneratorLogo.png\" height=30\u003e   \n\n[![NuGet](https://img.shields.io/npm/l/express.svg)](https://github.com/borisdj/CsCodeGenerator/blob/master/LICENSE)  \n\n## Installation\nAvailable on [![NuGet](https://img.shields.io/nuget/v/CsCodeGenerator.svg)](https://www.nuget.org/packages/CsCodeGenerator/) latest version.  \nPackage manager console command for installation: *Install-Package CsCodeGenerator*   \n\n## Support\nIf you find this project useful you can mark it by leaving a Github **Star** :star:  \nIf you want help development, you can become a CONTRIBUTOR or you can make a DONATION:  \n[\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png\" alt=\"Buy Me A Coffee\" height=28\u003e](https://www.buymeacoffee.com/boris.dj) _ or _ \n[![Button](https://img.shields.io/badge/donate-Bitcoin-orange.svg?logo=bitcoin):zap:](https://borisdj.net/donation/donate-btc.html)  \nWant to **Contact** for Development \u0026 Consulting: [www.codis.tech](http://www.codis.tech) (*Quality Assurance*)  \n\n## Contributing\nPlease read [CONTRIBUTING](CONTRIBUTING.md) for details on code of conduct, and the process for submitting pull requests.  \nWhen opening issues do write detailed explanation of the problem or feature with reproducible example.  \n\n**Also take a look into others packages:\u003c/br\u003e\nOpen source (MIT or cFOSS) authored [.Net libraries](https://infopedia.io/dot-net-libraries/) (@**Infopedia.io** personal blog post)\n| №  | .Net library             | Description                                              |\n| -  | ------------------------ | -------------------------------------------------------- |\n| 1  | [EFCore.BulkExtensions](https://github.com/borisdj/EFCore.BulkExtensions) | EF Core Bulk CRUD Ops (**Flagship** Lib) |\n| 2  | [EFCore.UtilExtensions](https://github.com/borisdj/EFCore.UtilExtensions) | EF Core Custom Annotations and AuditInfo |\n| 3  | [EFCore.FluentApiToAnnotation](https://github.com/borisdj/EFCore.FluentApiToAnnotation) | Converting FluentApi configuration to Annotations |\n| 4  | [FixedWidthParserWriter](https://github.com/borisdj/FixedWidthParserWriter) | Reading \u0026 Writing fixed-width/flat data files |\n| 5* | [CsCodeGenerator](https://github.com/borisdj/CsCodeGenerator) | C# code generation based on Classes and elements |\n| 6  | [CsCodeExample](https://github.com/borisdj/CsCodeExample) | Examples of C# code in form of a simple tutorial |\n\n\n## GeneratorModel Structure:\n\n**Class Inheritance Hierarchy**\n```csharp\n                                |-* BaseElement\n              ClassModel : -----|\nProperty : -- Field : ----------|\nConstructor : Method : ---------|\n              EnumModel : ------|\n              InterfaceModel : -|\n```\n**Component Composition**\n```csharp\nCsGenerator\n|\n|---Files\n\t|\n\t|---Enums\n\t|\n\t|---Classes\n\t\t|\n\t\t|---Fields\n\t\t|\n\t\t|---Constructors (DefaultConstructor first)\n\t\t|\t|---Attributes\n\t\t|\t|\t|--- Parameters\n\t\t|\t|\n\t\t|\t|---Parameters\n\t\t|\n\t\t|---Properties\n\t\t|\t|---Attributes\n\t\t|\t|\t|--- Parameters\n\t\t|\t|\n\t\t|\t|---Parameters\n\t\t|\n\t\t|---Methods\n\t\t|\t|---Attributes\n\t\t|\t|\t|--- Parameters\n\t\t|\t|\n\t\t|\t|---Parameters\n\t\t|\n\t\t|---NestedClasses (recursively)\n\t\t\t|--- ...\n```\n\n## How to use it \nFollowing is first example of ComplexNumber class and then creating its ClassModel for writing to Complex.cs  \nThere are 2 option to configure it:  \n-one is using Fluent methods (A)  \n-and other with pure classes and properties (B)\n\nClass we want to generate:\n```csharp\nusing System;\nusing System.Model;\n\nnamespace CsCodeGenerator.Tests\n{\n    [Description(\"Some class info\")]\n    public partial class ComplexNumber : SomeBaseClass, NumbericInterface\n    {\n        protected const double PI = 3.14;\n        private string remark;\n\n        public ComplexNumber() { }\n\n        public ComplexNumber(double real, double imaginary = 0)\n        {\n            Real = real;\n            Imaginary = imaginary;\n        }\n\n        public static string DefaultFormat { get; } = \"a + b * i\";\n\n        public double Real { get; set; }\n\n        public double Imaginary { get; set; }\n\n        public virtual string Remark\n        {\n            get { return remark; }\n            set { remark = value; }\n        }\n\n        public double Modul()\n        {\n            return Math.Sqrt(Real * Real + Imaginary * Imaginary);\n        }\n\n        public ComplexNumber Add(ComplexNumber input)\n        {\n            ComplexNumber result = new ComplexNumber();\n            result.Real = Real + input.Real;\n            result.Imaginary = Imaginary + input.Imaginary;\n            return result;\n        }\n\n        /// \u003csummary\u003e\n        // example of 2 KeyWords(new and virtual), usually here would be just virtual\n        /// \u003csummary\u003e\n        public new virtual string ToString()\n        {\n            return $\"({Real:0.00}, {Imaginary:0.00})\";\n        }\n    }\n}\n```\n\nA) Code to do it with Fluent methods - shorter code and more readable syntax. [***With**Element()* such as `WithProperty`].\nFluent calls are composed with BaseElement, when configuring deeper level we need to instanciate with New and call in the scope.  \nTo be able to get subElements returned to main scope (like EFCore FluentAPI setting works) then more extension methods would be needed - one example is commented in source code: `WithPropertyReturn`.\n```csharp\nvar usingDirectives = new List\u003cstring\u003e\n{\n    \"System;\",\n    \"System.ComponentModel;\"\n};\nstring fileNameSpace = \"CsCodeGenerator.Tests\";\nstring complexNumberText = \"ComplexNumber\";\n\n// Class\nvar classModel = new ClassModel();\nvar indent = classModel.Indent;\n\nvar complexNumberClass = (ClassModel)classModel\n    .WithAttribute(new AttributeModel(\"Description\")\n        .WithParameter(@\"\"\"Some class info\"\"\"))\n    .WithKeyWord(KeyWord.Partial)\n    .WithName(complexNumberText)\n    .WithConstructor(new Constructor(complexNumberText) { BracesInNewLine = false })\n    .WithConstructor(new Constructor(complexNumberText)\n        .WithParameter(BuiltInDataType.Double, \"real\", null)\n        .WithParameter(BuiltInDataType.Double, \"imaginary\", \"0\")\n        .WithBodyLine(\"Real = real;\")\n        .WithBodyLine(\"Imaginary = imaginary;\"))\n    .WithField(new Field(BuiltInDataType.Double, \"PI\") { SingleKeyWord = KeyWord.Const, DefaultValue = \"3.14\" })\n    .WithField(new Field(BuiltInDataType.String, \"remark\") { AccessModifier = AccessModifier.Private })\n    .WithProperty(new Property(BuiltInDataType.String, \"DefaultFormat\")\n        { SingleKeyWord = KeyWord.Static, IsGetOnly = true, DefaultValue = @\"\"\"a + b * i\"\"\" })\n    .WithProperty(BuiltInDataType.Double, \"Real\")\n    .WithProperty(BuiltInDataType.Double, \"Imaginary\")\n    .WithProperty(new Property(BuiltInDataType.String, \"Remark\")\n        { SingleKeyWord = KeyWord.Virtual, IsAutoImplemented = false }\n        .WithGetter(\"remark\")\n        .WithSetter(\"remark = value\"))\n    .WithMethod(new Method(BuiltInDataType.Double, \"Modul\")\n        .WithBodyLine(\"return Math.Sqrt(Real * Real + Imaginary * Imaginary);\"))\n    .WithMethod(new Method(complexNumberText, \"Add\")\n        .WithParameter(complexNumberText, \"input\", null)\n        .WithBodyLine(\"ComplexNumber result = new ComplexNumber\")\n        .WithBodyLine(\"{\")\n        .AddIndent()\n            .WithBodyLine(\"Real = Real + input.Real,\")\n            .WithBodyLine(\"Imaginary = Imaginary + input.Imaginary,\")\n        .RemoveIndent()\n        .WithBodyLine(\"};\")\n        .WithBodyLine(\"return result;\"))\n    .WithMethod(new Method(BuiltInDataType.String, \"ToString\") { \n                    KeyWords = [KeyWord.New, KeyWord.Virtual],\n                    Comment = \"example of 2 KeyWords(new and virtual), usually here would be just virtual\" }\n        .WithBodyLine(\"return $\\\"({Real:0.00}, {Imaginary:0.00})\\\";\"));\n\nvar complexNumberFile = new FileModel(complexNumberText);\ncomplexNumberFile.LoadUsingDirectives(usingDirectives);\ncomplexNumberFile.Namespace = fileNameSpace;\ncomplexNumberFile.Classes.Add(complexNumberClass);\n\nvar csGenerator = new CsGenerator();\ncsGenerator.Files.Add(complexNumberFile);\ncsGenerator.CreateFiles();\n```\n\nB) Alternative way without Fluent:\n```csharp\nvar usingDirectives = new List\u003cstring\u003e\n{\n    \"using System;\",\n    \"using System.ComponentModel;\"\n};\nstring fileNameSpace = $\"{Util.Namespace} CsCodeGenerator.Tests\";\nstring complexNumberText = \"ComplexNumber\";\n\nClassModel complexNumberClass = new ClassModel(complexNumberText);\ncomplexNumberClass.SingleKeyWord = KeyWord.Partial; // one way to set single KeyWord\n//complexNumberClass.KeyWords.Add(KeyWord.Partial); // or alternative way\ncomplexNumberClass.BaseClass =  \"SomeBaseClass\";\ncomplexNumberClass.Interfaces.Add(\"NumbericInterface)\";\n\nvar descriptionAttribute = new AttributeModel(\"Description\")\n{\n    SingleParameter = new Parameter(@\"\"\"Some class info\"\"\")\n};\ncomplexNumberClass.AddAttribute(descriptionAttribute);\n\ncomplexNumberClass.DefaultConstructor.IsVisible = true;\n\nConstructor secondConstructor = new Constructor(complexNumberClass.Name);\nsecondConstructor.Parameters.Add(new Parameter(BuiltInDataType.Double, \"real\"));\nsecondConstructor.Parameters.Add(new Parameter(BuiltInDataType.Double, \"imaginary\") { Value =\"0\" });\nsecondConstructor.BodyLines.Add(\"Real = real;\");\nsecondConstructor.BodyLines.Add(\"Imaginary = imaginary;\");\ncomplexNumberClass.Constructors.Add(secondConstructor);\n\nvar fields = new Field[]\n{\n    new Field(BuiltInDataType.Double, \"PI\") { SingleKeyWord = KeyWord.Const, DefaultValue =\"3.14\" },\n    new Field(BuiltInDataType.String, \"remark\") { AccessModifier = AccessModifier.Private },\n}.ToDictionary(a =\u003e a.Name, a =\u003e a);\n\nvar properties = new Property[]\n{\n    new Property(BuiltInDataType.String, \"DefaultFormat\")\n    {\n        SingleKeyWord = KeyWord.Static,\n        IsGetOnly = true,\n        DefaultValue = @\"\"\"a + b * i\"\"\"\n    },\n    new Property(BuiltInDataType.Double, \"Real\"),\n    new Property(BuiltInDataType.Double, \"Imaginary\"),\n    new Property(BuiltInDataType.String, \"Remark\")\n    {\n        SingleKeyWord = KeyWord.Virtual,\n        IsAutoImplemented = false,\n        GetterBody = \"remark\",\n        SetterBody = \"remark = value\"\n\n    },\n}.ToDictionary(a =\u003e a.Name, a =\u003e a);\n\nvar methods = new Method[]\n{\n    new Method(BuiltInDataType.Double, \"Modul\")\n    {\n        BodyLines = new List\u003cstring\u003e { \"return Math.Sqrt(Real * Real + Imaginary * Imaginary);\" }\n    },\n    new Method(complexNumberText, \"Add\")\n    {\n        Parameters = new List\u003cParameter\u003e { new Parameter(\"ComplexNumber\", \"input\", null) },\n        BodyLines = new List\u003cstring\u003e\n        {\n            \"ComplexNumber result = new ComplexNumber();\",\n            \"result.Real = Real + input.Real;\",\n            \"result.Imaginary = Imaginary + input.Imaginary;\",\n            \"return result;\"\n        }\n    },\n    new Method(BuiltInDataType.String, \"ToString\")\n    {\n        Comment = \"example of 2 KeyWords(new and virtual), usually here just virtual\",\n        KeyWords = new List\u003cKeyWord\u003e { KeyWord.New, KeyWord.Virtual },\n        BodyLines = new List\u003cstring\u003e { \"return $\\\"({Real:0.00}, {Imaginary:0.00})\\\";\" }\n    }\n}.ToDictionary(a =\u003e a.Name, a =\u003e a);\n\ncomplexNumberClass.Fields = fields;\ncomplexNumberClass.Properties = properties;\ncomplexNumberClass.Methods = methods;\n\nFileModel complexNumberFile = new FileModel(complexNumberText);\ncomplexNumberFile.LoadUsingDirectives(usingDirectives);\ncomplexNumberFile.Namespace = fileNameSpace;\ncomplexNumberFile.Classes.Add(complexNumberClass.Name, complexNumberClass);\n\nCsGenerator csGenerator = new CsGenerator();\ncsGenerator.Files.Add(complexNumberFile.Name, complexNumberFile);\ncsGenerator.CreateFiles(); //Console.Write(complexNumberFile); \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborisdj%2Fcscodegenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fborisdj%2Fcscodegenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborisdj%2Fcscodegenerator/lists"}