This is the third post in the series: Visualizing ASP.NET Core 3.0 endpoints using GraphvizOnline.

  1. Part 1 - Visualizing endpoints using the DOT language
  2. Part 2 - Adding an endpoint graph to your ASP.NET Core application
  3. Part 3 - Creating a custom DfaGraphWriter using ImpromptuInterface for easier reflection (this post)
  4. Part 4 - Creating a custom endpoint visualization graph
  5. Part 5 - Detecting duplicate routes in ASP.NET Core

In this post I lay the groundwork for creating a custom implementation of DfaGraphWriterDfaGraphWriter is public, so you can use it in your application as I showed in my previous post, but all the classes it uses are marked internal. That makes creating your own version problematic. To work around that, I use an open source reflection library, ImpromptuInterface, to make creating a custom DfaGraphWriter implementation easier.

We’ll start by looking at the existing DfaGraphWriter, to understand the internal classes it uses and the issues that causes us. Then we’ll look at using some custom interfaces and the ImpromptuInterface library to allow us to call those classes. In the next post, we’ll look at how to use our custom interfaces to create a custom version of the DfaGraphWriter.

Exploring the existing DfaGraphWriter

The [DfaGraphWriter](https://github.com/dotnet/aspnetcore/blob/083f81d7604352822820f6313c3d4eb219c044a8/src/Http/Routing/src/Internal/DfaGraphWriter.cs) class lives inside one of the “pubternal” folders in ASP.NET Core. It’s registered as a singleton and uses an injected IServiceProvider to retrieve the helper service, DfaMatcherBuilder:

 public class DfaGraphWriter
{
    private readonly IServiceProvider _services;
    public DfaGraphWriter(IServiceProvider services)
    {
        _services = services;
    }

    public void Write(EndpointDataSource dataSource, TextWriter writer)
    {
        // retrieve the required DfaMatcherBuilder
        var builder = _services.GetRequiredService<DfaMatcherBuilder>();

        // loop through the endpoints in the dataSource, and add them to the builder
        var endpoints = dataSource.Endpoints;
        for (var i = 0; i < endpoints.Count; i++)
        {
            if (endpoints[i] is RouteEndpoint endpoint && (endpoint.Metadata.GetMetadata<ISuppressMatchingMetadata>()?.SuppressMatching ?? false) == false)
            {
                builder.AddEndpoint(endpoint);
            }
        }

        // Build the DfaTree. 
        // This is what we use to create the endpoint graph
        var tree = builder.BuildDfaTree(includeLabel: true);

        // Add the header
        writer.WriteLine("digraph DFA {");

        // Visit each node in the graph to create the output
        tree.Visit(WriteNode);

        //Close the graph
        writer.WriteLine("}");

        // Recursively walks the tree, writing it to the TextWriter
        void WriteNode(DfaNode node)
        {
            // Removed for brevity - we'll explore it in the next post
        }
    }
}

#asp.net core #routing

DfaGraphWriter use ImpromptuInterface:Visualizing ASP.NETCore3.0 use GraphvizOnline-Part 3
1.75 GEEK