Beispiel #1
0
        static void Main(string[] args)
        {
            var fileContents = File.ReadAllText(@"D:\workshop\pitstop\pitstop.analyzed.json");

            Types = JsonConvert.DeserializeObject <List <TypeDescription> >(fileContents, JsonDefaults.DeserializerSettings()).ToList();

            var type = Types.FirstOrDefault("Pitstop.TimeService.Events.DayHasPassed");

            Types.PopulateInheritedBaseTypes();
            Types.PopulateInheritedMembers();

            Console.WriteLine("Base types:");
            foreach (var baseType in type.BaseTypes)
            {
                Console.WriteLine($"- {baseType}");
            }
            Console.WriteLine();

            Console.WriteLine("Fields:");
            foreach (var field in type.Fields)
            {
                Console.WriteLine($"- {field.Name}");
            }

            Console.WriteLine();
            Console.WriteLine("Commands:");
            var commands = Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Command"));

            foreach (var command in commands)
            {
                Console.WriteLine($"- {command.FullName}");
            }

            Console.WriteLine();
            Console.WriteLine("Events:");
            var @events = Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Event"));

            foreach (var @event in @events)
            {
                Console.WriteLine($"- {@event.FullName}");
            }


            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Command Handlers:");
            var commandHandlers = Types
                                  .Where(t => t.IsClass() && t.Methods.Any(m => m.Parameters.Any(p => p.Attributes.Any(a => a.Type.Equals("Microsoft.AspNetCore.Mvc.FromBodyAttribute")))))
                                  .ToDictionary(t => t.FullName, t => t.Methods.Where(m => m.Parameters.Any(p => p.Attributes.Any(a => a.Type.Equals("Microsoft.AspNetCore.Mvc.FromBodyAttribute")))).Select(m => Types.First(m.Parameters.Last().Type).Name).ToList());

            foreach (var kv in commandHandlers)
            {
                Console.WriteLine(kv.Key);

                foreach (var @namespace in kv.Value)
                {
                    Console.WriteLine($"- {@namespace}");
                }

                Console.WriteLine();
            }

            var eventHandlerClasses = Types
                                      .Where(t => t.IsClass() && t.ImplementsType("Pitstop.Infrastructure.Messaging.IMessageHandlerCallback"))
                                      .Where(t => t.Methods.Any(m => m.Name == "HandleAsync" && m.Parameters.Any(p => Types.First(p.Type).ImplementsType("Pitstop.Infrastructure.Messaging.Event"))))
                                      .Select(t => (EventHandlerClass: t, Events: t.Methods.Where(m => m.Name == "HandleAsync" && m.Parameters.Any(p => Types.First(p.Type).ImplementsType("Pitstop.Infrastructure.Messaging.Event"))).Select(m => Types.First(m.Parameters[0].Type).Name).ToList()));

            // Pivot events and handlers
            var query = from ehc in eventHandlerClasses
                        from e in ehc.Events
                        group ehc.EventHandlerClass.Namespace by e into g
                        select g;

            Console.WriteLine();
            Console.WriteLine("Event Receiving Services:");
            foreach (var group in query)
            {
                Console.WriteLine(group.Key);

                foreach (var @namespace in group)
                {
                    Console.WriteLine($"- {@namespace}");
                }

                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine("Trace Statements:");
            var customerController       = Types.First("Pitstop.Application.CustomerManagementAPI.Controllers.CustomersController");
            var handlingMethod           = customerController.Methods.First(m => m.Name == "RegisterAsync" && m.Parameters[0].Type == "Pitstop.CustomerManagementAPI.Commands.RegisterCustomer");
            var messagePublishStatements = handlingMethod.Statements.SelectMany(s => FlattenStatements(s).OfType <InvocationDescription>().Where(s => s.Name == "PublishMessageAsync"));

            foreach (var statement in messagePublishStatements)
            {
                Console.WriteLine($"When a RegisterCustomer command is handled, a {Types.First(statement.Arguments[1].Type).Name} event will be published.");
            }
        }
        static void Main(string[] args)
        {
            var fileContents = File.ReadAllText(@"D:\workshop\pitstop\pitstop.analyzed.json");

            Types = JsonConvert.DeserializeObject <List <TypeDescription> >(fileContents, JsonDefaults.DeserializerSettings()).ToList();

            Types.PopulateInheritedBaseTypes();
            Types.PopulateInheritedMembers();

            var stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("# Pitstop Generated Documentation");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("## Service Architecture");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("![Pitstop solution architecture](https://github.com/EdwinVW/pitstop/wiki/img/solution-architecture.png)");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("## Commands");
            stringBuilder.AppendLine();

            foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Command"))
                     .GroupBy(t => t.Name)
                     .OrderBy(g => g.Key))
            {
                stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}");
                stringBuilder.AppendLine();

                stringBuilder.AppendLine("#### Services");
                stringBuilder.AppendLine();
                foreach (var command in group.OrderBy(c => c.Namespace))
                {
                    stringBuilder.AppendLine($"- {command.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}");
                }
                stringBuilder.AppendLine();

                if (group.SelectMany(t => t.Fields).Any())
                {
                    stringBuilder.AppendLine("#### Fields");
                    stringBuilder.AppendLine();

                    stringBuilder.AppendLine("|Property|Type|Description|");
                    stringBuilder.AppendLine("|-|-|-|");

                    foreach (var field in group.SelectMany(t => t.Fields)
                             .GroupBy(f => (f.Type, f.Name))
                             .Select(g => g.First())
                             .OrderBy(f => f.Name))
                    {
                        stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|");
                    }

                    stringBuilder.AppendLine();

                    var type = group.First();
                    if (Types.CommandHandlerFor(type) != null)
                    {
                        RenderCommandDiagram(stringBuilder, type);
                    }
                    else
                    {
                        stringBuilder.AppendLine("> ❗ No command handler found");
                        stringBuilder.AppendLine();
                    }
                }
            }

            stringBuilder.AppendLine("## Events");
            stringBuilder.AppendLine();

            foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Event"))
                     .GroupBy(t => t.Name)
                     .OrderBy(t => t.Key))
            {
                stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}");
                stringBuilder.AppendLine();

                stringBuilder.AppendLine("#### Services");
                stringBuilder.AppendLine();
                foreach (var @event in group.OrderBy(e => e.Namespace))
                {
                    stringBuilder.AppendLine($"- {@event.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}");
                }

                stringBuilder.AppendLine();

                if (group.SelectMany(t => t.Fields).Any())
                {
                    stringBuilder.AppendLine("#### Fields");
                    stringBuilder.AppendLine();

                    stringBuilder.AppendLine("|Property|Type|Description|");
                    stringBuilder.AppendLine("|-|-|-|");

                    foreach (var field in group.SelectMany(t => t.Fields)
                             .GroupBy(f => (f.Type, f.Name))
                             .Select(g => g.First())
                             .OrderBy(f => f.Name))
                    {
                        stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|");
                    }

                    stringBuilder.AppendLine();
                }
            }

            stringBuilder.AppendLine("## Aggregates");
            stringBuilder.AppendLine();

            foreach (var aggregateRoot in Types.Where(t => t.ImplementsTypeStartsWith("Pitstop.WorkshopManagementAPI.Domain.Core.AggregateRoot<")))
            {
                stringBuilder.AppendLine($"### {aggregateRoot.Name.ToSentenceCase()}");
                stringBuilder.AppendLine();

                var aggregateIDType = Types.First(aggregateRoot.BaseTypes.First(bt => bt.StartsWith("Pitstop.WorkshopManagementAPI.Domain.Core.AggregateRoot<")).GenericTypes().First());

                stringBuilder.AppendLine("```plantuml");
                stringBuilder.UmlDiagramStart();

                RenderClass(stringBuilder, aggregateIDType);

                stringBuilder.AppendLine($"{aggregateIDType.Name} -- {aggregateRoot.Name}");

                RenderClass(stringBuilder, aggregateRoot);

                stringBuilder.UmlDiagramEnd();
                stringBuilder.AppendLine("```");
                stringBuilder.AppendLine();
            }

            File.WriteAllText("pitstop.generated.md", stringBuilder.ToString());
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            var fileContents = File.ReadAllText(@"D:\workshop\pitstop\pitstop.analyzed.json");

            Types = JsonConvert.DeserializeObject <List <TypeDescription> >(fileContents, JsonDefaults.DeserializerSettings()).ToList();

            Types.PopulateInheritedBaseTypes();
            Types.PopulateInheritedMembers();

            var stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("# Pitstop Generated Documentation");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("## Service Architecture");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("![Pitstop solution architecture](https://github.com/EdwinVW/pitstop/wiki/img/solution-architecture.png)");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("## Commands");
            stringBuilder.AppendLine();

            foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Command"))
                     .GroupBy(t => t.Name)
                     .OrderBy(g => g.Key))
            {
                stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}");
                stringBuilder.AppendLine();

                stringBuilder.AppendLine("#### Services");
                stringBuilder.AppendLine();
                foreach (var command in group.OrderBy(c => c.Namespace))
                {
                    stringBuilder.AppendLine($"- {command.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}");
                }
                stringBuilder.AppendLine();

                if (group.SelectMany(t => t.Fields).Any())
                {
                    stringBuilder.AppendLine("#### Fields");
                    stringBuilder.AppendLine();

                    stringBuilder.AppendLine("|Property|Type|Description|");
                    stringBuilder.AppendLine("|-|-|-|");

                    foreach (var field in group.SelectMany(t => t.Fields)
                             .GroupBy(f => (f.Type, f.Name))
                             .Select(g => g.First())
                             .OrderBy(f => f.Name))
                    {
                        stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|");
                    }

                    stringBuilder.AppendLine();
                }
            }

            stringBuilder.AppendLine("## Events");
            stringBuilder.AppendLine();

            foreach (var group in Types.Where(t => t.ImplementsType("Pitstop.Infrastructure.Messaging.Event"))
                     .GroupBy(t => t.Name)
                     .OrderBy(t => t.Key))
            {
                stringBuilder.AppendLine($"### {group.Key.ToSentenceCase()}");
                stringBuilder.AppendLine();

                stringBuilder.AppendLine("#### Services");
                stringBuilder.AppendLine();
                foreach (var @event in group.OrderBy(e => e.Namespace))
                {
                    stringBuilder.AppendLine($"- {@event.Namespace.Split('.').Reverse().Skip(1).First().ToSentenceCase()}");
                }

                stringBuilder.AppendLine();

                if (group.SelectMany(t => t.Fields).Any())
                {
                    stringBuilder.AppendLine("#### Fields");
                    stringBuilder.AppendLine();

                    stringBuilder.AppendLine("|Property|Type|Description|");
                    stringBuilder.AppendLine("|-|-|-|");

                    foreach (var field in group.SelectMany(t => t.Fields)
                             .GroupBy(f => (f.Type, f.Name))
                             .Select(g => g.First())
                             .OrderBy(f => f.Name))
                    {
                        stringBuilder.AppendLine($"|{field.Name}|{field.Type.ForDiagram()}|{field.DocumentationComments?.Summary}|");
                    }

                    stringBuilder.AppendLine();
                }
            }

            File.WriteAllText("pitstop.generated.md", stringBuilder.ToString());
        }