{"id":14529725,"url":"https://github.com/8T4/c4sharp","last_synced_at":"2025-09-02T00:32:23.136Z","repository":{"id":40503678,"uuid":"352080063","full_name":"8T4/c4sharp","owner":"8T4","description":"C4Sharp (C4S) is a .net library for building C4 Model diagrams.","archived":false,"fork":false,"pushed_at":"2024-07-16T16:48:32.000Z","size":28958,"stargazers_count":273,"open_issues_count":3,"forks_count":39,"subscribers_count":12,"default_branch":"main","last_synced_at":"2024-12-25T06:03:20.491Z","etag":null,"topics":["c4-plantuml","c4model","csharp","dotnet","dsl","nuget","plantuml"],"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/8T4.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-27T13:30:00.000Z","updated_at":"2024-12-11T11:56:02.000Z","dependencies_parsed_at":"2023-11-18T02:08:10.164Z","dependency_job_id":"b438ad67-e101-4c2b-904b-158a85be9fc9","html_url":"https://github.com/8T4/c4sharp","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8T4%2Fc4sharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8T4%2Fc4sharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8T4%2Fc4sharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8T4%2Fc4sharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/8T4","download_url":"https://codeload.github.com/8T4/c4sharp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231727115,"owners_count":18417390,"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":["c4-plantuml","c4model","csharp","dotnet","dsl","nuget","plantuml"],"created_at":"2024-09-05T00:01:01.936Z","updated_at":"2025-09-02T00:32:23.120Z","avatar_url":"https://github.com/8T4.png","language":"C#","funding_links":[],"categories":["Documentation Types"],"sub_categories":["Architectural Documentation"],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/8T4/c4sharp/main/docs/images/8t4-c4-brand-2.png\" alt=\"logo\" width='128'\u003e  \n\u003c/p\u003e\n\nC4Sharp (`C4S`) is a .net library for building diagrams as code, based on [C4 Model](https://c4model.com/). It works\nlike a superset of [C4-PlantUML](https://github.com/plantuml-stdlib/C4-PlantUML) through which developers can create,\nshare, and consume [C4 Model diagrams](https://c4model.com/) as code (C#) such as Context, Container, Component and\nDeployment diagrams. The library generates the following diagram types: PNG, SVG, PUML, MERMAID\n\n\u003e[!NOTE]\\\n\u003e The C4 model is an easy-to-learn, developer-friendly approach to software architecture diagramming. Good software architecture diagrams assist with communication inside/outside of software development/product teams, efficient onboarding of new staff, architecture reviews/evaluations, risk identification (e.g. risk-storming), threat modeling (e.g. STRIDE/LINDDUN), etc.  \n\u003e [SIMON BROWN](https://twitter.com/simonbrown)\n\n\u003e[!IMPORTANT]\n\u003e There are benefits to using these tools over the heavier alternatives, including easy version control and the ability to generate the DSLs from many sources. ools in this space that we like include Diagrams, Structurizr DSL, AsciiDoctor Diagram and stables such as WebSequenceDiagrams, PlantUML and the venerable Graphviz. It's also fairly simple to generate your own SVG these days, so don't rule out quickly writing your own tool either. One of our authors wrote a small Ruby script to quickly create SVGs, for example.    \n\u003e [Thoughtworks Technology Radar](https://www.thoughtworks.com/en-br/radar/techniques/diagrams-as-code)\n\n## Getting Started\n\nFirst, you will need the [.NET 8.0+](https://docs.microsoft.com/pt-br/dotnet/standard/net-standard)\nand [Java](https://www.java.com/en/download/) to run C4Sharp. Also, you should install the C4Sharp package in your project.\nThis package is available through [Nuget Packages](https://www.nuget.org/packages/C4Sharp).\n\n| Package | Description                          | Version                                                                                        | Downloads | Maintainability | Status |  \n|---------|--------------------------------------|------------------------------------------------------------------------------------------------| ----- |----- |----- |\n|`C4SHARP`| dotnet library for building diagrams | [![NuGet](https://img.shields.io/nuget/v/C4Sharp.svg)](https://www.nuget.org/packages/C4Sharp) | [![Nuget](https://img.shields.io/nuget/dt/C4Sharp.svg)](https://www.nuget.org/packages/C4Sharp) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/51ea16a0d91548cb9e84bd6ab3e8cb9e)](https://www.codacy.com/gh/8T4/c4sharp/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=8T4/c4sharp\u0026amp;utm_campaign=Badge_Grade) | [![.NET](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml) |\n|`C4SCLI` | cli for compiling C4S projects       | [![NuGet](https://img.shields.io/nuget/v/c4scli.svg)](https://www.nuget.org/packages/c4scli)   | [![Nuget](https://img.shields.io/nuget/dt/c4scli.svg)](https://www.nuget.org/packages/c4scli) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/51ea16a0d91548cb9e84bd6ab3e8cb9e)](https://www.codacy.com/gh/8T4/c4sharp/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=8T4/c4sharp\u0026amp;utm_campaign=Badge_Grade) | [![.NET](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml) |\n\n\n### Create a new diagram from scratch\nTo build a diagram using the C4S library we need to identify the structures and their relationships through a class that inherits properties directly from `DiagramBuilder` (_ContainerDiagram, ComponentDiagram, ContextDiagram, SequenceDiagram, DeploymentDiagram_). See the following example of building a container diagram:\n\n\n```csharp\npublic class ContainerDiagramSample : ContainerDiagram\n{\n    protected override string Title =\u003e \"Container diagram for Internet Banking System v2\";\n\n    protected override IEnumerable\u003cStructure\u003e Structures =\u003e\n    [\n        Person.None | Boundary.External | (\n            alias: \"Customer\",\n            label: \"Personal Banking Customer\",\n            description: \"A customer of the bank, with personal bank accounts.\"\n        ),\n\n        SoftwareSystem.None | (\n            alias: \"BankingSystem\",\n            label: \"Internet Banking System\",\n            description: \"Allows customers to view information about their bank accounts, and make payments.\"\n        ),\n\n        SoftwareSystem.None | Boundary.External | (\n            alias: \"MailSystem\",\n            label: \"E-mail system\",\n            description: \"The internal Microsoft Exchange e-mail system.\"\n        ),\n\n        Bound(\"c1\", \"Internet Banking\",\n            Container.Undefined | (\n                type: WebApplication,\n                alias: \"WebApp\",\n                label: \"WebApp\",\n                technology: \"C#, WebApi\",\n                description: \"Delivers the static content and the Internet banking SPA\"\n            ),\n            Container.None | (\n                type: Spa,\n                alias: \"Spa\",\n                label: \"Spa\",\n                technology: \"JavaScript, Angular\",\n                description: \"Delivers the static content and the Internet banking SPA\"\n            ),\n            Container.None | (\n                type: Mobile,\n                alias: \"MobileApp\",\n                label: \"Mobile App\",\n                technology: \"C#, Xamarin\",\n                description: \"Provides a mobile banking experience\"\n            ),\n            Container.None | (\n                type: Database,\n                alias: \"SqlDatabase\",\n                label: \"SqlDatabase\",\n                technology: \"SQL Database\",\n                description: \"Stores user registration information, hashed auth credentials, access logs, etc.\"\n            ),\n            Container.None | (\n                type: Queue,\n                alias: \"RabbitMQ\",\n                label: \"RabbitMQ\",\n                technology: \"RabbitMQ\",\n                description: \"Stores user registration information, hashed auth credentials, access logs, etc.\"\n            ),\n            Container.None | (\n                type: Api,\n                alias: \"BackendApi\",\n                label: \"BackendApi\",\n                technology: \"Dotnet, Docker Container\",\n                description: \"Provides Internet banking functionality via API.\"\n            )\n        )\n    ];\n\n    protected override IEnumerable\u003cRelationship\u003e Relationships =\u003e new[]\n    {\n        this[\"Customer\"] \u003e this[\"WebApp\"] | (\"Uses\", \"HTTPS\"),\n        this[\"Customer\"] \u003e this[\"Spa\"] | (\"Uses\", \"HTTPS\"),\n        this[\"Customer\"] \u003e this[\"MobileApp\"] | \"Uses\",\n\n        this[\"WebApp\"] \u003e this[\"Spa\"] | \"Delivers\" | Position.Neighbor,\n        this[\"Spa\"] \u003e this[\"BackendApi\"] | (\"Uses\", \"async, JSON/HTTPS\"),\n        this[\"MobileApp\"] \u003e this[\"BackendApi\"] | (\"Uses\", \"async, JSON/HTTPS\"),\n        this[\"SqlDatabase\"] \u003c this[\"BackendApi\"] | (\"Uses\", \"async, JSON/HTTPS\") | Position.Neighbor,\n        this[\"RabbitMQ\"] \u003c this[\"BackendApi\"] | (\"Uses\", \"async, JSON\"),\n\n        this[\"Customer\"] \u003c this[\"MailSystem\"] | \"Sends e-mails to\",\n        this[\"MailSystem\"] \u003c this[\"BackendApi\"] | (\"Sends e-mails using\", \"sync, SMTP\"),\n        this[\"BackendApi\"] \u003e this[\"BankingSystem\"] | (\"Uses\", \"sync/async, XML/HTTPS\") | Position.Neighbor\n    };\n}\n```\n\n### Create a new diagram from existing code\n\nyou can create structures that will be used in the diagram, as in the following example:\n\n```c#\n\npublic static class People\n{\n    public static Person Customer =\u003e new(\n        alias: \"customer\",\n        label: \"Personal Banking Customer\",\n        description: \"A customer of the bank, with personal bank accounts.\",\n        boundary: Boundary.External\n    );\n\n    public static Person InternalCustomer =\u003e new(\n        alias: \"internalcustomer\",\n        label: \"Personal Banking Customer\",\n        description: \"An customer of the bank, with personal bank accounts.\"\n    );\n\n    public static Person Manager =\u003e new(\n        alias: \"manager\",\n        label: \"Manager Banking Customer\",\n        description: \"A manager of the bank, with personal bank accounts.\"\n    );\n}\n\npublic static class Systems\n{\n    public static SoftwareSystem BankingSystem =\u003e new(\n        alias: \"BankingSystem\",\n        label: \"Internet Banking System\",\n        description: \"Allows customers to view information about their bank accounts, and make payments.\"\n    );\n\n    public static SoftwareSystem Mainframe =\u003e new(\n        alias: \"Mainframe\",\n        label: \"Mainframe Banking System\",\n        description: \"Stores all of the core banking information about customers, accounts, transactions, etc.\",\n        boundary: Boundary.External\n    );\n\n    public static SoftwareSystem MailSystem =\u003e new(\n        alias: \"MailSystem\",\n        label: \"E-mail system\",\n        description: \"The internal Microsoft Exchange e-mail system.\",\n        boundary: Boundary.External\n    );\n}\n\n\n```\n\n```c#\npublic class ContextDiagramSample : ContextDiagram\n{\n    protected override string Title =\u003e \"Component diagram for Internet Banking System\";\n    \n    protected override IEnumerable\u003cStructure\u003e Structures =\u003e new Structure[]\n    {\n        Customer,\n        BankingSystem,\n        Mainframe,\n        MailSystem\n    };\n\n    protected override IEnumerable\u003cRelationship\u003e Relationships =\u003e new[]\n    {\n        Customer \u003e BankingSystem,\n        Customer \u003c MailSystem | \"Sends e-mails to\",\n        BankingSystem \u003e MailSystem | (\"Sends e-mails\", \"SMTP\") | Neighbor,\n        BankingSystem \u003e Mainframe\n    };\n}\n```\n### Compiling the diagram\nThere are two strategies for compiling diagrams in your project: self-compiling and using the `C4SCLI` tool.\nThe following code shows how to compile the diagram:\n\n#### Self-compiling approach: \n\n```c#\nusing C4Sharp.Diagrams;\nusing C4Sharp.Diagrams.Plantuml;\nusing C4Sharp.Diagrams.Themes;\nusing ModelDiagrams.Diagrams;\n\nvar diagrams = new DiagramBuilder[]\n{\n    new ContextDiagramSample(),\n    new ComponentDiagramSample(),\n    new ContainerDiagramSample(),\n    new EnterpriseDiagramSample(),\n    new SequenceDiagramSample(),\n    new DeploymentDiagramSample()\n};\n\nvar path = Path.Combine(\"..\", \"..\", \"..\", \"..\", \"..\", \"docs\", \"images\");\n        \nnew PlantumlContext()\n    .UseDiagramImageBuilder()\n    .Export(path, diagrams, new DefaultTheme());\n```\n\nThe result of the previous code is the following diagram:\n![img](./docs/images/container-diagram-for-internet-banking-system-c4container.svg)\n\n#### Using the C4SCLI tool:\n\n\u003e [!TIP]\\\n\u003e The `C4SCLI` can be used in DevOps pipelines, removing the need to manually compile diagrams. For this, install `C4SCLI` tool and execute de the following command:\n```shell\n$ c4scli build \u003csolution path\u003e [-o \u003coutput path\u003e]\n```\n\n### Customizing the diagram\n#### Using Themes\nThemes are used to customize the diagram. The following code shows how to use the `ParadisoTheme` theme to compile the diagram:\n\n```c#\nnew PlantumlContext()\n    .UseDiagramImageBuilder()\n    .Export(path, diagrams, new ParadisoTheme());\n```\n\nThe result of the previous code is the following diagram:\n![img](./docs/images/container-diagram-for-internet-banking-system-v2-c4container.svg)\n\n#### Creating a custom theme\n\nYou can create a custom theme by implementing the `ITheme` interface. The following code shows how to create a custom theme:\n\n```c#\npublic class DefaultTheme: IDiagramTheme\n{\n    private const string ComponentBackground = \"#85bbf0\";\n    private const string ComponentBorder = \"#78a8d9\";\n    private const string ComponentText = \"#000000\";\n    \n    private const string ContainerBackground = \"#438dd4\";\n    private const string ContainerBorder = \"#3e82c5\";\n    private const string ContainerText = \"#FFFFFF\";\n    \n    private const string PersonBackground = \"#0d437b\";\n    private const string PersonBorder = \"#0d437b\";\n    private const string PersonText = \"#FFFFFF\";\n    \n    private const string ExternalBackground = \"#999999\";\n    private const string ExternalBorder = \"#8a8a8a\";\n    private const string ExternalText = \"#FFFFFF\";\n\n    private const string SystemBackground = \"#1a67be\";\n    private const string SystemBorder = \"#175eaa\";\n    private const string SystemText = \"#FFFFFF\";\n\n    public IElementStyle? Style =\u003e new ElementStyle()\n        .UpdateElementStyle(ElementName.System, SystemBackground, SystemText, SystemBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)\n        .UpdateElementStyle(ElementName.ExternalSystem, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1)\n        .UpdateElementStyle(ElementName.Person, PersonBackground, PersonText, PersonBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)\n        .UpdateElementStyle(ElementName.Component, ComponentBackground, ComponentText, ComponentBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)\n        .UpdateElementStyle(ElementName.ExternalComponent, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1)\n        .UpdateElementStyle(ElementName.Container, ContainerBackground, ContainerText, ContainerBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)\n        .UpdateElementStyle(ElementName.ExternalContainer, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1);\n\n    public IBoundaryStyle? BoundaryStyle =\u003e new BoundaryStyle()\n        .UpdateBoundaryStyle(ElementName.System, \"#FFFFFF\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape)\n        .UpdateBoundaryStyle(ElementName.Container, \"#FFFFFF\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape)\n        .UpdateBoundaryStyle(ElementName.Enterprise, \"#FFFFFF\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape);\n\n    public IElementTag? Tags { get; } = null;\n    public IRelationshipTag? RelTags { get; } = null;\n}\n```\n#### Customizing the diagram through the SetStyle method\n\nUsing the `C4S` library, you can customize the diagram by implementing the SetStyle() method, as in the following example:\n\n```c#\nprotected override IElementStyle? SetStyle()\n{\n    return new ElementStyle()\n        .UpdateElementStyle(ElementName.Person, \"#000000\", \"#000000\")\n        .UpdateElementStyle(ElementName.Container, \"#ffffff\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape)\n        .UpdateElementStyle(ElementName.System, \"#f4f4f4\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape)\n        .UpdateElementStyle(ElementName.ExternalSystem, \"#f4f4f4\", \"#000000\", \"#000000\", false, Shape.RoundedBoxShape);\n}    \n```\n\n![img](./docs/images/c4bank-deposit-area-c4container-bw.png)\n\n### Exporting the diagram to different formats\n\nNow, C4Sharp can compile the [Mermaid](https://github.com/mermaid-js/mermaid) markdown file. For this, you should use the function `UseDiagramMermaidBuilder()`. The following code shows how to compile these files. \n\n```c#\n      context\n            .UseDiagramImageBuilder()\n            .UseDiagramSvgImageBuilder()\n            .UseDiagramMermaidBuilder()\n            .Export(diagrams);\n```\nUsing the code above you'll have the following result:\n\n```mermaid\nC4Context\n\ntitle System Enterprise diagram for Internet Banking System\n\nPerson_Ext(customer, \"Personal Banking Customer\", \"A customer of the bank, with personal bank accounts.\")\n\nEnterprise_Boundary(enterprise.boundary, \"Domain A\") {\n    System(BankingSystem, \"Internet Banking System\", \"Allows customers to view information about their bank accounts, and make payments.\", $tags=\"services\")\n    \nEnterprise_Boundary(enterprise.boundary.1, \"Domain Internal Users\") {\n    Person(internalcustomer, \"Personal Banking Customer\", \"An internal customer of the bank, with personal bank accounts.\")\n}\n\n    \nEnterprise_Boundary(enterprise.boundary.2, \"Domain Managers\") {\n    Person(manager, \"Manager Banking Customer\", \"A manager of the bank, with personal bank accounts.\")\n}\n\n}\n\nSystem_Ext(Mainframe, \"Mainframe Banking System\", \"Stores all of the core banking information about customers, accounts, transactions, etc.\")\nSystem_Ext(MailSystem, \"E-mail system\", \"The internal Microsoft Exchange e-mail system.\")\n\nRel(customer, BankingSystem, \"uses\")\nRel(internalcustomer, BankingSystem, \"uses\")\nRel(manager, BankingSystem, \"uses\")\nRel_Back(customer, MailSystem, \"Sends e-mails to\")\nRel(BankingSystem, MailSystem, \"Sends e-mails\", \"SMTP\")\nRel(BankingSystem, Mainframe, \"uses\")\n```\n\n\n# Learn\n- See more in our [sample code](./samples):\n- To learn more about `C4S` access our [wiki](https://github.com/8T4/c4sharp/wiki).\n\n# Thanks\n\n### C4 community\n\n- 🌟 [Simon Brown](https://twitter.com/simonbrown)\n- 🌟 [PlantUML Team](https://plantuml.com/)\n- 🌟 [C4-PlantUML Team](https://github.com/plantuml-stdlib/C4-PlantUML)\n\n### Contributors\n\n- 🥇 [Alberto Monteiro](https://github.com/AlbertoMonteiro)\n- 🥇 [Nino Dioses](https://github.com/Nino-Dioses)\n\n### Colleagues\n\n- 🤝 [Abraão Honório](https://www.linkedin.com/in/abraaohonorio)\n- 🤝 [Daniel Martins](https://www.linkedin.com/in/daniel-de-souza-martins)\n- 🤝 [Rafael Santos](https://www.linkedin.com/in/rafael-santos-0b51465)\n- 🤝 [Marcus Vinicius Santana Silva](https://github.com/Lowpoc#marcus-vinicius-santana-silva-lowpoc-)\n\n# Guide to contributing to a GitHub project\n\nThis is a guide to contributing to this open source project that uses GitHub. It’s mostly based on how many open sorce\nprojects operate. That’s all there is to it. The fundamentals are:\n\n- Fork the project \u0026 clone locally.\n- Create an upstream remote and sync your local copy before you branch.\n- Branch for each separate piece of work.\n- Do the work, write good commit messages, and read the CONTRIBUTING file if there is one.\n- Push to your origin repository.\n- Create a new PR in GitHub.\n- Respond to any code review feedback.\n\nIf you want to contribute to an open source project, the best one to pick is one that you are using yourself. The\nmaintainers will appreciate it!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F8T4%2Fc4sharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F8T4%2Fc4sharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F8T4%2Fc4sharp/lists"}