# Draw .Net Core project relations with PowerShell and yUML

**Date:** 2017-10-22  
**Author:** Kees C. Bakker  
**Categories:** .NET Core / C#, PowerShell  
**Original:** https://keestalkstech.com/draw-net-core-project-relations-with-powershell-and-yuml/

![Draw .Net Core project relations with PowerShell and yUML](https://keestalkstech.com/wp-content/uploads/2017/10/mike-wilson-113305-e1556137049247.jpg)

---

Having a diagram of how your C# projects interlink, can be a big help. I've created a small *PowerShell* script that will produce the diagram based on the **.csproj** projects and their dependencies in a solution directory. It will generate yUML diagrams like this:

![](https://keestalkstech.com/wp-content/uploads/2018/12/fa70af451.jpg)

## The basic idea

We're taking advantage of the fact that **.csproj** files for .Net Core are XML files. This means they can be queried by **Select-Xml**.

## The script

The following code will open up a browser with the diagram:

```powershell
(ls *.csproj -Recurse -Exclude *test* | % {

    # store for later
    $projectName = $_.BaseName;

    # select project references
    Select-Xml -Path $_.FullName -XPath "//ProjectReference/@Include" |
    Select-Object -Expand Node  |
    Select-Object -Expand '#text' |

    # extract project name for each reference
    Select-String -Pattern '^(.*\\)?(.*?)(.csproj)?$' |
    % { $_.Matches.Groups[2].Value } |

    # create the yUML reference
    % { "[" + $projectName + "]->[" + $_ + "]" }

})  -join "%2C%20" | # join using ", " URL encoded string
% { start -filepath ('http://yuml.me/diagram/plain/class/' + $_) }
```

Pretty cool, right? Thanks to the guys of [yuml.me](https://yuml.me)!

## Listing Nuget packagess

If you like to create a diagram of both project and Nuget packages, you can use the following script (the **Select-Xml** statement is now changed). Note: these diagrams are very large. Some URLs are way too big to start. Handle with care!

```powershell
(ls *.csproj -Recurse -Exclude *test* | % {

    # store for later
    $projectName = $_.BaseName;

    # select project references
    Select-Xml -Path $_.FullName -XPath "//*[self::ProjectReference or self::PackageReference]/@Include" |
    Select-Object -Expand Node  |
    Select-Object -Expand '#text' |

    # extract project name for each reference
    Select-String -Pattern '^(.*\\)?(.*?)(.csproj)?$' |
    % { $_.Matches.Groups[2].Value } |

    # create the yUML reference
    % { "[" + $projectName + "]->[" + $_ + "]" }

})  -join "%2C%20" | # join using ", " URL encoded string
% { start -filepath ('http://yuml.me/diagram/plain/class/' + $_) }
```

The diagram will be way bigger:

![](https://keestalkstech.com/wp-content/uploads/2017/10/ezgif.com-gif-maker.jpg)

The URL that the script generates is: [huuuuuuuuuge](https://yuml.me/diagram/plain/class/[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[Microsoft.ApplicationInsights.AspNetCore]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[Microsoft.AspNetCore]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[Microsoft.AspNetCore.Mvc]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[Microsoft.Extensions.Logging.Debug]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Core]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Shopping]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApi]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalog]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalogGenerator]-%3E[unsplasharp.api]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalogGenerator]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalog]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalogGenerator]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Utilities]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.ApplicationInsights.AspNetCore]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.AspNetCore]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.AspNetCore.Mvc]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.AspNetCore.StaticFiles]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.Extensions.Logging.Debug]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[Microsoft.VisualStudio.Web.BrowserLink]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.WebApp]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.StoreApiClient]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.Shopping]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Core]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalog]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Utilities]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.UnsplashCatalog]-%3E[KeesTalksTech.Assessments.Wehkamp.Store.Core]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApiClient]-%3E[FubarCoder.RestSharp.Portable.Core]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.StoreApiClient]-%3E[FubarCoder.RestSharp.Portable.HttpClient]%2C%20[KeesTalksTech.Assessments.Wehkamp.Store.Utilities]-%3E[System.Xml.XmlSerializer])!

Pretty cool, right? Thanks to the guys of [yuml.me](https://yuml.me)!
