Git Product home page Git Product logo

plantumlclassdiagramgenerator's Introduction

PlantUmlClassDiagramGenerator

This is a generator to create a class-diagram of PlantUML from the C# source code.

README.md Version revision history

Version Commit Comment
1.1 e73b4fe Add "-excludeUmlBeginEndTags" option
1.0 70bb820 Because the README.md for other languages is not always updated at the same time, a version number is needed

Roslyn Source Generator

The class diagram is automatically generated by the Roslyn Source Generator. Details are provided in the link below.

Visual Studio Code Extension

.Net Core global tools

Nuget Gallery: https://www.nuget.org/packages/PlantUmlClassDiagramGenerator

Installation

Download and install the .NET 8.0 SDK or newer. Once installed, run the following command.

dotnet tool install --global PlantUmlClassDiagramGenerator

Usage

Run the "puml-gen" command.

puml-gen InputPath [OutputPath] [-dir] [-public | -ignore IgnoreAccessibilities] [-excludePaths ExcludePathList] [-createAssociation]
  • InputPath: (Required) Sets a input source file or directory name.
  • OutputPath: (Optional) Sets a output file or directory name.
    If you omit this option, plantuml files are outputted to same directory as the input files.
  • -dir: (Optional) Specify when InputPath and OutputPath are directory names.
  • -public: (Optional) If specified, only public accessibility members are output.
  • -ignore: (Optional) Specify the accessibility of members to ignore, with a comma separated list.
  • -excludePaths: (Optional) Specify the exclude file and directory.
    Specifies a relative path from the "InputPath", with a comma separated list. To exclude multiple paths, which contain a specific folder name, preceed the name by "**/". Example: "**/bin"
  • -createAssociation: (Optional) Create object associations from references of fields and properites.
  • -allInOne: (Optional) Only if -dir is set: copy the output of all diagrams to file include.puml (this allows a PlanUMLServer to render it).
  • -attributeRequired: (Optional) When this switch is enabled, only types with "PlantUmlDiagramAttribute" in the type declaration will be output.
  • -excludeUmlBeginEndTags: (Optional) When this switch is enabled, it will exclude the "@startuml" and "@enduml" tags from the puml file.

examples

puml-gen C:\Source\App1\ClassA.cs -public
puml-gen C:\Source\App1 C:\PlantUml\App1 -dir -ignore Private,Protected -createAssociation -allInOne
puml-gen C:\Source\App1 C:\PlantUml\App1 -dir -excludePaths bin,obj,Properties

Specification for conversion to PlantUML

Type Declaration

Type Keywords

C# PlantUML
class class
struct struct
interface interface
enum enum
record <<record>> class

Type Modifiers

C# PlantUML
abstract abstract
static <<static>>
partial <<partial>>
sealed <<sealed>>
  • C#
class ClassA {  
}
struct StructA {
}
interface InterfaceA {
}
record RecordA {
}
abstract class AbstractClass {
}
static class StaticClass {
}
sealed partial class ClassB{
}
enum EnumType{
  Apple,
  Orange,
  Grape
}
  • PlantUML
@startuml
class ClassA {
}
struct StructA {
}
interface InterfaceA {
}
class RecordA <<record>> {
}
abstract class AbstractClass {
}
class StaticClass <<static>> {
}
class ClassB <<sealed>> <<partial>> {
}
enum EnumType {
    Apple,
    Orange,
    Grape,
}
@enduml

TypeDeclaration.png

Generics Type

  • C#
class GenericsType<T1>{
}
class GenericsType<T1,T2>{
}
  • PlantUML
class "GenericsType`1"<T1>{
}
class "GenericsType`2"<T1,T2>{
}

GenericsTypeDeclaration.png

Member Declaration

Accessibility Modifiers

C# PlantUML
public +
internal <<internal>>
protected internal # <<internal>>
protected #
private -

Modifiers

C# PlantUML
abstract {abstract}
static {static}
virtual <<virtual>>
override <<override>>
new <<new>>
readonly <<readonly>>
event <<event>>

Property Accessors

C# PlantUML
int Prop {get; set;} Prop : int <<get>> <<set>>
int Prop {get;} Prop : int <get>
int Prop {get; private set } Prop : int <<get>><<private set>>
int Prop => 100; Prop : int <<get>>
  • C#
abstract class AbstractClass
{
    protected int _x;
    internal int _y;
    protected internal int _z;
    public abstract void AbstractMethod();
    protected virtual void VirtualMethod(string s){

    }
    public string BaseMethod(int n){
        return "";
    }
}
class ClassM : AbstractClass
{
    public static readonly double PI =3.141592;
    public int PropA { get; set; }
    public int PropB { get; protected set; }
    public event EventHandler SomeEvent;
    public override void AbstractMethod(){
        
    }
    protected override void VirtualMethod(string s)
    {

    }
    public override string ToString()
    {
        return "override";
    }
    public new string BaseMethod(int n){
        return "new";
    }
}
  • PlantUML
abstract class AbstractClass {
    # _x : int
    <<internal>> _y : int
    # <<internal>> _z : int
    + {abstract} AbstractMethod() : void
    # <<virtual>> VirtualMethod(s:string) : void
    + BaseMethod(n:int) : string
}
class ClassM {
    + {static} <<readonly>> PI : double = 3.141592
    + PropA : int <<get>> <<set>>
    + PropB : int <<get>> <<protected set>>
    +  <<event>> SomeEvent : EventHandler 
    + <<override>> AbstractMethod() : void
    # <<override>> VirtualMethod(s:string) : void
    + <<override>> ToString() : string
    + <<new>> BaseMethod(n:int) : string
}
AbstractClass <|-- ClassM

MemberDeclaration.png

Field and Property Initializers

Only literal initializers are output.

  • C#
class ClassC
{
    private int fieldA = 123;
    public double Pi {get;} = 3.14159;
    protected List<string> Items = new List<string>(); 
}
  • PlantUML
class ClassC {
  - fieldA : int = 123
  + Pi : double = 3.14159
  # Items : List<string>
}

Initializer.png

Nested Class Declaration

Nested classes are expanded and associated with "OuterClass + - InnerClass".

  • C#
class OuterClass 
{
  class InnerClass 
  {
    struct InnerStruct 
    {

    }
  }
}
  • PlantUML
class OuterClass{

}
class InnerClass{

}
<<struct>> class InnerStruct {

}
OuterClass +- InnerClass
InnerClass +- InnerStruct

NestedClass.png

Inheritance Relationsips

  • C#
abstract class BaseClass
{
    public abstract void AbstractMethod();
    protected virtual int VirtualMethod(string s) => 0;
}
class SubClass : BaseClass
{
    public override void AbstractMethod() { }
    protected override int VirtualMethod(string s) => 1;
}

interface IInterfaceA {}
interface IInterfaceA<T>:IInterfaceA
{
    T Value { get; }
}
class ImplementClass : IInterfaceA<int>
{
    public int Value { get; }
}
  • PlantUML
abstract class BaseClass {
    + {abstract} AbstractMethod() : void
    # <<virtual>> VirtualMethod(s:string) : int
}
class SubClass {
    + <<override>> AbstractMethod() : void
    # <<override>> VirtualMethod(s:string) : int
}
interface IInterfaceA {
}
interface "IInterfaceA`1"<T> {
    Value : T <<get>>
}
class ImplementClass {
    + Value : int <<get>>
}
BaseClass <|-- SubClass
IInterfaceA <|-- "IInterfaceA`1"
"IInterfaceA`1" "<int>" <|-- ImplementClass

InheritanceRelationsips.png

Associations (from references of fields and properties)

If you specify the "createAssociation" option, object associations is created from field and property references.

  • C#
class ClassA{
    public IList<string> Strings{get;} = new List<string>();
    public Type1 Prop1{get;set;}
    public Type2 field1;
}

class Type1 {
    public int value1{get;set;}
}

class Type2{
    public string string1{get;set;}
    public ExternalType Prop2 {get;set;}
}
  • PlantUML
@startuml
class ClassA {
}
class Type1 {
    + value1 : int <<get>> <<set>>
}
class Type2 {
    + string1 : string <<get>> <<set>>
}
class "IList`1"<T> {
}
ClassA o-> "Strings<string>" "IList`1"
ClassA --> "Prop1" Type1
ClassA --> "field1" Type2
Type2 --> "Prop2" ExternalType
@enduml

InheritanceRelationsips.png

Record types (with parameter list)

Record types in C# 9 can have a parameter list. In these cases these parameters are added as properties to the class.

  • C#
record Person(string Name, int Age);

record Group(string GroupName) {
    public Person[] Members { get; init; }
}
  • PlantUML
@startuml
class Person <<record>> {
    + Name : string <<get>> <<init>>
    + Age : int <<get>> <<init>>
}
class Group <<record>> {
    + GroupName : string <<get>> <<init>>
    + Members : Person[] <<get>> <<init>>
}
@enduml

InheritanceRelationsips.png

Attribute-based configuration

You can add the package PlantUmlClassDiagramGenerator.Attributes to your C# project for attribute-based configuration.

PlantUmlDiagramAttribute

Only types to which PlantUmlDiagramAttribute has been added will be output. This attribute is enabled if the -attributeRequired switch is added to the command line argument.

This attribute can be added only to type declalerations.

  • class
  • struct
  • enum
  • record
class ClassA
{
    public string Name { get; set; }
    public int Age { get; set; }
}

[PlantUmlDiagram]
class ClassB
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Only ClassB with PlantUmlDiagramAttribute will be output.

@startuml
class ClassB {
    + Name : string <<get>> <<set>>
    + Age : int <<get>> <<set>>
}
@enduml

PlantUmlIgnoreAttribute

Elements with this attribute added are excluded from the output.

[PlantUmlIgnore]
class ClassA
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class ClassB
{
    public string Name { get; set; }
    [PlantUmlIgnore]
    public int Age { get; set; }
}

class ClassC
{
    public string Name { get; set; }
    public int Age { get; set; }

    [PlantUmlIgnore]
    public ClassC(string name, int age) => (Name, Age) = (name, age);
    
    public void MethodA();
    
    [PlantUmlIgnore]
    public void MethodB();
}
@startuml
class ClassB {
    + Name : string
}
class ClassC {
    + Name : string
    + Age : int
    + MethodA() : void
}
@enduml

PlantUmlAssociationAttribute

By adding this attribute, you can define association between classes. This attribute can be added to properties, fields and method parameters.

The details of the association are defined in the following properties.

  • Name
    • Specifies the type name on the leaf node side.
    • If omitted, the name of the element to which the attribute is added is used.
  • Association
    • Specifies the edge portion of the association.Sets a valid string in PlantUML.
    • If omitted, "--" is used.
  • RootLabel
    • Specifies the label to be displayed on the root node side.
    • If omitted, nothing is displayed.
  • Label
    • Specifies the label to be displayed in the center of the edge.
    • If omitted, nothing is displayed.
  • LeafLabel
    • Specifies the label to be displayed on the leaf node side.
    • If omitted, nothing is displayed.
class Parameters
{
    public string A { get; set; }
    public string B { get; set; }
}

class CustomAssociationSample
{
    [PlantUmlAssociation(Name = "Name", Association = "*-->", LeafLabel = "LeafLabel", Label= "Label", RootLabel = "RootLabel")] 
    public ClassA A { get; set; }
}

class CollectionItemsSample
{
    [PlantUmlAssociation(Name = "Item", Association = "o--", LeafLabel = "0..*", Label = "Items")]
    public IList<Item> Items { get; set; }
}

class MethodParamtersSample
{
    public void Run([PlantUmlAssociation(Association = "..>", Label = "use")] Parameters p)
    {
        Console.WriteLine($"{p.A},{p.B}");
    }

    private ILogger logger;
    public MyClass([PlantUmlAssociation(Association = "..>", Label = "Injection")] ILogger logger)
    {
        this.logger = logger;
    }
}
@startuml
class Parameters {
    + A : string <<get>> <<set>>
    + B : string <<get>> <<set>>
}
class CustomAssociationSample {
}
class CollectionItemsSample {
}
class MethodParamtersSample {
    + Run(p:Parameters) : void
    + MyClass(logger:ILogger)
}
CustomAssociationSample "RootLabel" *--> "LeafLabel" Name : "Label"
CollectionItemsSample o-- "0..*" Item : "Items"
MethodParamtersSample ..> Parameters : "use"
MethodParamtersSample ..> ILogger : "Injection"
@enduml

CustomAssociation.png

PlantUmlIgnoreAssociationAttribute

This attribute can be added to properties and fields. Properties (or fields) with this attribute are described as members of the class without any association.

class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class ClassA
{
    public static User DefaultUser { get; }
    public IList<User> Users { get; }

    public ClassA(IList<User> users)
    {
        Users = users;
        DefaultUser = new User()
        {
            Name = "DefaultUser",
            Age = "20"
        };
    }
}

class ClassB
{
    [PlantUmlIgnoreAssociation]
    public static User DefaultUser { get; }

    [PlantUmlIgnoreAssociation]
    public IList<User> Users { get; }

    public ClassB(IList<User> users)
    {
        Users = users;
        DefaultUser = new User()
        {
            Name = "DefaultUser",
            Age = "20"
        };
    }
}
@startuml
class User {
    + Name : string <<get>> <<set>>
    + Age : int <<get>> <<set>>
}
class ClassA {
    + ClassA(users:IList<User>)
}
class ClassB {
    + {static} DefaultUser : User <<get>>
    + Users : IList<User> <<get>>
    + ClassB(users:IList<User>)
}
class "IList`1"<T> {
}
ClassA --> "DefaultUser" User
ClassA --> "Users<User>" "IList`1"
@enduml

IgnoreAssociation.png

plantumlclassdiagramgenerator's People

Contributors

0x326 avatar chraxo avatar crazytoken avatar crown0815 avatar dependabot[bot] avatar drpepperbianco avatar filippobottega avatar gjuttla avatar incerrygit avatar khalidabuhakmeh avatar msallin avatar pendingchanges avatar pierre3 avatar shawnallen85 avatar shiena avatar thild avatar tyagi avatar vivraan avatar zacch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plantumlclassdiagramgenerator's Issues

Model Class attributes as class associations

I noticed that attributes are not modelled as class associations, which makes it very hard to see the coherence of generated classes

I'd propose an option to model attributes that have a non-simple class type to model as association,

so

class Foo 
{
  private readonly List<Bar> bars = new List<Bar>();
}

would become

Foo "- bars" --> "*" Bar

Generated malformed include file

I have this project for which I used the command ". -dir . -excludePaths Cryssage\obj -createAssociation -AllInOne"

And it generated good puml files for everything except the include.puml which looked like this:

image

After every '.' character from a file name it appends the character '\' .

Make generic types more readable: MyType`2 => MyType<T1,T2>

Since generic types are suffixed with backtick followed by the number of arguments it makes for difficult reading. This system exists solely to support the compiler, not humans.

Therefore I wish at least an option (if not default behaviour) that generic types are reprinted in a form that we expect from looking at the code.

Instead of:
MyType`2

The output should be:
MyType<T1,T2>

Of course if the actual type names used in the code would be preserved that would be even better, like so:
MyType<TKey,TValue>

All of a sudden you realize that this is probably some kind of dictionary, which you couldn't infer from the two versions above.

[Feature request] Private variables in VS Code extension

HI,

Currently, the private variables are not created with a - in front of the variable, meaning the proper icons are not showed in the class diagram output eventually. It would be nice to have this as I now do it manually.

Also, Currently when class A owns a variable of class B. The name of the variable is shown at the end of the arrow pointing from A to B. It would be nice to just have it inside the field of A as a variable of type B. so "aclass : B"

Only nullable properties are outputted

Having the following C# code:

public class Test
{
    public LinkedClass AdditionalData { get; set; }
    public LinkedClass? AdditionalData2 { get; set; }
}

public class LinkedClass
{
    public string Name { get; set; }
}

and running the following command: dotnet puml-gen ./ ./UML -dir -public -createAssociation

I get the following output:

@startuml
class Test {
    + AdditionalData2 : LinkedClass? <<get>> <<set>>
}
class LinkedClass {
    + Name : string <<get>> <<set>>
}
Test --> "AdditionalData" LinkedClass
@enduml

Only the nullable property is outputted.
Using version 1.3.4

Support struct type

Currently both class and struct use the type "class" in plantuml even though it supports the use of "struct".

excludePaths should allow excluding paths on all folder levels

Current situation

Currently the excludePaths argument filters only the exact specified path and does not allow filtering for all folders on all subfolder levels.

Example:

C:\dev\my-app> puml-gen -excludePaths obj 

This call excludes C:\dev\my-app\obj, but it does not exclude for example C:\dev\my-app\projectAbc\obj.

When using PlantUmlClassDiagramGenerator with a solution that contains multiple projects, this leads to a quite long list of excludePaths. Also, when new projects are added, or an existing project is renamed, then each time the excludePaths have to be adapted.

Proposal

It should be possible to generically filter all folders with a specific name, independent of the subfolder level where it is located.

Therefore wildcard characters should be allowed, such as known from .gitignore. For example to skip all obj folders on all levels the following parameter could be used:

puml-gen -excludePaths **/obj

Benefits:

  • Increases the flexibility.
  • The pattern is widely known.
  • No breaking api change.
  • The change is relatively easy to implement.

I would be happy to provide the implementation, if you agree with such a change.

An option to include class namespaces

Love the tool! I have a feature request that would make my workflow much easier.

I would like to see a flag added that would include the namespace for any class and reference to the output.

For example, instead of:

@startuml
interface IContactNotificationDbDataProvider {
    UpdateNotificationSetReadToTrue(guids:IEnumerable<Guid>) : Task
}
@enduml
@startuml
class ContactNotificationService {
    + <<async>> MarkNotificationsAsRead(guids:IEnumerable<Guid>) : Task
}
class "ILogger`1"<T> {
}
IContactNotificationService <|-- ContactNotificationService
ContactNotificationService --> "_dataProvider" IContactNotificationDbDataProvider
ContactNotificationService --> "_logger<ContactNotificationService>" "ILogger`1"
@enduml

I would prefer:

namespace Notifications {
    namespace Logic {
        namespace Services {
            class ContactNotificationService {
                + <<async>> MarkNotificationsAsRead(guids:IEnumerable<Guid>) : Task
            }
        }
    }
    namespace Model {
        namespace IService {
            interface IContactNotificationService {
                MarkNotificationsAsRead(guids:IEnumerable<Guid>) : Task
            }
        }
    }
}
namespace Microsoft.Extensions.Logging {
    interface ILogger<T> {
    }
}

Notification.Model.IService.IContactNotificationService <|-- Notification.Logic.Services.ContactNotificationService
Notification.Logic.Services.ContactNotificationService --> "_logger<ContactNotificationService>" Microsoft.Extensions.Logging.ILogger

How read List of Object

Hi, I made few adjustments to the application, including introducing the DateTime type, However, I have difficulties incorporating the List of Object. Maybe you have ideas regarding this issue?

Can't specify directory path as InputPath

Environment

  • PlantUmlClassDiagramGenerator version: 1.1.0
> dotnet --info
.NET Core SDK (global.json を反映):
 Version:   3.0.100-rc1-014190
 Commit:    c4d43f672d

ランタイム環境:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100-rc1-014190\

Host (useful for support):
  Version: 3.0.0-rc1-19456-20
  Commit:  8f5d7b1ba4

Summary

> puml-gen.exe C:\path\to\a\Project\Program.cs

This will generate C:\path\to\a\Project\Program.puml as expected, but following will not.

> puml-gen.exe C:\path\to\a\Project
"C:\path\to\a\Project" does not exist.

In VSCode, output path is relative to input path, not workspace folder

Thank you for the extension to Visual Studio Code.

The description of the csharp2plantuml.outputPath configuration option states that its value is relative to the workspace folder. However, the actual behavior (from this line) is that the output folder option is relative to the input folder. Please consider resolving the conflict in favor of the documentation, such that the value is relative to the workspace folder.

Inheritance

Great work, I was about to start a project like that!

It would be great if we can see the base classes, created with "<|--"

Addition of table of contents to the README?

Hello,

Thank you for this tool! I used it to create diagrams for my talk at the ACCU conference last week.

I find myself referring back to the examples here, often.

For this, it would really help if the front page had a table of contents.

I could set this up very quickly using mdsnippets - and if you don't mind a GitHub Action being added, I'd make it so that the ToC would be updated automatically on push, if the headings changed.

https://github.com/SimonCropp/MarkdownSnippets/blob/master/docs/github-action.md

Here's me demoing this at CppCon last year

Would you accept a PR for this? Thanks.

How to use it?

Is there anywhere a documentation how to use it?
I run the command csharp2plantuml.classDiagram in vs code but nothing happend.

What have i to do to get an class diagram from project?

L.G

Generate one puml file for a set of interfaces and classes related to each other by inheritance

I think for bigger projects it would not be feasible to generate allInOne. On the other side to have one puml for each type, which then only includes its base types does not help either. One would have to manually copy those together. for which one would like to see a complete inheritance diagram.
Therefore I think it would make sense to have a type filter like the fully qualified name of a class or an interface as parameter, with the goal to obtain a diagram with all the classes and interfaces related by inheritance. Later this could be refined to generate for example only recursively inherited classes or base classes.
In order to achieve this, one needs two passes. First generate all the syntax tree objects with their relations. Then starting from the seed class or interface recursively run through the relations to obtain the set to be rendered in puml.
In order for this to work one would need a type dictionary for classes, interfaces, structs, ... where the key is the fully qualified type name.
And also two relations dictionaries, one base->inherited, one inherited->base, where the key is the fully qualified type name, and the value is a list of fully qualified type names. Or one could put both relation-directions in one dictionary.
Anyway, using these dictionaries, one can reduce the types to be rendered, and then in a second pass render only those which remain after the filtering.

Doesn't generate a relation of type 'Composition'

I have tried to generate the code for a Composition but it always display a Association diagram.

For this:

    namespace Composition
    {
        public class SecondClientInstaller
        {
            DBLogger logger = new DBLogger();
        }
    
        public class DBLogger
        {
        }
    
    }

we get
@startuml
class SecondClientInstaller {
}
class DBLogger {
}
SecondClientInstaller --> "logger" DBLogger
@enduml

The console app has net48 but with net5 was the same.

Simple solution to this error?

I honestly do not know what to do about this error. Any one that knows?

A fatal error occurred. The required library libhostfxr.so could not be found.
If this is a self-contained application, that library should exist in [/home/oscar/.dotnet/tools/.store/plantumlclassdiagramgenerator/1.2.4/plantumlclassdiagramgenerator/1.2.4/tools/net5.0/any/].
If this is a framework-dependent application, install the runtime in the global location [/usr/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [/etc/dotnet/install_location].

Just installed vscode plugin...how do I use it?

Just installed vscode plugin...how do I use it?

Can you please include a link to documentation that details how to use the plugin extension in vscode. I have set the input path in the extension plugins. How do I generate the diagram????

[Feature Request] Support for record types

Hi,
I recently tried to incorporate this dotnet tool in my project where I use and target dotnet 5. It seems like the tool doesn't handle records correctly. Whenever I use a record in my source, the output results in an invalid plantuml file.

Consider the following. I've got the following record

    public record ExampleRecord {
      public int AnInt { get; }
      public string AStringValue { get; }
    }

When I pass this through the generator, I get the following PlantUml spec:

+ AnInt : int <<get>>
+ AStringValue : string <<get>>

I would expect record to be handled the same way as classes, at least in the beginning. And by the way the following record notation doesn't output anything at all, which is expected as it's a new notation type that is record specific.

public record ExampleRecord (int AnInt, string AStringValue);

Exception when generating html export

Thanks very much for your project!

When exporting my classdiagram with png, it works fine.
But when exporting html I get the following exception (similar for pdf as well):

Error found in diagram include
java.lang.UnsupportedOperationException: HTML
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.createUGraphic(ImageBuilder.java:444)
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageInternal(ImageBuilder.java:267)
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageTOBEMOVED(ImageBuilder.java:208)
	at net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek.createFileInternal(CucaDiagramFileMakerSvek.java:142)
	at net.sourceforge.plantuml.svek.CucaDiagramFileMakerSvek.createFile(CucaDiagramFileMakerSvek.java:77)
	at net.sourceforge.plantuml.cucadiagram.CucaDiagram.exportDiagramInternal(CucaDiagram.java:651)
	at net.sourceforge.plantuml.classdiagram.ClassDiagram.exportDiagramInternal(ClassDiagram.java:196)
	at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:200)
	at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:140)
	at net.sourceforge.plantuml.SourceStringReader.outputImage(SourceStringReader.java:158)
	at net.sourceforge.plantuml.Pipe.managePipe(Pipe.java:113)
	at net.sourceforge.plantuml.Run.managePipe(Run.java:359)
	at net.sourceforge.plantuml.Run.main(Run.java:166)
Exception in thread "main" java.lang.UnsupportedOperationException: HTML
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.createUGraphic(ImageBuilder.java:444)
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageInternal(ImageBuilder.java:267)
	at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageTOBEMOVED(ImageBuilder.java:208)
	at net.sourceforge.plantuml.UmlDiagram.exportDiagramError(UmlDiagram.java:260)
	at net.sourceforge.plantuml.UmlDiagram.exportDiagramError(UmlDiagram.java:218)
	at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:208)
	at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:140)
	at net.sourceforge.plantuml.SourceStringReader.outputImage(SourceStringReader.java:158)
	at net.sourceforge.plantuml.Pipe.managePipe(Pipe.java:113)
	at net.sourceforge.plantuml.Run.managePipe(Run.java:359)
	at net.sourceforge.plantuml.Run.main(Run.java:166)

Any idea what I am missing?

Feature Request: Create associations with Nullable types

Current state

public record Foo
{
    public IEnumerable<Bar>? Bars { get; set; }
}

public record Bar
{
    // ...
}

generates:

class Foo <<record>> {
    + Bars: IEnumerable<MdmPhoneModel>?
}
class Bar <<record>> {
    ...
}

Desired state

An association from Foo to Bar is created.

All-in-one diagram

At the moment, when generating a diagram including several classes, each .cs file will be mapped to a .puml file and then an "include.puml" file will be created adding them all. This is all good and fine as long as you are not working with ServerRendering, in which case there is no way to see a diagram integrating all diagrams at once. Is there any plans to add an option in order to create a new "all-included" file?

Generating an invalid puml due to the @ prefix

steps to reproduce:

  1. Prepare the source file including the @ prefix

    @startuml
    class @ClassA{
    	    public @IList<@string> @Strings{get;} = new @List<@string>();
    		    public @Type1 @Prop1{get;set;}
    			    public @Type2 @field1;
    }
    
    class @Type1 {
    	    public @int @value1{get;set;}
    }
    
    class @Type2{
    	    public @string @string1{get;set;}
    		    public @ExternalType @Prop2 {get;set;}
    }
    @enduml
  2. Generating .puml with puml-gen

    $ puml-gen .\input.cs -createAssociation
    
    @startuml
    class @ClassA {
    }
    class @Type1 {
    }
    class @Type2 {
    }
    class "@IList`1"<T> {
    }
    @ClassA o-> "@Strings<@string>" "@IList`1"
    @ClassA --> "@Prop1" @Type1
    @ClassA --> "@field1" @Type2
    @Type1 --> "@value1" @int
    @Type2 --> "@string1" @string
    @Type2 --> "@Prop2" @ExternalType
    @enduml
  3. Generating .png with plantuml

    plantuml input.puml
    
  4. The generated .puml contains an error

    Error line 10 in file: input.puml
    Some diagram description contains errors
    

plantuml error due to a string variable containing curly brackets

Perhaps plantuml is causing a parsing error if the {{ }} for the sub-diagram is only on one side.

see also

double opening curly brackets only

input source

class OpeningBracket {
    string str = @"
{{
";
}

puml converted by puml-gen

@startuml
class OpeningBracket {
    str : string = @"
{{
"
}
@enduml

error in plantuml

$ plantuml OpeningBracket.puml
Error line 2 in file: OpeningBracket.puml
Some diagram description contains errors

single closing curly bracket only

input source

class ClosingBracket {
    string str = @"
}
";
}

puml converted by puml-gen

@startuml
class ClosingBracket {
    str : string = @"
}
"
}
@enduml

error in plantuml

$ plantuml ClosingBracket.puml
Error line 5 in file: ClosingBracket.puml
Some diagram description contains errors

VSCode extension not working on Ubuntu 22.04.1 LTS

Problem: when I run the extension via Command Pallete (Ctrl+Shift+P) I don't get the .puml files under the plantuml folder. Actually, I get no output at all even a single error message. I tried it in my laptop with WIndows 11 and it worked fine.

Visual Studio Code version

Version: 1.73.1
Commit: 6261075646f055b99068d3688932416f2346dd3b
Date: 2022-11-09T03:54:53.913Z
Electron: 19.0.17
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Linux x64 5.15.0-53-generic
Sandboxed: No

Ubuntu Version

OS Name: Ubuntu 22.04.1 LTS
OS Type: 64-bit
GNOME Version: 42.5
WIndowing System: Wayland

dotnet version

dotnet --version
7.0.100

Cannot find Graphviz

Hello guys, first, thanks for this project, it's awesome!

I want to generate a plantuml file with all my classes in dotnet core api.

I am getting this error attached. Am I doing something wrong?

image

tks

Use lines instead of List`1

I created a diagram which looked like this:
image
Everything which is connected goes via List'1. Could there be an option to just use lines like:

ClassA --> "0..*" ClassB

Where "0..*" shows it's a list.

Do we have build which will be suitable for 6.0.3?

It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '5.0.0' (x64) was not found.

  • The following frameworks were found:
    6.0.3 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

You can resolve the problem by installing the specified framework and/or SDK.

The specified framework can be found at:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.