pierre3 / PlantUmlClassDiagramGenerator

This is a generator to create a class-diagram of PlantUML from the C# source code.
MIT License
654 stars 129 forks source link

An option to include class namespaces #24

Open Greven145 opened 4 years ago

Greven145 commented 4 years ago

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
shiena commented 3 years ago

I have tried to implement namespace support.

https://github.com/shiena/PlantUmlClassDiagramGenerator/tree/support-namespace

It works to some extent, but I can't convert the fully qualified type names of the parent class/interface and fields well.

For example, if you convert the following classes

class C0 {}
namespace N1
{
    class C1
    {
        class C2 : C0
        {
            C0 field = new C0();
        }
    }
}

This is the expected output.

@startuml
class C0 {
}
class "C1" as N1.C1 {
}
class "C2" as N1.C1+C2 {
    field : C0
}
C0 <|-- "N1.C1+C2"
N1.C1 +-- "N1.C1+C2"
@enduml

But this is the actual output.

@startuml
class C0 {
}
class "C1" as N1.C1 {
}
class "C2" as N1.C1+C2 {
    'The fully qualified type name of the field is wrong
    field : N1.C1+C0
}
'The fully qualified type name of the parent class is wrong
"N1.C1+C0" <|-- "N1.C1+C2"
N1.C1 +-- "N1.C1+C2"
@enduml

This is because we don't know the name of the fully qualified type of the using class because it is parsed by syntax tree. It may be possible to solve this problem by parsing with a semantic model.

0ge commented 1 year ago

FWIW; if you !include a sub diagram inside a namespace clause, it will assign the imported classes to that namespace. Example:

namespace MyNamespace {
   !include Project/Folder/MyClass.puml
}

I've used it with some success to have the class diagram generator generate all classes (e.g. puml-gen . plantuml/ -dir) and then manually create the diagrams by explicitly including the classes I want in that diagram.