static void Main(string[] args)
        {
            Workspace workspace = new Workspace("Contoso University", "A software architecture model of the Contoso University sample project.");
            Model     model     = workspace.Model;
            ViewSet   views     = workspace.Views;
            Styles    styles    = views.Configuration.Styles;

            Person         universityStaff   = model.AddPerson("University Staff", "A staff member of the Contoso University.");
            SoftwareSystem contosoUniversity = model.AddSoftwareSystem("Contoso University", "Allows staff to view and update student, course, and instructor information.");

            universityStaff.Uses(contosoUniversity, "uses");

            // if the client-side of this application was richer (e.g. it was a single-page app), I would include the web browser
            // as a container (i.e. User --uses-> Web Browser --uses-> Web Application (backend for frontend) --uses-> Database)
            Container webApplication = contosoUniversity.AddContainer("Web Application", "Allows staff to view and update student, course, and instructor information.", "Microsoft ASP.NET MVC");
            Container database       = contosoUniversity.AddContainer("Database", "Stores information about students, courses and instructors", "Microsoft SQL Server Express LocalDB");

            database.AddTags("Database");
            universityStaff.Uses(webApplication, "Uses", "HTTPS");
            webApplication.Uses(database, "Reads from and writes to");

            ComponentFinder componentFinder = new ComponentFinder(
                webApplication,
                typeof(ContosoUniversity.MvcApplication).Namespace, // doing this typeof forces the ContosoUniversity assembly to be loaded
                new TypeBasedComponentFinderStrategy(
                    new InterfaceImplementationTypeMatcher(typeof(System.Web.Mvc.IController), null, "ASP.NET MVC Controller"),
                    new ExtendsClassTypeMatcher(typeof(System.Data.Entity.DbContext), null, "Entity Framework DbContext")
                    )
                //new TypeSummaryComponentFinderStrategy(@"C:\Users\simon\ContosoUniversity\ContosoUniversity.sln", "ContosoUniversity")
                );

            componentFinder.FindComponents();

            // connect the user to the web MVC controllers
            webApplication.Components.ToList().FindAll(c => c.Technology == "ASP.NET MVC Controller").ForEach(c => universityStaff.Uses(c, "uses"));

            // connect all DbContext components to the database
            webApplication.Components.ToList().FindAll(c => c.Technology == "Entity Framework DbContext").ForEach(c => c.Uses(database, "Reads from and writes to"));

            // link the components to the source code
            foreach (Component component in webApplication.Components)
            {
                foreach (CodeElement codeElement in component.Code)
                {
                    if (codeElement.Url != null)
                    {
                        codeElement.Url = codeElement.Url.Replace(new Uri(@"C:\Users\simon\ContosoUniversity\").AbsoluteUri, "https://github.com/simonbrowndotje/ContosoUniversity/blob/master/");
                        codeElement.Url = codeElement.Url.Replace('\\', '/');
                    }
                }
            }

            // rather than creating a component model for the database, let's simply link to the DDL
            // (this is really just an example of linking an arbitrary element in the model to an external resource)
            database.Url = "https://github.com/simonbrowndotje/ContosoUniversity/tree/master/ContosoUniversity/Migrations";

            SystemContextView contextView = views.CreateSystemContextView(contosoUniversity, "Context", "The system context view for the Contoso University system.");

            contextView.AddAllElements();

            ContainerView containerView = views.CreateContainerView(contosoUniversity, "Containers", "The containers that make up the Contoso University system.");

            containerView.AddAllElements();

            ComponentView componentView = views.CreateComponentView(webApplication, "Components", "The components inside the Contoso University web application.");

            componentView.AddAllElements();

            // create an example dynamic view for a feature
            DynamicView dynamicView      = views.CreateDynamicView(webApplication, "GetCoursesForDepartment", "A summary of the \"get courses for department\" feature.");
            Component   courseController = webApplication.GetComponentWithName("CourseController");
            Component   schoolContext    = webApplication.GetComponentWithName("SchoolContext");

            dynamicView.Add(universityStaff, "Requests the list of courses from", courseController);
            dynamicView.Add(courseController, "Uses", schoolContext);
            dynamicView.Add(schoolContext, "Gets a list of courses from", database);

            // add some styling
            styles.Add(new ElementStyle(Tags.Person)
            {
                Background = "#0d4d4d", Color = "#ffffff", Shape = Shape.Person
            });
            styles.Add(new ElementStyle(Tags.SoftwareSystem)
            {
                Background = "#003333", Color = "#ffffff"
            });
            styles.Add(new ElementStyle(Tags.Container)
            {
                Background = "#226666", Color = "#ffffff"
            });
            styles.Add(new ElementStyle("Database")
            {
                Shape = Shape.Cylinder
            });
            styles.Add(new ElementStyle(Tags.Component)
            {
                Background = "#407f7f", Color = "#ffffff"
            });

            StructurizrClient structurizrClient = new StructurizrClient("20e54135-adff-4bdf-b684-ff6c3ffc478f", "1c714777-3b06-4e2a-9eb4-35a3648b1592");

            structurizrClient.MergeWorkspace(32431, workspace);
        }
Beispiel #2
0
        private static void Main(string[] args)
        {
            var workspace = new Workspace("Financial Risk System",
                                          "A simple example C4 model based upon the financial risk system architecture kata, created using Structurizr for .NET");
            var model = workspace.Model;

            // create the basic model
            var financialRiskSystem = model.AddSoftwareSystem(Location.Internal, "Financial Risk System",
                                                              "Calculates the bank's exposure to risk for product X");

            var businessUser = model.AddPerson(Location.Internal, "Business User", "A regular business user");

            businessUser.Uses(financialRiskSystem, "Views reports using");

            var configurationUser = model.AddPerson(Location.Internal, "Configuration User",
                                                    "A regular business user who can also configure the parameters used in the risk calculations");

            configurationUser.Uses(financialRiskSystem, "Configures parameters using");

            var tradeDataSystem = model.AddSoftwareSystem(Location.Internal, "Trade Data System",
                                                          "The system of record for trades of type X");

            financialRiskSystem.Uses(tradeDataSystem, "Gets trade data from");

            var referenceDataSystem = model.AddSoftwareSystem(Location.Internal, "Reference Data System",
                                                              "Manages reference data for all counterparties the bank interacts with");

            financialRiskSystem.Uses(referenceDataSystem, "Gets counterparty data from");

            var emailSystem = model.AddSoftwareSystem(Location.Internal, "E-mail system", "Microsoft Exchange");

            financialRiskSystem.Uses(emailSystem, "Sends a notification that a report is ready to");
            emailSystem.Delivers(businessUser, "Sends a notification that a report is ready to", "E-mail message",
                                 InteractionStyle.Asynchronous);

            var centralMonitoringService = model.AddSoftwareSystem(Location.Internal, "Central Monitoring Service",
                                                                   "The bank-wide monitoring and alerting dashboard");

            financialRiskSystem.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP",
                                     InteractionStyle.Asynchronous).AddTags(AlertTag);

            var activeDirectory = model.AddSoftwareSystem(Location.Internal, "Active Directory",
                                                          "Manages users and security roles across the bank");

            financialRiskSystem.Uses(activeDirectory, "Uses for authentication and authorisation");

            var webApplication = financialRiskSystem.AddContainer("Web Application",
                                                                  "Allows users to view reports and modify risk calculation parameters", "ASP.NET MVC");

            businessUser.Uses(webApplication, "Views reports using");
            configurationUser.Uses(webApplication, "Modifies risk calculation parameters using");
            webApplication.Uses(activeDirectory, "Uses for authentication and authorisation");

            var batchProcess = financialRiskSystem.AddContainer("Batch Process", "Calculates the risk",
                                                                "Windows Service");

            batchProcess.Uses(emailSystem, "Sends a notification that a report is ready to");
            batchProcess.Uses(tradeDataSystem, "Gets trade data from");
            batchProcess.Uses(referenceDataSystem, "Gets counterparty data from");
            batchProcess.Uses(centralMonitoringService, "Sends critical failure alerts to", "SNMP",
                              InteractionStyle.Asynchronous).AddTags(AlertTag);

            var fileSystem = financialRiskSystem.AddContainer("File System", "Stores risk reports", "Network File Share");

            webApplication.Uses(fileSystem, "Consumes risk reports from");
            batchProcess.Uses(fileSystem, "Publishes risk reports to");

            var scheduler = batchProcess.AddComponent("Scheduler",
                                                      "Starts the risk calculation process at 5pm New York time", "Quartz.NET");
            var orchestrator = batchProcess.AddComponent("Orchestrator", "Orchestrates the risk calculation process",
                                                         "C#");
            var tradeDataImporter = batchProcess.AddComponent("Trade data importer",
                                                              "Imports data from the Trade Data System", "C#");
            var referenceDataImporter = batchProcess.AddComponent("Reference data importer",
                                                                  "Imports data from the Reference Data System", "C#");
            var riskCalculator  = batchProcess.AddComponent("Risk calculator", "Calculates risk", "C#");
            var reportGenerator = batchProcess.AddComponent("Report generator",
                                                            "Generates a Microsoft Excel compatible risk report", "C# and Microsoft.Office.Interop.Excel");
            var reportPublisher = batchProcess.AddComponent("Report distributor",
                                                            "Publishes the report to the web application", "C#");
            var emailComponent = batchProcess.AddComponent("E-mail component", "Sends e-mails", "C#");
            var reportChecker  = batchProcess.AddComponent("Report checker",
                                                           "Checks that the report has been generated by 9am singapore time", "C#");
            var alertComponent = batchProcess.AddComponent("Alert component", "Sends SNMP alerts",
                                                           "C# and #SNMP Library");

            scheduler.Uses(orchestrator, "Starts");
            scheduler.Uses(reportChecker, "Starts");
            orchestrator.Uses(tradeDataImporter, "Imports data using");
            tradeDataImporter.Uses(tradeDataSystem, "Imports data from");
            orchestrator.Uses(referenceDataImporter, "Imports data using");
            referenceDataImporter.Uses(referenceDataSystem, "Imports data from");
            orchestrator.Uses(riskCalculator, "Calculates the risk using");
            orchestrator.Uses(reportGenerator, "Generates the risk report using");
            orchestrator.Uses(reportPublisher, "Publishes the risk report using");
            reportPublisher.Uses(fileSystem, "Publishes the risk report to");
            orchestrator.Uses(emailComponent, "Sends e-mail using");
            emailComponent.Uses(emailSystem, "Sends a notification that a report is ready to");
            reportChecker.Uses(alertComponent, "Sends alerts using");
            alertComponent.Uses(centralMonitoringService, "Sends alerts using", "SNMP", InteractionStyle.Asynchronous)
            .AddTags(AlertTag);

            // create some views
            var viewSet     = workspace.Views;
            var contextView = viewSet.CreateContextView(financialRiskSystem);

            contextView.PaperSize = PaperSize.A4_Landscape;
            contextView.AddAllSoftwareSystems();
            contextView.AddAllPeople();

            var containerView = viewSet.CreateContainerView(financialRiskSystem);

            contextView.PaperSize = PaperSize.A4_Landscape;
            containerView.AddAllElements();

            var componentViewForBatchProcess = viewSet.CreateComponentView(batchProcess);

            contextView.PaperSize = PaperSize.A3_Landscape;
            componentViewForBatchProcess.AddAllElements();
            componentViewForBatchProcess.Remove(configurationUser);
            componentViewForBatchProcess.Remove(webApplication);
            componentViewForBatchProcess.Remove(activeDirectory);

            // tag and style some elements
            var styles = viewSet.Configuration.Styles;

            financialRiskSystem.AddTags("Risk System");

            styles.Add(new ElementStyle(Tags.Element)
            {
                Color = "#ffffff", FontSize = 34
            });
            styles.Add(new ElementStyle("Risk System")
            {
                Background = "#8a458a"
            });
            styles.Add(new ElementStyle(Tags.SoftwareSystem)
            {
                Width      = 650,
                Height     = 400,
                Background = "#510d51",
                //Shape = Shape.Box
            });
            styles.Add(new ElementStyle(Tags.Person)
            {
                Width      = 550,
                Background = "#62256e",
                //Shape = Shape.Person
            });
            styles.Add(new ElementStyle(Tags.Container)
            {
                Width      = 650,
                Height     = 400,
                Background = "#a46ba4",
                //Shape = Shape.Box
            });
            styles.Add(new ElementStyle(Tags.Component)
            {
                Width      = 550,
                Background = "#c9a1c9",
                //Shape = Shape.Box
            });

            styles.Add(new RelationshipStyle(Tags.Relationship)
            {
                Thickness = 4,
                Dashed    = false,
                FontSize  = 32,
                Width     = 400
            });
            styles.Add(new RelationshipStyle(Tags.Synchronous)
            {
                Dashed = false
            });
            styles.Add(new RelationshipStyle(Tags.Asynchronous)
            {
                Dashed = true
            });
            styles.Add(new RelationshipStyle(AlertTag)
            {
                Color = "#ff0000"
            });

            businessUser.Relationships.ToList().ForEach(r => r.AddTags("HTTPS"));

            // and upload the model to structurizr.com
            var structurizrClient = new StructurizrClient("4fd23f21-0139-4fb3-b832-22a1fc8b8d83", "d439618a-336d-4c37-b6fe-20c0846ffbd9");

            //structurizrClient.PutWorkspace(9861L, workspace);
            structurizrClient.MergeWorkspace(9861L, workspace);
        }