VBUC
Visual Basic Upgrade Companion. VB6 Converter for .NET & Web.

VB6
ASP
RapidScan-LogoDownload Now

WebMAP
Cloud Application Migration Tools Transform Desktop Applications

C#
Silverlight
Access
VB.NET
PowerBuilder
Winforms
ASP.NET Web Forms

SnowConvert
The best available tools to perform code migrations from a source database or Spark application to Snowflake.

Oracle
Spark Scala
Spark Python
SQL Server
Teradata

Get Started
There are countless ways to take advantage of BlackDiamond Studio and SnowConvert.

Migration and Other Snowflake Services
Get Up and Running with Snowpark
Using the SnowConvert Trial
Build a Cross-Platform Object Inventory

Try BlackDiamond Studio

Time to Mobilize
Free Assessment Tool

Visualize DI dependencies in ASP.NET Core DI Container.

by Mauricio Rojas, on Apr 25, 2020 10:43:25 AM

 

I few months ago I took an old VB.NET Winforms up and modernized with WebMAP to ASP.NET Core and Angular. I added some new controllers, integrated swagger, hangfire and some other new stuff.

Everything was working fine and I jumped to some other projects.

After a few months I had to work again in this app. I just needed to add a couple of new controllers.

However I had some problems because I had forgotten a lot about the app, I did not remember all the dependencies in the DI container setup. 

I thought that there should be a way to visualize all  those dependencies. But sadly after a while I could not find one.

So I had to create one for myself.

In the end it was quite easy. I am posting this code in case you find this useful too.

To start, we need a reference to the IServiceCollection object. So if you have an ASP.NET Core app like me just go to your StartUp.cs file.

IServiceCollection _services;

public void ConfigureServices(IServiceCollection services)
{
        _services = services;
         // rest omitted
}

 

Ok, now that you do that you just need to iterate through the service collection. Go to your Configure(IApplicationBuilder app,...) section in Startup.cs and add the following gist:

 

            app.Map("/allservices", builder => builder.Run(async context =>
            {
                var sb = new StringBuilder();
                var dependencies = new Dictionary<string,string>();
                sb.AppendLine("<pre>");
                sb.AppendLine("digraph Services {");
                var services = _services.Select(svc => svc.ServiceType.ToString()).ToHashSet();

                foreach (var svc in _services)
                {
                    var serviceName = svc.ServiceType.ToString();
                    var implementationName = svc.ImplementationType?.ToString();
                    if (implementationName != null)
                    {
                        var implDependencies = svc.ImplementationType.GetConstructors().SelectMany(cons => cons.GetParameters()).Select(p => p.ParameterType.ToString()).Distinct().Where(x => services.Contains(x));
                        if (implDependencies.Count() > 0)
                        {
                            // Register Constructor dependendencies
                            foreach(var d in implDependencies)
                            {
                                dependencies.TryAdd(implementationName, d);
                            }
                        }
                    }
                }
                Action<string, string, string, IEnumerable<string>> printGroup = (label, cluster, color, group) =>
                {
                    if (group.Count() > 0)
                    {
                        sb.AppendLine($"  subgraph cluster_{cluster} {{");
                        sb.AppendLine("      style = filled;");
                        sb.AppendLine($"     color = {color};");
                        sb.AppendLine("      node[style = filled, color = white];");
                        sb.AppendLine($"     label = \"{label}\";");
                        foreach (var item in group)
                        {
                        sb.AppendLine($"     \"{item}\"");
                        }
                        sb.AppendLine("  }");
                    }
                };
                var scopedGroup = _services.Where(s => s.Lifetime == ServiceLifetime.Scoped).Select(s => s.ServiceType.ToString());
                var transientGroup = _services.Where(s => s.Lifetime == ServiceLifetime.Transient).Select(s => s.ServiceType.ToString());
                printGroup("scoped", "0", "blue", scopedGroup);
                printGroup("transient", "1", "lightgrey", transientGroup);
                // Make interfaces different
                sb.AppendLine();
                sb.AppendLine();
                sb.AppendLine("     node [color=green]");
                var interfacesGroup = _services.Where(s => s.ServiceType.IsInterface).Select(s => s.ServiceType.ToString());
                foreach (var @interface in interfacesGroup)
                {
                    sb.AppendLine($"     \"{@interface}\"");
                }
                sb.AppendLine();
                sb.AppendLine("    node [color=black]");
                var noninterfacesGroup = _services.Where(s => !s.ServiceType.IsInterface).Select(s => s.ServiceType.ToString());
                foreach (var nonInterface in noninterfacesGroup)
                {
                    sb.AppendLine($"     \"{nonInterface}\"");
                }
                //Now print dependencies
                foreach (var d in dependencies)
                {
                    sb.AppendLine($"     \"{d.Key}\" -> \"{d.Value}\"");
                }
                sb.AppendLine("}");
                sb.AppendLine("</pre>");
                // Ok ready. Now return all the graph
                await context.Response.WriteAsync(sb.ToString());
            }));

 

With that code in place you can browse to this url:

Screenshot of after the code is in place you should see this and can browse url

Ok now you can go to any website like:

And paste that graph definition:

Screenshot of how to paste the graph definition

Ok, I know it is a little rough but it only took a couple of hours. I hope it helps you if you ever need a way to visualize your DI dependencies like me.

 

Topics:asp.net coreasp.netvb.net

Comments

Subscribe to Mobilize.Net Blog

More...

More...
FREE CODE ASSESSMENT TOOL