{"id":13629079,"url":"https://github.com/pierre3/PlantUmlClassDiagramGenerator","last_synced_at":"2025-04-17T04:33:00.335Z","repository":{"id":43210816,"uuid":"41860665","full_name":"pierre3/PlantUmlClassDiagramGenerator","owner":"pierre3","description":"This is a generator to create a class-diagram of PlantUML from the C# source code.","archived":false,"fork":false,"pushed_at":"2024-11-26T00:57:13.000Z","size":4052,"stargazers_count":717,"open_issues_count":40,"forks_count":135,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-17T03:53:34.505Z","etag":null,"topics":["c-sharp","class-diagram","plantuml"],"latest_commit_sha":null,"homepage":null,"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/pierre3.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":"pierre3"}},"created_at":"2015-09-03T13:17:42.000Z","updated_at":"2025-04-16T18:09:49.000Z","dependencies_parsed_at":"2023-02-09T02:46:17.373Z","dependency_job_id":"6119c7bd-b3d2-4eed-abda-dac31e5eaa19","html_url":"https://github.com/pierre3/PlantUmlClassDiagramGenerator","commit_stats":{"total_commits":121,"total_committers":18,"mean_commits":6.722222222222222,"dds":0.371900826446281,"last_synced_commit":"72b98c97652189b15349b8bdc8782c48eb4ac12a"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre3%2FPlantUmlClassDiagramGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre3%2FPlantUmlClassDiagramGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre3%2FPlantUmlClassDiagramGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre3%2FPlantUmlClassDiagramGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pierre3","download_url":"https://codeload.github.com/pierre3/PlantUmlClassDiagramGenerator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249316044,"owners_count":21249881,"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":["c-sharp","class-diagram","plantuml"],"created_at":"2024-08-01T22:01:02.319Z","updated_at":"2025-04-17T04:32:57.418Z","avatar_url":"https://github.com/pierre3.png","language":"C#","funding_links":["https://github.com/sponsors/pierre3"],"categories":["Contributors Welcome for those"],"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"],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cstrong\u003e\u003ca href=\"README.md\"\u003eEnglish\u003c/a\u003e | \u003ca href=\"README.zh-CN.md\"\u003e简体中文\u003c/a\u003e\u003c/strong\u003e\n\u003c/div\u003e\n\n\n# PlantUmlClassDiagramGenerator\n\nThis is a generator to create a class-diagram of PlantUML from the C# source code.\n\n**README.md Version revision history**\n\n| Version | Commit                                                       | Comment                                                      |\n| ------- | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| 1.1     | [e73b4fe](https://github.com/pierre3/PlantUmlClassDiagramGenerator/commit/e73b4feed9cd261271eb990a9c859f53536e8d7c) | Add \"-excludeUmlBeginEndTags\" option |\n| 1.0     | [70bb820](https://github.com/pierre3/PlantUmlClassDiagramGenerator/commit/70bb8202f7f489aa2d85ce9c25c58121c8f63aed) | Because the README.md for other languages is not always updated at the same time, a version number is needed |\n\n## Roslyn Source Generator\n\nThe class diagram is automatically generated by the Roslyn Source Generator. Details are provided in the link below.\n\n- [PlantUmlClassDiagramGenerator.SourceGenerator](/src/PlantUmlClassDiagramGenerator.SourceGenerator)\n\n\n## Visual Studio Code Extension\n\n- [C# to PlantUML](https://marketplace.visualstudio.com/items?itemName=pierre3.csharp-to-plantuml)\n\n## .Net Core global tools\n\nNuget Gallery: https://www.nuget.org/packages/PlantUmlClassDiagramGenerator\n\n### Installation\nDownload and install the [.NET 8.0 SDK](https://www.microsoft.com/net/download/windows) or newer. Once installed, run the following command.\n\n```bat\ndotnet tool install --global PlantUmlClassDiagramGenerator\n```\n### Usage\nRun the \"puml-gen\" command.\n\n```bat\npuml-gen InputPath [OutputPath] [-dir] [-public | -ignore IgnoreAccessibilities] [-excludePaths ExcludePathList] [-createAssociation]\n```\n\n- InputPath: (Required) Sets a input source file or directory name.\n- OutputPath: (Optional) Sets a output file or directory name.  \n  If you omit this option, plantuml files are outputted to same directory as the input files.\n- -dir: (Optional) Specify when InputPath and OutputPath are directory names.\n- -public: (Optional) If specified, only public accessibility members are output. \n- -ignore: (Optional) Specify the accessibility of members to ignore, with a comma separated list.\n- -excludePaths: (Optional) Specify the exclude file and directory.   \n  Specifies a relative path from the \"InputPath\", with a comma separated list.\n  To exclude multiple paths, which contain a specific folder name, preceed the name by \"\\*\\*/\". Example: \"**/bin\"\n- -createAssociation: (Optional) Create object associations from references of fields and properites.\n- -allInOne: (Optional) Only if -dir is set: copy the output of all diagrams to file include.puml (this allows a PlanUMLServer to render it).\n- -attributeRequired: (Optional) When this switch is enabled, only types with \"PlantUmlDiagramAttribute\" in the type declaration will be output.\n- -excludeUmlBeginEndTags: (Optional) When this switch is enabled, it will exclude the \\\"@startuml\\\" and \\\"@enduml\\\" tags from the puml file.\n\nexamples\n```bat\npuml-gen C:\\Source\\App1\\ClassA.cs -public\n```\n\n```bat\npuml-gen C:\\Source\\App1 C:\\PlantUml\\App1 -dir -ignore Private,Protected -createAssociation -allInOne\n```\n\n```bat\npuml-gen C:\\Source\\App1 C:\\PlantUml\\App1 -dir -excludePaths bin,obj,Properties\n```\n\n## Specification for conversion to PlantUML\n\n### Type Declaration\n\n#### Type Keywords\n\n|C#               | PlantUML           |\n|:----------------|-------------------:|\n| `class`         | `class`            |\n| `struct`        | `struct`           |\n| `interface`     | `interface`        |\n| `enum`          | `enum`             |\n| `record`        | `\u003c\u003crecord\u003e\u003e class` |\n\n#### Type Modifiers\n\n|C#               | PlantUML           |\n|:----------------|-------------------:|\n| `abstract`       | `abstract`        |\n| `static`        | `\u003c\u003cstatic\u003e\u003e`       |\n| `partial`       | `\u003c\u003cpartial\u003e\u003e`      |\n| `sealed`        | `\u003c\u003csealed\u003e\u003e`       |\n\n- C#\n\n```cs\nclass ClassA {  \n}\nstruct StructA {\n}\ninterface InterfaceA {\n}\nrecord RecordA {\n}\nabstract class AbstractClass {\n}\nstatic class StaticClass {\n}\nsealed partial class ClassB{\n}\nenum EnumType{\n  Apple,\n  Orange,\n  Grape\n}\n```\n- PlantUML\n\n```\n@startuml\nclass ClassA {\n}\nstruct StructA {\n}\ninterface InterfaceA {\n}\nclass RecordA \u003c\u003crecord\u003e\u003e {\n}\nabstract class AbstractClass {\n}\nclass StaticClass \u003c\u003cstatic\u003e\u003e {\n}\nclass ClassB \u003c\u003csealed\u003e\u003e \u003c\u003cpartial\u003e\u003e {\n}\nenum EnumType {\n    Apple,\n    Orange,\n    Grape,\n}\n@enduml\n```\n\n![TypeDeclaration.png](uml/TypeDeclaration.png)\n\n#### Generics Type\n\n- C#\n\n```cs\nclass GenericsType\u003cT1\u003e{\n}\nclass GenericsType\u003cT1,T2\u003e{\n}\n```\n- PlantUML\n\n```\nclass \"GenericsType`1\"\u003cT1\u003e{\n}\nclass \"GenericsType`2\"\u003cT1,T2\u003e{\n}\n```\n\n![GenericsTypeDeclaration.png](uml/GenericsTypeDeclaration.png)\n\n### Member Declaration\n\n#### Accessibility Modifiers\n\n|C#                    | PlantUML           |\n|:---------------------|-------------------:|\n| `public`             | `+`                |\n| `internal`           | `\u003c\u003cinternal\u003e\u003e`     |\n| `protected internal` | `# \u003c\u003cinternal\u003e\u003e`   |\n| `protected`          | `#`                |\n| `private`            | `-`                |\n\n#### Modifiers\n\n|C#            | PlantUML         |\n|:-------------|-----------------:|\n| `abstract`   | `{abstract}`     |\n| `static`     | `{static}`       |\n| `virtual`    | `\u003c\u003cvirtual\u003e\u003e`    |\n| `override`   | `\u003c\u003coverride\u003e\u003e`   |\n| `new`        | `\u003c\u003cnew\u003e\u003e`        |\n| `readonly`   | `\u003c\u003creadonly\u003e\u003e`   |\n| `event`      | `\u003c\u003cevent\u003e\u003e`      |\n\n#### Property Accessors\n\n|C#                              | PlantUML                            |\n|:-------------------------------|------------------------------------:|\n| `int Prop {get; set;}`         | `Prop : int \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e`        |\n| `int Prop {get;}`              | `Prop : int \u003cget\u003e`                  |\n| `int Prop {get; private set }` | `Prop : int \u003c\u003cget\u003e\u003e\u003c\u003cprivate set\u003e\u003e` |\n| `int Prop =\u003e 100;`             | `Prop : int \u003c\u003cget\u003e\u003e`                |\n\n- C#\n\n```cs\nabstract class AbstractClass\n{\n    protected int _x;\n    internal int _y;\n    protected internal int _z;\n    public abstract void AbstractMethod();\n    protected virtual void VirtualMethod(string s){\n\n    }\n    public string BaseMethod(int n){\n        return \"\";\n    }\n}\nclass ClassM : AbstractClass\n{\n    public static readonly double PI =3.141592;\n    public int PropA { get; set; }\n    public int PropB { get; protected set; }\n    public event EventHandler SomeEvent;\n    public override void AbstractMethod(){\n        \n    }\n    protected override void VirtualMethod(string s)\n    {\n\n    }\n    public override string ToString()\n    {\n        return \"override\";\n    }\n    public new string BaseMethod(int n){\n        return \"new\";\n    }\n}\n```\n\n- PlantUML\n\n```\nabstract class AbstractClass {\n    # _x : int\n    \u003c\u003cinternal\u003e\u003e _y : int\n    # \u003c\u003cinternal\u003e\u003e _z : int\n    + {abstract} AbstractMethod() : void\n    # \u003c\u003cvirtual\u003e\u003e VirtualMethod(s:string) : void\n    + BaseMethod(n:int) : string\n}\nclass ClassM {\n    + {static} \u003c\u003creadonly\u003e\u003e PI : double = 3.141592\n    + PropA : int \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n    + PropB : int \u003c\u003cget\u003e\u003e \u003c\u003cprotected set\u003e\u003e\n    +  \u003c\u003cevent\u003e\u003e SomeEvent : EventHandler \n    + \u003c\u003coverride\u003e\u003e AbstractMethod() : void\n    # \u003c\u003coverride\u003e\u003e VirtualMethod(s:string) : void\n    + \u003c\u003coverride\u003e\u003e ToString() : string\n    + \u003c\u003cnew\u003e\u003e BaseMethod(n:int) : string\n}\nAbstractClass \u003c|-- ClassM\n```\n\n![MemberDeclaration.png](uml/MemberDeclaration.png)\n\n#### Field and Property Initializers\n\nOnly __literal__ initializers are output.\n\n- C#\n\n```cs\nclass ClassC\n{\n    private int fieldA = 123;\n    public double Pi {get;} = 3.14159;\n    protected List\u003cstring\u003e Items = new List\u003cstring\u003e(); \n}\n```\n\n- PlantUML\n\n```\nclass ClassC {\n  - fieldA : int = 123\n  + Pi : double = 3.14159\n  # Items : List\u003cstring\u003e\n}\n```\n\n![Initializer.png](uml/Initializer.png)\n\n### Nested Class Declaration\n\nNested classes are expanded and associated with \"OuterClass + - InnerClass\".\n\n- C#\n\n```cs\nclass OuterClass \n{\n  class InnerClass \n  {\n    struct InnerStruct \n    {\n\n    }\n  }\n}\n```\n\n- PlantUML\n\n```\nclass OuterClass{\n\n}\nclass InnerClass{\n\n}\n\u003c\u003cstruct\u003e\u003e class InnerStruct {\n\n}\nOuterClass +- InnerClass\nInnerClass +- InnerStruct\n```\n\n![NestedClass.png](uml/NestedClass.png)\n\n### Inheritance Relationsips\n\n- C#\n\n```cs\nabstract class BaseClass\n{\n    public abstract void AbstractMethod();\n    protected virtual int VirtualMethod(string s) =\u003e 0;\n}\nclass SubClass : BaseClass\n{\n    public override void AbstractMethod() { }\n    protected override int VirtualMethod(string s) =\u003e 1;\n}\n\ninterface IInterfaceA {}\ninterface IInterfaceA\u003cT\u003e:IInterfaceA\n{\n    T Value { get; }\n}\nclass ImplementClass : IInterfaceA\u003cint\u003e\n{\n    public int Value { get; }\n}\n```\n\n- PlantUML\n\n```\nabstract class BaseClass {\n    + {abstract} AbstractMethod() : void\n    # \u003c\u003cvirtual\u003e\u003e VirtualMethod(s:string) : int\n}\nclass SubClass {\n    + \u003c\u003coverride\u003e\u003e AbstractMethod() : void\n    # \u003c\u003coverride\u003e\u003e VirtualMethod(s:string) : int\n}\ninterface IInterfaceA {\n}\ninterface \"IInterfaceA`1\"\u003cT\u003e {\n    Value : T \u003c\u003cget\u003e\u003e\n}\nclass ImplementClass {\n    + Value : int \u003c\u003cget\u003e\u003e\n}\nBaseClass \u003c|-- SubClass\nIInterfaceA \u003c|-- \"IInterfaceA`1\"\n\"IInterfaceA`1\" \"\u003cint\u003e\" \u003c|-- ImplementClass\n```\n\n![InheritanceRelationsips.png](uml/InheritanceRelationsips.png)\n\n### Associations (from references of fields and properties)\n\nIf you specify the \"createAssociation\" option, object associations is created from field and property references.\n\n- C#\n\n```cs\nclass ClassA{\n    public IList\u003cstring\u003e Strings{get;} = new List\u003cstring\u003e();\n    public Type1 Prop1{get;set;}\n    public Type2 field1;\n}\n\nclass Type1 {\n    public int value1{get;set;}\n}\n\nclass Type2{\n    public string string1{get;set;}\n    public ExternalType Prop2 {get;set;}\n}\n```\n\n- PlantUML\n\n```\n@startuml\nclass ClassA {\n}\nclass Type1 {\n    + value1 : int \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n}\nclass Type2 {\n    + string1 : string \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n}\nclass \"IList`1\"\u003cT\u003e {\n}\nClassA o-\u003e \"Strings\u003cstring\u003e\" \"IList`1\"\nClassA --\u003e \"Prop1\" Type1\nClassA --\u003e \"field1\" Type2\nType2 --\u003e \"Prop2\" ExternalType\n@enduml\n```\n\n![InheritanceRelationsips.png](uml/Associations.png)\n\n\n### Record types (with parameter list)\n\nRecord types in C# 9 can have a parameter list. In these cases these parameters\nare added as properties to the class.\n\n\n- C#\n\n```cs\nrecord Person(string Name, int Age);\n\nrecord Group(string GroupName) {\n    public Person[] Members { get; init; }\n}\n```\n\n- PlantUML\n\n```\n@startuml\nclass Person \u003c\u003crecord\u003e\u003e {\n    + Name : string \u003c\u003cget\u003e\u003e \u003c\u003cinit\u003e\u003e\n    + Age : int \u003c\u003cget\u003e\u003e \u003c\u003cinit\u003e\u003e\n}\nclass Group \u003c\u003crecord\u003e\u003e {\n    + GroupName : string \u003c\u003cget\u003e\u003e \u003c\u003cinit\u003e\u003e\n    + Members : Person[] \u003c\u003cget\u003e\u003e \u003c\u003cinit\u003e\u003e\n}\n@enduml\n```\n\n![InheritanceRelationsips.png](uml/RecordParameterList.png)\n\n## Attribute-based configuration\n\nYou can add the package [PlantUmlClassDiagramGenerator.Attributes](https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.Attributes) to your C# project for attribute-based configuration.\n\n### PlantUmlDiagramAttribute\nOnly types to which PlantUmlDiagramAttribute has been added will be output.\nThis attribute is enabled if the -attributeRequired switch is added to the command line argument.\n\nThis attribute can be added only to type declalerations.\n- class\n- struct\n- enum\n- record\n\n```cs\nclass ClassA\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n}\n\n[PlantUmlDiagram]\nclass ClassB\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n}\n```\n\nOnly ClassB with PlantUmlDiagramAttribute will be output.\n\n```\n@startuml\nclass ClassB {\n    + Name : string \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n    + Age : int \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n}\n@enduml\n```\n\n\n### PlantUmlIgnoreAttribute\nElements with this attribute added are excluded from the output.\n\n```cs\n[PlantUmlIgnore]\nclass ClassA\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n}\n\nclass ClassB\n{\n    public string Name { get; set; }\n    [PlantUmlIgnore]\n    public int Age { get; set; }\n}\n\nclass ClassC\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n\n    [PlantUmlIgnore]\n    public ClassC(string name, int age) =\u003e (Name, Age) = (name, age);\n    \n    public void MethodA();\n    \n    [PlantUmlIgnore]\n    public void MethodB();\n}\n```\n\n```\n@startuml\nclass ClassB {\n    + Name : string\n}\nclass ClassC {\n    + Name : string\n    + Age : int\n    + MethodA() : void\n}\n@enduml\n```\n\n### PlantUmlAssociationAttribute\nBy adding this attribute, you can define association between classes.\nThis attribute can be added to properties, fields and method parameters.\n\nThe details of the association are defined in the following properties.\n\n- _Name_\n  - Specifies the type name on the leaf node side.\n  - If omitted, the name of the element to which the attribute is added is used.\n- _Association_\n  - Specifies the edge portion of the association.Sets a valid string in PlantUML.\n  - If omitted, \"--\" is used.\n- _RootLabel_\n  - Specifies the label to be displayed on the root node side.\n  - If omitted, nothing is displayed. \n- _Label_\n  - Specifies the label to be displayed in the center of the edge.\n  - If omitted, nothing is displayed. \n- _LeafLabel_ \n  - Specifies the label to be displayed on the leaf node side.\n  - If omitted, nothing is displayed.  \n\n```cs\nclass Parameters\n{\n    public string A { get; set; }\n    public string B { get; set; }\n}\n\nclass CustomAssociationSample\n{\n    [PlantUmlAssociation(Name = \"Name\", Association = \"*--\u003e\", LeafLabel = \"LeafLabel\", Label= \"Label\", RootLabel = \"RootLabel\")] \n    public ClassA A { get; set; }\n}\n\nclass CollectionItemsSample\n{\n    [PlantUmlAssociation(Name = \"Item\", Association = \"o--\", LeafLabel = \"0..*\", Label = \"Items\")]\n    public IList\u003cItem\u003e Items { get; set; }\n}\n\nclass MethodParamtersSample\n{\n    public void Run([PlantUmlAssociation(Association = \"..\u003e\", Label = \"use\")] Parameters p)\n    {\n        Console.WriteLine($\"{p.A},{p.B}\");\n    }\n\n    private ILogger logger;\n    public MyClass([PlantUmlAssociation(Association = \"..\u003e\", Label = \"Injection\")] ILogger logger)\n    {\n        this.logger = logger;\n    }\n}\n```\n\n```\n@startuml\nclass Parameters {\n    + A : string \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n    + B : string \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n}\nclass CustomAssociationSample {\n}\nclass CollectionItemsSample {\n}\nclass MethodParamtersSample {\n    + Run(p:Parameters) : void\n    + MyClass(logger:ILogger)\n}\nCustomAssociationSample \"RootLabel\" *--\u003e \"LeafLabel\" Name : \"Label\"\nCollectionItemsSample o-- \"0..*\" Item : \"Items\"\nMethodParamtersSample ..\u003e Parameters : \"use\"\nMethodParamtersSample ..\u003e ILogger : \"Injection\"\n@enduml\n```\n\n![CustomAssociation.png](uml/CustomAssociation.png)\n\n### PlantUmlIgnoreAssociationAttribute\n\nThis attribute can be added to properties and fields.\nProperties (or fields) with this attribute are described as members of the class without any association.\n\n```cs\nclass User\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n}\n\nclass ClassA\n{\n    public static User DefaultUser { get; }\n    public IList\u003cUser\u003e Users { get; }\n\n    public ClassA(IList\u003cUser\u003e users)\n    {\n        Users = users;\n        DefaultUser = new User()\n        {\n            Name = \"DefaultUser\",\n            Age = \"20\"\n        };\n    }\n}\n\nclass ClassB\n{\n    [PlantUmlIgnoreAssociation]\n    public static User DefaultUser { get; }\n\n    [PlantUmlIgnoreAssociation]\n    public IList\u003cUser\u003e Users { get; }\n\n    public ClassB(IList\u003cUser\u003e users)\n    {\n        Users = users;\n        DefaultUser = new User()\n        {\n            Name = \"DefaultUser\",\n            Age = \"20\"\n        };\n    }\n}\n```\n\n```\n@startuml\nclass User {\n    + Name : string \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n    + Age : int \u003c\u003cget\u003e\u003e \u003c\u003cset\u003e\u003e\n}\nclass ClassA {\n    + ClassA(users:IList\u003cUser\u003e)\n}\nclass ClassB {\n    + {static} DefaultUser : User \u003c\u003cget\u003e\u003e\n    + Users : IList\u003cUser\u003e \u003c\u003cget\u003e\u003e\n    + ClassB(users:IList\u003cUser\u003e)\n}\nclass \"IList`1\"\u003cT\u003e {\n}\nClassA --\u003e \"DefaultUser\" User\nClassA --\u003e \"Users\u003cUser\u003e\" \"IList`1\"\n@enduml\n```\n\n![IgnoreAssociation.png](uml/IgnoreAssociation.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierre3%2FPlantUmlClassDiagramGenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpierre3%2FPlantUmlClassDiagramGenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierre3%2FPlantUmlClassDiagramGenerator/lists"}