├── .gitattributes
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── Structurizr.Client.Tests
├── Api
│ ├── Md5DigestTests.cs
│ └── StructurizrClientTests.cs
├── Encryption
│ ├── AesEncryptionStrategyTests.cs
│ ├── EncryptedWorkspaceTests.cs
│ └── MockEncryptionStrategy.cs
├── IO
│ └── JsonReaderTests.cs
├── Structurizr.Client.Tests.csproj
└── TestFailedException.cs
├── Structurizr.Client
├── Api
│ ├── ApiResponse.cs
│ ├── HashBasedMessageAuthenticationCode.cs
│ ├── HmacAuthorizationHeader.cs
│ ├── HmacContent.cs
│ ├── HttpHeaders.cs
│ ├── Md5Digest.cs
│ ├── StructurizrClient.cs
│ └── StructurizrClientException.cs
├── AssemblyInfo.cs
├── Encryption
│ ├── AesEncryptionStrategy.cs
│ ├── EncryptedJsonReader.cs
│ ├── EncryptedJsonWriter.cs
│ ├── EncryptedWorkspace.cs
│ └── EncryptionStrategy.cs
├── IO
│ └── Json
│ │ ├── EncryptionStrategyJsonConverter.cs
│ │ ├── JsonReader.cs
│ │ ├── JsonWriter.cs
│ │ └── PaperSizeJsonConverter.cs
├── Structurizr.Client.csproj
└── Util
│ └── WorkspaceUtils.cs
├── Structurizr.Core.Tests
├── AbstractTestBase.cs
├── Config
│ └── WorkspaceConfigurationTests.cs
├── Documentation
│ ├── Arc42DocumentationTests.cs
│ ├── DocumentationTemplateTests.cs
│ ├── DocumentationTests.cs
│ ├── FormatFinderTests.cs
│ ├── SectionTests.cs
│ ├── StructurizrDocumentationTests.cs
│ ├── ViewpointsAndPerspectivesDocumentationTests.cs
│ ├── arc42
│ │ ├── architectural-decisions.md
│ │ ├── building-block-view.md
│ │ ├── constraints.md
│ │ ├── context-and-scope.md
│ │ ├── crosscutting-concepts.md
│ │ ├── deployment-view.md
│ │ ├── glossary.md
│ │ ├── introduction-and-goals.md
│ │ ├── quality-requirements.md
│ │ ├── risks-and-technical-debt.md
│ │ ├── runtime-view.md
│ │ └── solution-strategy.md
│ ├── example.md
│ ├── image.gif
│ ├── image.jpeg
│ ├── image.jpg
│ ├── image.png
│ ├── images
│ │ ├── image.gif
│ │ ├── image.jpeg
│ │ ├── image.jpg
│ │ └── image.png
│ ├── markdown
│ │ ├── 1.md
│ │ └── subdirectory
│ │ │ └── 2.md
│ ├── noimages
│ │ └── readme.md
│ ├── structurizr
│ │ ├── code-for-componentA1.md
│ │ ├── code-for-componentA2.md
│ │ ├── components-for-containerA.md
│ │ ├── components-for-containerB.md
│ │ ├── constraints.md
│ │ ├── containers.md
│ │ ├── context.md
│ │ ├── data.md
│ │ ├── decision-log.md
│ │ ├── deployment.md
│ │ ├── development-environment.md
│ │ ├── functional-overview.md
│ │ ├── infrastructure-architecture.md
│ │ ├── operation-and-support.md
│ │ ├── principles.md
│ │ ├── quality-attributes.md
│ │ └── software-architecture.md
│ └── viewpointsandperspectives
│ │ ├── 01-introduction.md
│ │ ├── 02-glossary.md
│ │ ├── 03-system-stakeholders-and-requirements.md
│ │ ├── 04-architectural-forces.md
│ │ ├── 05-architectural-views.md
│ │ ├── 06-system-qualities.md
│ │ └── 07-appendices.adoc
├── Model
│ ├── CodeElementTests.cs
│ ├── ComponentTests.cs
│ ├── ContainerInstanceTests.cs
│ ├── ContainerTests.cs
│ ├── CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategyTests.cs
│ ├── CreateImpliedRelationshipsUnlessSameRelationshipExistsStrategyTests.cs
│ ├── DeploymentNodeTests.cs
│ ├── ElementTests.cs
│ ├── GroupableElementTests.cs
│ ├── HttpHealthCheckTests.cs
│ ├── ModelItemTests.cs
│ ├── ModelTests.cs
│ ├── PersonTests.cs
│ ├── RelationshipTests.cs
│ └── SoftwareSystemInstanceTests.cs
├── Structurizr.Core.Tests.csproj
├── TestFailedException.cs
├── Util
│ ├── ImageUtilTests.cs
│ ├── UrlTests.cs
│ ├── readme.txt
│ └── structurizr-logo.png
├── View
│ ├── AutomaticLayoutTests.cs
│ ├── BrandingTests.cs
│ ├── ColorPairTests.cs
│ ├── ColorTests.cs
│ ├── ComponentViewTests.cs
│ ├── ConfigurationTests.cs
│ ├── ContainerViewTests.cs
│ ├── DefaultLayoutMergeStrategyTests.cs
│ ├── DeploymentViewTests.cs
│ ├── DimensionsTests.cs
│ ├── DynamicViewTests.cs
│ ├── ElementStyleTests.cs
│ ├── FilteredViewTests.cs
│ ├── FontTests.cs
│ ├── RelationshipStyleTests.cs
│ ├── SequenceCounterTests.cs
│ ├── SequenceNumberTests.cs
│ ├── StaticViewTests.cs
│ ├── StyleTests.cs
│ ├── SystemContextViewTests.cs
│ ├── SystemLandscapeViewTests.cs
│ └── ViewTests.cs
└── WorkspaceTests.cs
├── Structurizr.Core
├── AbstractWorkspace.cs
├── AssemblyInfo.cs
├── Config
│ ├── Role.cs
│ ├── User.cs
│ └── WorkspaceConfiguration.cs
├── Documentation
│ ├── Arc42DocumentationTemplate.cs
│ ├── Decision.cs
│ ├── DecisionStatus.cs
│ ├── Documentation.cs
│ ├── DocumentationTemplate.cs
│ ├── Format.cs
│ ├── FormatFinder.cs
│ ├── FormattedContent.cs
│ ├── Image.cs
│ ├── Section.cs
│ ├── StructurizrDocumentationTemplate.cs
│ └── ViewpointsAndPerspectivesDocumentationTemplate.cs
├── Model
│ ├── AbstractImpliedRelationshipsStrategy.cs
│ ├── CanonicalNameGenerator.cs
│ ├── CodeElement.cs
│ ├── CodeElementRole.cs
│ ├── Component.cs
│ ├── Container.cs
│ ├── ContainerInstance.cs
│ ├── CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy.cs
│ ├── CreateImpliedRelationshipsUnlessSameRelationshipExistsStrategy.cs
│ ├── DefaultImpliedRelationshipsStrategy.cs
│ ├── DeploymentElement.cs
│ ├── DeploymentNode.cs
│ ├── Element.cs
│ ├── Enterprise.cs
│ ├── GroupableElement.cs
│ ├── HttpHealthCheck.cs
│ ├── IdGenerator.cs
│ ├── ImpliedRelationshipsStrategy.cs
│ ├── InfrastructureNode.cs
│ ├── InteractionStyle.cs
│ ├── Location.cs
│ ├── Model.cs
│ ├── ModelItem.cs
│ ├── Person.cs
│ ├── Perspective.cs
│ ├── Relationship.cs
│ ├── SequentialIntegerIdGeneratorStrategy.cs
│ ├── SoftwareSystem.cs
│ ├── SoftwareSystemInstance.cs
│ ├── StaticStructureElement.cs
│ ├── StaticStructureElementInstance.cs
│ └── Tags.cs
├── Structurizr.Core.csproj
├── Util
│ ├── DictionaryUtils.cs
│ ├── ImageUtils.cs
│ └── Url.cs
├── View
│ ├── Animation.cs
│ ├── AutomaticLayout.cs
│ ├── Border.cs
│ ├── Branding.cs
│ ├── Color.cs
│ ├── ColorPair.cs
│ ├── ComponentView.cs
│ ├── ContainerView.cs
│ ├── DefaultLayoutMergeStrategy.cs
│ ├── DeploymentView.cs
│ ├── Dimensions.cs
│ ├── DynamicView.cs
│ ├── ElementNotPermittedInViewException.cs
│ ├── ElementStyle.cs
│ ├── ElementView.cs
│ ├── FilterMode.cs
│ ├── FilteredView.cs
│ ├── Font.cs
│ ├── LayoutMergeStrategy.cs
│ ├── MetadataSymbols.cs
│ ├── PaperSize.cs
│ ├── ParallelSequenceCounter.cs
│ ├── RankDirection.cs
│ ├── RelationshipStyle.cs
│ ├── RelationshipView.cs
│ ├── Routing.cs
│ ├── SequenceCounter.cs
│ ├── SequenceNumber.cs
│ ├── Shape.cs
│ ├── StaticView.cs
│ ├── Styles.cs
│ ├── SystemContextView.cs
│ ├── SystemLandscapeView.cs
│ ├── Terminology.cs
│ ├── Vertex.cs
│ ├── View.cs
│ ├── ViewConfiguration.cs
│ ├── ViewSet.cs
│ └── ViewSortOrder.cs
└── Workspace.cs
├── Structurizr.Examples
├── AmazonWebServicesExample.cs
├── Arc42DocumentationExample.cs
├── BigBankPlc.cs
├── ClientSideEncryption.cs
├── CorporateBranding.cs
├── Documentation
│ ├── adr
│ │ ├── 0001-record-architecture-decisions.md
│ │ ├── 0002-implement-as-shell-scripts.md
│ │ ├── 0003-single-command-with-subcommands.md
│ │ ├── 0004-markdown-format.md
│ │ ├── 0005-help-comments.md
│ │ ├── 0006-packaging-and-distribution-in-other-version-control-repositories.md
│ │ ├── 0007-invoke-adr-config-executable-to-get-configuration.md
│ │ └── 0008-use-iso-8601-format-for-dates.md
│ ├── arc42
│ │ ├── asciidoc
│ │ │ ├── 01-introduction-and-goals.adoc
│ │ │ ├── 02-architecture-constraints.adoc
│ │ │ ├── 03-system-scope-and-context.adoc
│ │ │ ├── 04-solution-strategy.adoc
│ │ │ ├── 05-building-block-view.adoc
│ │ │ ├── 06-runtime-view.adoc
│ │ │ ├── 07-deployment-view.adoc
│ │ │ ├── 08-crosscutting-concepts.adoc
│ │ │ ├── 09-architecture-decisions.adoc
│ │ │ ├── 10-quality-requirements.adoc
│ │ │ ├── 11-risks-and-technical-debt.adoc
│ │ │ └── 12-glossary.adoc
│ │ └── markdown
│ │ │ ├── 01-introduction-and-goals.md
│ │ │ ├── 02-architecture-constraints.md
│ │ │ ├── 03-system-scope-and-context.md
│ │ │ ├── 04-solution-strategy.md
│ │ │ ├── 05-building-block-view.md
│ │ │ ├── 06-runtime-view.md
│ │ │ ├── 07-deployment-view.md
│ │ │ ├── 08-crosscutting-concepts.md
│ │ │ ├── 09-architecture-decisions.md
│ │ │ ├── 10-quality-requirements.md
│ │ │ ├── 11-risks-and-technical-debt.md
│ │ │ └── 12-glossary.md
│ ├── structurizr
│ │ ├── asciidoc
│ │ │ ├── 01-context.adoc
│ │ │ ├── 02-functional-overview.adoc
│ │ │ ├── 03-quality-attributes.adoc
│ │ │ ├── 04-constraints.adoc
│ │ │ ├── 05-principles.adoc
│ │ │ ├── 06-software-architecture.adoc
│ │ │ ├── 07-data.adoc
│ │ │ ├── 08-infrastructure-architecture.adoc
│ │ │ ├── 09-deployment.adoc
│ │ │ ├── 10-development-environment.adoc
│ │ │ ├── 11-operation-and-support.adoc
│ │ │ └── 12-decision-log.adoc
│ │ └── markdown
│ │ │ ├── 01-context.md
│ │ │ ├── 02-functional-overview.md
│ │ │ ├── 03-quality-attributes.md
│ │ │ ├── 04-constraints.md
│ │ │ ├── 05-principles.md
│ │ │ ├── 06-software-architecture.md
│ │ │ ├── 07-data.md
│ │ │ ├── 08-infrastructure-architecture.md
│ │ │ ├── 09-deployment.md
│ │ │ ├── 10-development-environment.md
│ │ │ ├── 11-operation-and-support.md
│ │ │ └── 12-decision-log.md
│ └── viewpointsandperspectives
│ │ ├── asciidoc
│ │ ├── 01-introduction.adoc
│ │ ├── 02-glossary.adoc
│ │ ├── 03-system-stakeholders-and-requirements.adoc
│ │ ├── 04-architectural-forces.adoc
│ │ ├── 05-architectural-views
│ │ │ ├── 01-architectural-views.adoc
│ │ │ ├── 02-context-view.adoc
│ │ │ ├── 03-functional-view.adoc
│ │ │ ├── 04-information-view.adoc
│ │ │ ├── 05-concurrency-view.adoc
│ │ │ ├── 06-deployment-view.adoc
│ │ │ ├── 07-development-view.adoc
│ │ │ └── 08-operational-view.adoc
│ │ ├── 06-system-qualities.adoc
│ │ └── 07-appendices.adoc
│ │ └── markdown
│ │ ├── 01-introduction.md
│ │ ├── 02-glossary.md
│ │ ├── 03-system-stakeholders-and-requirements.md
│ │ ├── 04-architectural-forces.md
│ │ ├── 05-architectural-views
│ │ ├── 01-architectural-views.md
│ │ ├── 02-context-view.md
│ │ ├── 03-functional-view.md
│ │ ├── 04-information-view.md
│ │ ├── 05-concurrency-view.md
│ │ ├── 06-deployment-view.md
│ │ ├── 07-development-view.md
│ │ └── 08-operational-view.md
│ │ ├── 06-system-qualities.md
│ │ └── 07-appendices.md
├── FilteredViews.cs
├── FinancialRiskSystem.cs
├── FinancialRiskSystem
│ ├── context.adoc
│ ├── context.md
│ ├── functional-overview.md
│ ├── images
│ │ └── functional-overview.png
│ └── quality-attributes.md
├── GettingStarted.cs
├── HttpHealthChecks.cs
├── MicroservicesExample.cs
├── Structurizr.Examples.csproj
├── StructurizrDocumentationExample.cs
├── StylingElements.cs
├── StylingRelationships.cs
├── Theme.cs
├── Theme
│ └── theme.json
├── ViewpointsAndPerspectivesDocumentationExample.cs
├── WidgetsLimited.cs
└── structurizr-logo.png
├── Structurizr.sln
├── appveyor.yml
├── docs
├── api-client.md
├── binaries.md
├── changelog.md
├── client-side-encryption.md
├── component-diagram.md
├── container-diagram.md
├── corporate-branding.md
├── deployment-diagram.md
├── documentation-arc42.md
├── documentation-structurizr.md
├── documentation-viewpoints-and-perspectives.md
├── documentation.md
├── dynamic-diagram.md
├── faq.md
├── filtered-views.md
├── getting-started.md
├── health-checks.md
├── images
│ ├── basic-concepts.png
│ ├── component-diagram-1.png
│ ├── container-diagram-1.png
│ ├── corporate-branding-1.png
│ ├── corporate-branding-2.png
│ ├── corporate-branding-3.png
│ ├── corporate-branding-4.png
│ ├── deployment-diagram-1.png
│ ├── documentation-1.png
│ ├── documentation-2.png
│ ├── documentation-3.png
│ ├── dynamic-diagram-1.png
│ ├── filtered-views-1.png
│ ├── filtered-views-2.png
│ ├── getting-started-1.png
│ ├── getting-started-2.png
│ ├── getting-started-diagram-key.png
│ ├── implied-relationships-1.png
│ ├── readme-1.png
│ ├── structurizr-banner.png
│ ├── structurizr-overview.png
│ ├── styling-elements-1.png
│ ├── styling-elements-2.png
│ ├── styling-elements-3.png
│ ├── styling-elements-4.png
│ ├── styling-elements-5.png
│ ├── styling-elements-6.png
│ ├── styling-relationships-1.png
│ ├── styling-relationships-2.png
│ ├── styling-relationships-3.png
│ ├── styling-relationships-4.png
│ ├── system-context-diagram-1.png
│ └── system-landscape-diagram-1.png
├── implied-relationships.md
├── model.md
├── nuget.md
├── styling-elements.md
├── styling-relationships.md
├── system-context-diagram.md
├── system-landscape-diagram.md
├── usage-patterns.md
└── views.md
└── nuget.bat
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Explicitly declare text files you want to always be normalized and converted
5 | # to native line endings on checkout.
6 | #*.ts text
7 |
8 | # Shell scripts should always have lf line endings
9 | *.sh text eol=lf
10 | sources.list text eol=lf
11 |
12 | #### Visual Studio specific stuff
13 |
14 | ###############################################################################
15 | # Set default behavior for command prompt diff.
16 | #
17 | # This is need for earlier builds of msysgit that does not have it on by
18 | # default for csharp files.
19 | # Note: This is only used by command line
20 | ###############################################################################
21 | *.cs diff=csharp
22 |
23 | ###############################################################################
24 | # Set the merge driver for project and solution files
25 | #
26 | # Merging from the command prompt will add diff markers to the files if there
27 | # are conflicts (Merging from VS is not affected by the settings below, in VS
28 | # the diff markers are never inserted). Diff markers may cause the following
29 | # file extensions to fail to load in VS. An alternative would be to treat
30 | # these files as binary and thus will always conflict and require user
31 | # intervention with every merge. To do so, just comment the entries below and
32 | # uncomment the group further below
33 | ###############################################################################
34 | *.sln text eol=crlf
35 | *.csproj text eol=crlf
36 | *.vbproj text eol=crlf
37 | *.vcxproj text eol=crlf
38 | *.vcproj text eol=crlf
39 | *.dbproj text eol=crlf
40 | *.fsproj text eol=crlf
41 | *.lsproj text eol=crlf
42 | *.wixproj text eol=crlf
43 | *.modelproj text eol=crlf
44 | *.sqlproj text eol=crlf
45 | *.wmaproj text eol=crlf
46 |
47 | *.xproj text eol=crlf
48 | *.props text eol=crlf
49 | *.filters text eol=crlf
50 | *.vcxitems text eol=crlf
51 |
52 | *.sln merge=binary
53 | *.csproj merge=binary
54 | *.vbproj merge=binary
55 | *.vcxproj merge=binary
56 | *.vcproj merge=binary
57 | *.dbproj merge=binary
58 | *.fsproj merge=binary
59 | *.lsproj merge=binary
60 | *.wixproj merge=binary
61 | *.modelproj merge=binary
62 | *.sqlproj merge=binary
63 | *.wmaproj merge=binary
64 |
65 | *.xproj merge=binary
66 | *.props merge=binary
67 | *.filters merge=binary
68 | *.vcxitems merge=binary
69 |
70 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | solution: Structurizr.sln
3 |
--------------------------------------------------------------------------------
/Structurizr.Client.Tests/Api/Md5DigestTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Api.Tests
4 | {
5 |
6 | public class Md5DigestTests
7 | {
8 |
9 | private Md5Digest md5 = new Md5Digest();
10 |
11 | [Fact]
12 | public void Test_Generate_TreatsNullAsEmptyContent()
13 | {
14 | Assert.Equal(md5.Generate(""), md5.Generate(null));
15 | }
16 |
17 | [Fact]
18 | public void Test_Generate_WorksForUTF8CharacterEncoding()
19 | {
20 | Assert.Equal("0a35e149dbbb2d10d744bf675c7744b1", md5.Generate("è"));
21 | }
22 |
23 | [Fact]
24 | public void Test_Generate()
25 | {
26 | Assert.Equal("ed076287532e86365e841e92bfc50d8c", md5.Generate("Hello World!"));
27 | Assert.Equal("d41d8cd98f00b204e9800998ecf8427e", md5.Generate(""));
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Structurizr.Client.Tests/Encryption/MockEncryptionStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Structurizr.Encryption;
3 |
4 | namespace Structurizr.Api.Encryption.Tests
5 | {
6 | internal class MockEncryptionStrategy : EncryptionStrategy
7 | {
8 | public override string Type { get; }
9 |
10 | public override string Encrypt(string plaintext)
11 | {
12 | var array = plaintext.ToCharArray();
13 | Array.Reverse(array);
14 | return new string(array);
15 | }
16 |
17 | public override string Decrypt(string ciphertext)
18 | {
19 | var array = ciphertext.ToCharArray();
20 | Array.Reverse(array);
21 | return new string(array);
22 | }
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/Structurizr.Client.Tests/Structurizr.Client.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | false
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Structurizr.Client.Tests/TestFailedException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr.Api.Tests
4 | {
5 | public class TestFailedException : Exception
6 | {
7 |
8 | public TestFailedException()
9 | {
10 | }
11 |
12 | public TestFailedException(string message) : base(message)
13 | {
14 | }
15 |
16 | }
17 | }
--------------------------------------------------------------------------------
/Structurizr.Client/Api/ApiResponse.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Converters;
3 | using System.Collections.Generic;
4 | using System.Runtime.Serialization;
5 |
6 | namespace Structurizr.Api
7 | {
8 |
9 | [DataContract]
10 | internal sealed class ApiResponse
11 | {
12 |
13 | [DataMember(Name = "success", EmitDefaultValue = false)]
14 | internal bool Success;
15 |
16 | [DataMember(Name = "message", EmitDefaultValue = false)]
17 | internal string Message;
18 |
19 | [DataMember(Name = "revision", EmitDefaultValue = false)]
20 | internal long? Revision;
21 |
22 | static internal ApiResponse Parse(string json)
23 | {
24 | JsonSerializerSettings settings = new JsonSerializerSettings()
25 | {
26 | ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
27 | Converters = new List {
28 | new IsoDateTimeConverter()
29 | }
30 | };
31 |
32 | ApiResponse apiResponse = JsonConvert.DeserializeObject(json, settings);
33 | return apiResponse;
34 | }
35 |
36 | }
37 | }
--------------------------------------------------------------------------------
/Structurizr.Client/Api/HashBasedMessageAuthenticationCode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using System.Text;
4 |
5 | namespace Structurizr.Api
6 | {
7 | internal class HashBasedMessageAuthenticationCode
8 | {
9 |
10 | private string apiSecret;
11 |
12 | internal HashBasedMessageAuthenticationCode(string apiSecret)
13 | {
14 | this.apiSecret = apiSecret;
15 | }
16 |
17 | public string Generate(string content)
18 | {
19 | HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret));
20 | byte[] bytes = Encoding.UTF8.GetBytes(content);
21 | byte[] hash = hmac.ComputeHash(bytes);
22 |
23 | return BitConverter.ToString(hash).Replace("-", "").ToLower();
24 | }
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Structurizr.Client/Api/HmacAuthorizationHeader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace Structurizr.Api
5 | {
6 | internal class HmacAuthorizationHeader
7 | {
8 |
9 | private string apiKey;
10 | private string hmac;
11 |
12 | public HmacAuthorizationHeader(string apiKey, string hmac)
13 | {
14 | this.apiKey = apiKey;
15 | this.hmac = hmac;
16 | }
17 |
18 | public override string ToString()
19 | {
20 | return apiKey + ":" + Convert.ToBase64String(Encoding.UTF8.GetBytes(hmac));
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Structurizr.Client/Api/HmacContent.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Structurizr.Api
4 | {
5 | internal class HmacContent
6 | {
7 |
8 | private string[] strings;
9 |
10 | internal HmacContent(params string[] strings)
11 | {
12 | this.strings = strings;
13 | }
14 |
15 | public override string ToString()
16 | {
17 | StringBuilder buf = new StringBuilder();
18 | foreach (string s in strings)
19 | {
20 | buf.Append(s);
21 | buf.Append("\n");
22 | }
23 |
24 | return buf.ToString();
25 | }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Structurizr.Client/Api/HttpHeaders.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Api
2 | {
3 | internal class HttpHeaders
4 | {
5 |
6 | internal const string UserAgent = "User-Agent";
7 | internal const string Authorization = "Authorization";
8 | internal const string XAuthorization = "X-Authorization";
9 | internal const string ContentType = "Content-Type";
10 | internal const string ContentMd5 = "Content-MD5";
11 | internal const string Nonce = "Nonce";
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Structurizr.Client/Api/Md5Digest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using System.Text;
4 |
5 | namespace Structurizr.Api
6 | {
7 | internal class Md5Digest
8 | {
9 |
10 | internal string Generate(string content)
11 | {
12 | if (content == null)
13 | {
14 | content = "";
15 | }
16 |
17 | MD5 md5 = MD5.Create();
18 | byte[] textToHash = Encoding.UTF8.GetBytes(content);
19 | byte[] result = md5.ComputeHash(textToHash);
20 |
21 | return BitConverter.ToString(result).Replace("-", "").ToLower();
22 | }
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Structurizr.Client/Api/StructurizrClientException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr.Api
4 | {
5 | public class StructurizrClientException : Exception
6 | {
7 |
8 | public StructurizrClientException(String message) : base(message) { }
9 |
10 | public StructurizrClientException(String message, Exception innerException) : base(message, innerException) { }
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Structurizr.Client/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Structurizr.Client.Tests")]
2 |
3 | namespace Structurizr.Api
4 | {
5 | public class AssemblyInfo
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/Structurizr.Client/Encryption/EncryptedJsonReader.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Structurizr.IO.Json;
3 | using System.IO;
4 |
5 | namespace Structurizr.Encryption
6 | {
7 | public class EncryptedJsonReader
8 | {
9 |
10 | public EncryptedWorkspace Read(StringReader reader)
11 | {
12 | EncryptedWorkspace workspace = JsonConvert.DeserializeObject(
13 | reader.ReadToEnd(),
14 | new Newtonsoft.Json.Converters.StringEnumConverter(),
15 | new PaperSizeJsonConverter(),
16 | new EncryptionStrategyJsonConverter());
17 |
18 | return workspace;
19 | }
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Structurizr.Client/Encryption/EncryptedJsonWriter.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Structurizr.IO.Json;
3 | using System.IO;
4 |
5 | namespace Structurizr.Encryption
6 | {
7 | public class EncryptedJsonWriter
8 | {
9 |
10 | public bool IndentOutput { get; set; }
11 |
12 | public EncryptedJsonWriter(bool indentOutput)
13 | {
14 | this.IndentOutput = indentOutput;
15 | }
16 |
17 | public void Write(EncryptedWorkspace workspace, StringWriter writer)
18 | {
19 | string json = JsonConvert.SerializeObject(workspace,
20 | IndentOutput == true ? Formatting.Indented : Formatting.None,
21 | new Newtonsoft.Json.Converters.StringEnumConverter(),
22 | new PaperSizeJsonConverter());
23 |
24 | writer.WriteLine(json);
25 | }
26 |
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Structurizr.Client/Encryption/EncryptedWorkspace.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.IO.Json;
2 | using System.IO;
3 | using System.Runtime.Serialization;
4 |
5 | namespace Structurizr.Encryption
6 | {
7 |
8 | [DataContract]
9 | public class EncryptedWorkspace : AbstractWorkspace
10 | {
11 |
12 | private Workspace _workspace;
13 | public Workspace Workspace
14 | {
15 | get
16 | {
17 | if (_workspace != null)
18 | {
19 | return _workspace;
20 | }
21 | else if (Ciphertext != null)
22 | {
23 | Plaintext = EncryptionStrategy.Decrypt(Ciphertext);
24 | StringReader stringReader = new StringReader(Plaintext);
25 | return new JsonReader().Read(stringReader);
26 | }
27 | else
28 | {
29 | return null;
30 | }
31 | }
32 |
33 | set
34 | {
35 | _workspace = value;
36 | }
37 | }
38 |
39 | [DataMember(Name = "encryptionStrategy", EmitDefaultValue = false)]
40 | public EncryptionStrategy EncryptionStrategy { get; internal set; }
41 |
42 | internal string Plaintext { get; set; }
43 |
44 | [DataMember(Name = "ciphertext", EmitDefaultValue = false)]
45 | public string Ciphertext { get; internal set; }
46 |
47 | public EncryptedWorkspace() { }
48 |
49 | public EncryptedWorkspace(Workspace workspace, EncryptionStrategy encryptionStrategy)
50 | {
51 | Workspace = workspace;
52 | EncryptionStrategy = encryptionStrategy;
53 |
54 | Configuration = workspace.Configuration;
55 | workspace.ClearConfiguration();
56 |
57 | StringWriter stringWriter = new StringWriter();
58 | JsonWriter jsonWriter = new JsonWriter(false);
59 | jsonWriter.Write(workspace, stringWriter);
60 |
61 | Id = workspace.Id;
62 | Name = workspace.Name;
63 | Description = workspace.Description;
64 | Version = workspace.Version;
65 | Revision = workspace.Revision;
66 | LastModifiedAgent = workspace.LastModifiedAgent;
67 | LastModifiedUser = workspace.LastModifiedUser;
68 | Thumbnail = workspace.Thumbnail;
69 |
70 | Plaintext = stringWriter.ToString();
71 | Ciphertext = encryptionStrategy.Encrypt(Plaintext);
72 | }
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Structurizr.Client/Encryption/EncryptionStrategy.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr.Encryption
4 | {
5 |
6 | [DataContract]
7 | public abstract class EncryptionStrategy
8 | {
9 |
10 | [DataMember(Name = "type", EmitDefaultValue = false)]
11 | public abstract string Type { get; }
12 |
13 | public string Passphrase { get; set; }
14 |
15 | [DataMember(Name = "location", EmitDefaultValue = false)]
16 | public string Location
17 | {
18 | get
19 | {
20 | return "Client";
21 | }
22 | }
23 |
24 | public EncryptionStrategy() { }
25 |
26 | public EncryptionStrategy(string passphrase)
27 | {
28 | this.Passphrase = passphrase;
29 | }
30 |
31 | public abstract string Encrypt(string plaintext);
32 | public abstract string Decrypt(string ciphertext);
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Structurizr.Client/IO/Json/EncryptionStrategyJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Linq;
3 | using Structurizr.Encryption;
4 | using System;
5 | using System.Reflection;
6 |
7 | namespace Structurizr.IO.Json
8 | {
9 | internal class EncryptionStrategyJsonConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return typeof(EncryptionStrategy).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
14 | }
15 |
16 | public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | JObject item = JObject.Load(reader);
19 | string type = item["type"].Value();
20 | if (type == "aes")
21 | {
22 | return item.ToObject();
23 | }
24 | else
25 | {
26 | throw new NotSupportedException("The encryption strategy type of " + type + " is not supported");
27 | }
28 | }
29 |
30 | public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, JsonSerializer serializer)
31 | {
32 | throw new NotImplementedException("This operation is not implemented");
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Structurizr.Client/IO/Json/JsonReader.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using Newtonsoft.Json.Converters;
5 |
6 | namespace Structurizr.IO.Json
7 | {
8 | public class JsonReader
9 | {
10 |
11 | public IdGenerator IdGenerator;
12 |
13 | public Workspace Read(StringReader reader)
14 | {
15 | JsonSerializerSettings settings = new JsonSerializerSettings()
16 | {
17 | ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
18 | Converters = new List {
19 | new StringEnumConverter(),
20 | new IsoDateTimeConverter(),
21 | new PaperSizeJsonConverter()
22 | },
23 | ObjectCreationHandling = ObjectCreationHandling.Replace
24 | };
25 |
26 | Workspace workspace = JsonConvert.DeserializeObject(reader.ReadToEnd(), settings);
27 |
28 | if (IdGenerator != null) {
29 | workspace.Model.IdGenerator = IdGenerator;
30 | }
31 |
32 | workspace.Hydrate();
33 |
34 | return workspace;
35 | }
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Structurizr.Client/IO/Json/JsonWriter.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System.IO;
3 | using Newtonsoft.Json.Converters;
4 |
5 | namespace Structurizr.IO.Json
6 | {
7 | public class JsonWriter
8 | {
9 |
10 | public bool IndentOutput { get; set; }
11 |
12 | public JsonWriter(bool indentOutput)
13 | {
14 | this.IndentOutput = indentOutput;
15 | }
16 |
17 | public void Write(Workspace workspace, TextWriter writer)
18 | {
19 | string json = JsonConvert.SerializeObject(workspace,
20 | IndentOutput ? Formatting.Indented : Formatting.None,
21 | new StringEnumConverter(),
22 | new IsoDateTimeConverter(),
23 | new PaperSizeJsonConverter());
24 |
25 | writer.Write(json);
26 | }
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Structurizr.Client/IO/Json/PaperSizeJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Reflection;
4 |
5 | namespace Structurizr.IO.Json
6 | {
7 | internal class PaperSizeJsonConverter : JsonConverter
8 | {
9 | public override bool CanConvert(Type objectType)
10 | {
11 | return typeof(PaperSize).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
12 | }
13 |
14 | public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
15 | {
16 | return PaperSize.GetPaperSize(reader.Value as string);
17 | }
18 |
19 | public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, JsonSerializer serializer)
20 | {
21 | PaperSize paperSize = value as PaperSize;
22 | if (paperSize != null)
23 | {
24 | writer.WriteValue(paperSize.Key);
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Structurizr.Client/Structurizr.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 1.1.1
7 | true
8 |
9 |
10 |
11 | The API client for publishing models on the Structurizr cloud service and on-premises installation.
12 | Structurizr Limited
13 | Copyright 2017-2023
14 | https://opensource.org/licenses/Apache-2.0
15 | https://structurizr.com
16 | https://github.com/structurizr/dotnet
17 |
18 |
19 |
20 | netstandard2.0
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Structurizr.Client/Util/WorkspaceUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using Structurizr.IO.Json;
5 |
6 | namespace Structurizr
7 | {
8 |
9 | public class WorkspaceUtils
10 | {
11 |
12 | ///
13 | /// Loads a workspace from a JSON definition saved as a file
14 | ///
15 | /// a FileInfo object representing the location of the JSON definition
16 | /// a Workspace object
17 | public static Workspace LoadWorkspaceFromJson(FileInfo file)
18 | {
19 | if (file == null) {
20 | throw new ArgumentException("The path to a JSON file must be specified.");
21 | }
22 |
23 | if (!file.Exists) {
24 | throw new ArgumentException("The specified JSON file does not exist.");
25 | }
26 |
27 | string content = File.ReadAllText(file.FullName, Encoding.UTF8);
28 |
29 | return new JsonReader().Read(new StringReader(content));
30 | }
31 |
32 | ///
33 | /// Saves a workspace to a JSON definition as a file.
34 | ///
35 | /// a FileInfo object representing the location of the file to write the JSON definition
36 | public static void SaveWorkspaceToJson(Workspace workspace, FileInfo file)
37 | {
38 | if (workspace == null) {
39 | throw new ArgumentException("A workspace must be provided.");
40 | }
41 |
42 | if (file == null) {
43 | throw new ArgumentException("The path to a JSON file must be specified.");
44 | }
45 |
46 | using (StreamWriter writer = new StreamWriter(new FileStream(file.FullName, FileMode.Create)))
47 | {
48 | new JsonWriter(true).Write(workspace, writer);
49 | }
50 | }
51 |
52 | ///
53 | /// Prints the given workspace as an indented JSON document.
54 | ///
55 | /// the Workspace object to be printed
56 | public static void PrintWorkspaceAsJson(Workspace workspace)
57 | {
58 | JsonWriter jsonWriter = new JsonWriter(true);
59 | StringWriter stringWriter = new StringWriter();
60 | jsonWriter.Write(workspace, stringWriter);
61 | Console.WriteLine(stringWriter.ToString());
62 | }
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/AbstractTestBase.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Core.Tests
2 | {
3 | public abstract class AbstractTestBase
4 | {
5 |
6 | protected Workspace Workspace;
7 | protected Model Model;
8 | protected ViewSet Views;
9 |
10 | public AbstractTestBase()
11 | {
12 | Workspace = new Workspace("Name", "Description");
13 | Model = Workspace.Model;
14 | Views = Workspace.Views;
15 | }
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Config/WorkspaceConfigurationTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Structurizr.Config;
4 | using Xunit;
5 |
6 | namespace Structurizr.Core.Tests.Configuration
7 | {
8 | public class ConfigurationTests
9 | {
10 |
11 | [Fact]
12 | public void Test_AddUser_ThrowsAnException_WhenANullUsernameIsSpecified()
13 | {
14 | try
15 | {
16 | WorkspaceConfiguration configuration = new WorkspaceConfiguration();
17 | configuration.AddUser(null, Role.ReadWrite);
18 | throw new TestFailedException();
19 | }
20 | catch (ArgumentException iae)
21 | {
22 | Assert.Equal("A username must be specified.", iae.Message);
23 | }
24 | }
25 |
26 | [Fact]
27 | public void Test_AddUser_ThrowsAnException_WhenAnEmptyUsernameIsSpecified()
28 | {
29 | try
30 | {
31 | WorkspaceConfiguration configuration = new WorkspaceConfiguration();
32 | configuration.AddUser(" ", Role.ReadWrite);
33 | throw new TestFailedException();
34 | }
35 | catch (ArgumentException iae)
36 | {
37 | Assert.Equal("A username must be specified.", iae.Message);
38 | }
39 | }
40 |
41 | [Fact]
42 | public void Test_AddUser_AddsAUser()
43 | {
44 | WorkspaceConfiguration configuration = new WorkspaceConfiguration();
45 | configuration.AddUser("user@domain.com", Role.ReadOnly);
46 |
47 | Assert.Equal(1, configuration.Users.Count);
48 | Assert.Equal("user@domain.com", configuration.Users.First().Username);
49 | Assert.Equal(Role.ReadOnly, configuration.Users.First().Role);
50 | }
51 |
52 | }
53 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/FormatFinderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Structurizr.Documentation;
4 | using Xunit;
5 |
6 | namespace Structurizr.Core.Tests.Documentation
7 | {
8 |
9 | public class FormatFinderTests
10 | {
11 |
12 | [Fact]
13 | public void Test_FindFormat_ThrowsAnException_WhenAFileIsNotSpecified() {
14 | try {
15 | FormatFinder.FindFormat(null);
16 | throw new TestFailedException();
17 | } catch (ArgumentException iae) {
18 | Assert.Equal("A file must be specified.", iae.Message);
19 | }
20 | }
21 |
22 | [Fact]
23 | public void Test_FindFormat_ReturnsMarkdown_WhenAMarkdownFileIsSpecified() {
24 | Assert.Equal(Format.Markdown, FormatFinder.FindFormat(new FileInfo("foo.md")));
25 | Assert.Equal(Format.Markdown, FormatFinder.FindFormat(new FileInfo("foo.markdown")));
26 | Assert.Equal(Format.Markdown, FormatFinder.FindFormat(new FileInfo("foo.text")));
27 | }
28 |
29 | [Fact]
30 | public void Test_FindFormat_ReturnsAsciiDoc_WhenAnAsciiDocFileIsSpecified() {
31 | Assert.Equal(Format.AsciiDoc, FormatFinder.FindFormat(new FileInfo("foo.adoc")));
32 | Assert.Equal(Format.AsciiDoc, FormatFinder.FindFormat(new FileInfo("foo.asciidoc")));
33 | Assert.Equal(Format.AsciiDoc, FormatFinder.FindFormat(new FileInfo("foo.asc")));
34 | }
35 |
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/SectionTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Documentation.Tests
4 | {
5 | public class SectionTests
6 | {
7 |
8 | [Fact]
9 | public void Test_SetType_ProvidesBackwardsCompatibility()
10 | {
11 | Section section = new Section();
12 | section.SectionType = "Title"; // older clients use the type property
13 | Assert.Equal("Title", section.Title);
14 | }
15 |
16 | }
17 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/architectural-decisions.md:
--------------------------------------------------------------------------------
1 | Section 9
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/building-block-view.md:
--------------------------------------------------------------------------------
1 | Section 5
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/constraints.md:
--------------------------------------------------------------------------------
1 | Section 2
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/context-and-scope.md:
--------------------------------------------------------------------------------
1 | Section 3
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/crosscutting-concepts.md:
--------------------------------------------------------------------------------
1 | Section 8
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/deployment-view.md:
--------------------------------------------------------------------------------
1 | Section 7
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/glossary.md:
--------------------------------------------------------------------------------
1 | Section 12
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/introduction-and-goals.md:
--------------------------------------------------------------------------------
1 | Section 1
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/quality-requirements.md:
--------------------------------------------------------------------------------
1 | Section 10
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/risks-and-technical-debt.md:
--------------------------------------------------------------------------------
1 | Section 11
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/runtime-view.md:
--------------------------------------------------------------------------------
1 | Section 6
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/arc42/solution-strategy.md:
--------------------------------------------------------------------------------
1 | Section 4
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/example.md:
--------------------------------------------------------------------------------
1 | ## Heading
2 |
3 | Here is a paragraph.
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/image.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/image.gif
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/image.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/image.jpeg
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/image.jpg
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/image.png
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/images/image.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/images/image.gif
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/images/image.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/images/image.jpeg
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/images/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/images/image.jpg
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/images/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Documentation/images/image.png
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/markdown/1.md:
--------------------------------------------------------------------------------
1 | File 1
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/markdown/subdirectory/2.md:
--------------------------------------------------------------------------------
1 | File 2
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/noimages/readme.md:
--------------------------------------------------------------------------------
1 | There are no images in this directory.
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/code-for-componentA1.md:
--------------------------------------------------------------------------------
1 | Code section for component A1
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/code-for-componentA2.md:
--------------------------------------------------------------------------------
1 | Code section for component A2
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/components-for-containerA.md:
--------------------------------------------------------------------------------
1 | Components section for container A
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/components-for-containerB.md:
--------------------------------------------------------------------------------
1 | Components section for container B
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/constraints.md:
--------------------------------------------------------------------------------
1 | Constraints section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/containers.md:
--------------------------------------------------------------------------------
1 | Containers section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/context.md:
--------------------------------------------------------------------------------
1 | Context section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/data.md:
--------------------------------------------------------------------------------
1 | Data section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/decision-log.md:
--------------------------------------------------------------------------------
1 | Decision log section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/deployment.md:
--------------------------------------------------------------------------------
1 | Deployment section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/development-environment.md:
--------------------------------------------------------------------------------
1 | Development environment section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/functional-overview.md:
--------------------------------------------------------------------------------
1 | Functional overview section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/infrastructure-architecture.md:
--------------------------------------------------------------------------------
1 | Infrastructure architecture section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/operation-and-support.md:
--------------------------------------------------------------------------------
1 | Operation and support section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/principles.md:
--------------------------------------------------------------------------------
1 | Principles section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/quality-attributes.md:
--------------------------------------------------------------------------------
1 | Quality attributes section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/structurizr/software-architecture.md:
--------------------------------------------------------------------------------
1 | Software architecture section
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/01-introduction.md:
--------------------------------------------------------------------------------
1 | Section 1
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/02-glossary.md:
--------------------------------------------------------------------------------
1 | Section 2
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/03-system-stakeholders-and-requirements.md:
--------------------------------------------------------------------------------
1 | Section 3
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/04-architectural-forces.md:
--------------------------------------------------------------------------------
1 | Section 4
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/05-architectural-views.md:
--------------------------------------------------------------------------------
1 | Section 5
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/06-system-qualities.md:
--------------------------------------------------------------------------------
1 | Section 6
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Documentation/viewpointsandperspectives/07-appendices.adoc:
--------------------------------------------------------------------------------
1 | Section 7
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Model/CodeElementTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests
5 | {
6 |
7 |
8 | public class CodeElementTests
9 | {
10 |
11 | private readonly CodeElement _codeElement = new CodeElement("Wibble.Wobble, Foo.Bar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xyz");
12 |
13 | [Fact]
14 | public void Test_Construction_WhenAFullyQualifiedTypeIsSpecified()
15 | {
16 | Assert.Equal("Wobble", _codeElement.Name);
17 | }
18 |
19 | [Fact]
20 | public void Test_SetUrl_DoesNotThrowAnException_WhenANullUrlIsSpecified()
21 | {
22 | _codeElement.Url = null;
23 | }
24 |
25 | [Fact]
26 | public void Test_SetUrl_DoesNotThrowAnException_WhenAnEmptyUrlIsSpecified()
27 | {
28 | _codeElement.Url = "";
29 | }
30 |
31 | [Fact]
32 | public void Test_SetUrl_ThrowsAnException_WhenAnInvalidUrlIsSpecified()
33 | {
34 | try
35 | {
36 | _codeElement.Url = "www.somedomain.com";
37 | throw new TestFailedException();
38 | }
39 | catch (Exception e)
40 | {
41 | Assert.Equal("www.somedomain.com is not a valid URL.", e.Message);
42 | }
43 | }
44 |
45 | [Fact]
46 | public void Test_SetUrl_DoesNotThrowAnException_WhenAValidUrlIsSpecified()
47 | {
48 | _codeElement.Url = "http://www.somedomain.com";
49 | Assert.Equal("http://www.somedomain.com", _codeElement.Url);
50 | }
51 |
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Model/ComponentTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class ComponentTests
7 | {
8 |
9 | private Workspace workspace;
10 | private Model model;
11 | private SoftwareSystem softwareSystem;
12 | private Container container;
13 |
14 | public ComponentTests()
15 | {
16 | workspace = new Workspace("Name", "Description");
17 | model = workspace.Model;
18 | softwareSystem = model.AddSoftwareSystem("System", "Description");
19 | container = softwareSystem.AddContainer("Container", "Description", "Some technology");
20 | }
21 |
22 | [Fact]
23 | public void Test_Name_ReturnsTheGivenName_WhenANameIsGiven()
24 | {
25 | Component component = new Component();
26 | component.Name = "Some name";
27 | Assert.Equal("Some name", component.Name);
28 | }
29 |
30 | [Fact]
31 | public void Test_CanonicalName()
32 | {
33 | Component component = container.AddComponent("Component", "Description");
34 | Assert.Equal("Component://System.Container.Component", component.CanonicalName);
35 | }
36 |
37 | [Fact]
38 | public void Test_CanonicalName_WhenNameContainsASlashCharacter()
39 | {
40 | Component component = container.AddComponent("Name1/Name2", "Description");
41 | Assert.Equal("Component://System.Container.Name1Name2", component.CanonicalName);
42 | }
43 |
44 | [Fact]
45 | public void Test_Parent_ReturnsTheParentContainer()
46 | {
47 | Component component = container.AddComponent("Component", "Description");
48 | Assert.Equal(container, component.Parent);
49 | }
50 |
51 | [Fact]
52 | public void Test_Container_ReturnsTheParentContainer()
53 | {
54 | Component component = container.AddComponent("Name", "Description");
55 | Assert.Equal(container, component.Container);
56 | }
57 |
58 | [Fact]
59 | public void Test_RemoveTags_DoesNotRemoveRequiredTags()
60 | {
61 | Component component = new Component();
62 | Assert.True(component.Tags.Contains(Tags.Element));
63 | Assert.True(component.Tags.Contains(Tags.Component));
64 |
65 | component.RemoveTag(Tags.Component);
66 | component.RemoveTag(Tags.Element);
67 |
68 | Assert.True(component.Tags.Contains(Tags.Element));
69 | Assert.True(component.Tags.Contains(Tags.Component));
70 | }
71 |
72 | }
73 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Model/ContainerTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class ContainerTests
7 | {
8 |
9 | private Workspace workspace;
10 | private Model model;
11 | private SoftwareSystem softwareSystem;
12 | private Container container;
13 |
14 | public ContainerTests()
15 | {
16 | workspace = new Workspace("Name", "Description");
17 | model = workspace.Model;
18 | softwareSystem = model.AddSoftwareSystem("System", "Description");
19 | container = softwareSystem.AddContainer("Container", "Description", "Some technology");
20 | }
21 |
22 | [Fact]
23 | public void Test_CanonicalName()
24 | {
25 | Assert.Equal("Container://System.Container", container.CanonicalName);
26 | }
27 |
28 | [Fact]
29 | public void Test_CanonicalName_WhenNameContainsASlashCharacter()
30 | {
31 | container.Name = "Name1/Name2";
32 | Assert.Equal("Container://System.Name1Name2", container.CanonicalName);
33 | }
34 |
35 | [Fact]
36 | public void Test_Parent_ReturnsTheParentSoftwareSystem()
37 | {
38 | Assert.Equal(softwareSystem, container.Parent);
39 | }
40 |
41 | [Fact]
42 | public void Test_SoftwareSystem_ReturnsTheParentSoftwareSystem()
43 | {
44 | Assert.Equal(softwareSystem, container.SoftwareSystem);
45 | }
46 |
47 | [Fact]
48 | public void Test_RemoveTags_DoesNotRemoveRequiredTags()
49 | {
50 | Assert.True(container.Tags.Contains(Tags.Element));
51 | Assert.True(container.Tags.Contains(Tags.Container));
52 |
53 | container.RemoveTag(Tags.Container);
54 | container.RemoveTag(Tags.Element);
55 |
56 | Assert.True(container.Tags.Contains(Tags.Element));
57 | Assert.True(container.Tags.Contains(Tags.Container));
58 | }
59 |
60 | }
61 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Model/GroupableElementTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class GroupableElementTests : AbstractTestBase
7 | {
8 |
9 | [Fact]
10 | public void Test_getGroup_ReturnsNullByDefault()
11 | {
12 | Person element = Model.AddPerson("Person");
13 | Assert.Null(element.Group);
14 | }
15 |
16 | [Fact]
17 | public void Test_setGroup()
18 | {
19 | Person element = Model.AddPerson("Person");
20 | element.Group = "Group";
21 | Assert.Equal("Group", element.Group);
22 | }
23 |
24 | [Fact]
25 | public void Test_setGroup_TrimsWhiteSpace()
26 | {
27 | Person element = Model.AddPerson("Person");
28 | element.Group = " Group ";
29 | Assert.Equal("Group", element.Group);
30 | }
31 |
32 | [Fact]
33 | public void Test_setGroup_HandlesEmptyAndNullValues()
34 | {
35 | Person element = Model.AddPerson("Person");
36 | element.Group = "Group";
37 |
38 | element.Group = null;
39 | Assert.Null(element.Group);
40 |
41 | element.Group = "Group";
42 | element.Group = "";
43 | Assert.Null(element.Group);
44 |
45 | element.Group = "Group";
46 | element.Group = " ";
47 | Assert.Null(element.Group);
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Model/PersonTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class PersonTests
7 | {
8 |
9 | private Workspace workspace;
10 | private Model model;
11 | private Person person;
12 |
13 | public PersonTests()
14 | {
15 | workspace = new Workspace("Name", "Description");
16 | model = workspace.Model;
17 | person = model.AddPerson("Name", "Description");
18 | }
19 |
20 | [Fact]
21 | public void Test_CanonicalName()
22 | {
23 | Assert.Equal("Person://Name", person.CanonicalName);
24 | }
25 |
26 | [Fact]
27 | public void Test_CanonicalName_WhenNameContainsASlashCharacter()
28 | {
29 | person.Name = "Name1/Name2";
30 | Assert.Equal("Person://Name1Name2", person.CanonicalName);
31 | }
32 |
33 | [Fact]
34 | public void Test_Parent_ReturnsNull()
35 | {
36 | Assert.Null(person.Parent);
37 | }
38 |
39 | [Fact]
40 | public void Test_RemoveTags_DoesNotRemoveRequiredTags()
41 | {
42 | Assert.True(person.Tags.Contains(Tags.Element));
43 | Assert.True(person.Tags.Contains(Tags.Person));
44 |
45 | person.RemoveTag(Tags.Person);
46 | person.RemoveTag(Tags.Element);
47 |
48 | Assert.True(person.Tags.Contains(Tags.Element));
49 | Assert.True(person.Tags.Contains(Tags.Person));
50 | }
51 |
52 | }
53 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/TestFailedException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 | public class TestFailedException : Exception
6 | {
7 |
8 | }
9 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Util/UrlTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Xunit;
7 | using Structurizr.Util;
8 |
9 | namespace Structurizr.Core.Tests
10 | {
11 |
12 |
13 | public class UrlTests
14 | {
15 |
16 | [Fact]
17 | public void test_IsUrl_ReturnsFalse_WhenPassedNull()
18 | {
19 | Assert.False(Url.IsUrl(null));
20 | }
21 |
22 | [Fact]
23 | public void test_IsUrl_ReturnsFalse_WhenPassedAnEmptyString()
24 | {
25 | Assert.False(Url.IsUrl(""));
26 | Assert.False(Url.IsUrl(" "));
27 | }
28 |
29 | [Fact]
30 | public void test_IsUrl_ReturnsFalse_WhenPassedAnInvalidUrl()
31 | {
32 | Assert.False(Url.IsUrl("www.google.com"));
33 | }
34 |
35 | [Fact]
36 | public void test_IsUrl_ReturnsTrue_WhenPassedAValidUrl()
37 | {
38 | Assert.True(Url.IsUrl("https://www.google.com"));
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Util/readme.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/Util/structurizr-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Core.Tests/Util/structurizr-logo.png
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/AutomaticLayoutTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests.View
5 | {
6 | public class AutomaticLayoutTests
7 | {
8 | [Fact]
9 | public void Test_AutomaticLayout()
10 | {
11 | AutomaticLayout automaticLayout = new AutomaticLayout(RankDirection.LeftRight, 100, 200, 300, true);
12 |
13 | Assert.Equal(RankDirection.LeftRight, automaticLayout.RankDirection);
14 | Assert.Equal(100, automaticLayout.RankSeparation);
15 | Assert.Equal(200, automaticLayout.NodeSeparation);
16 | Assert.Equal(300, automaticLayout.EdgeSeparation);
17 | Assert.True(automaticLayout.Vertices);
18 | }
19 |
20 | [Fact]
21 | public void Test_RankSeparation_ThrowsAnException_WhenANegativeIntegerIsSpecified()
22 | {
23 | try
24 | {
25 | AutomaticLayout automaticLayout = new AutomaticLayout();
26 | automaticLayout.RankSeparation = -100;
27 | throw new TestFailedException();
28 | }
29 | catch (ArgumentException iae)
30 | {
31 | Assert.Equal("The rank separation must be a positive integer.", iae.Message);
32 | }
33 | }
34 |
35 | [Fact]
36 | public void Test_NodeSeparation_ThrowsAnException_WhenANegativeIntegerIsSpecified()
37 | {
38 | try
39 | {
40 | AutomaticLayout automaticLayout = new AutomaticLayout();
41 | automaticLayout.NodeSeparation = -100;
42 | throw new TestFailedException();
43 | }
44 | catch (ArgumentException iae)
45 | {
46 | Assert.Equal("The node separation must be a positive integer.", iae.Message);
47 | }
48 | }
49 |
50 | [Fact]
51 | public void Test_EdgeSeparation_ThrowsAnException_WhenANegativeIntegerIsSpecified()
52 | {
53 | try
54 | {
55 | AutomaticLayout automaticLayout = new AutomaticLayout();
56 | automaticLayout.EdgeSeparation = -100;
57 | throw new TestFailedException();
58 | }
59 | catch (ArgumentException iae)
60 | {
61 | Assert.Equal("The edge separation must be a positive integer.", iae.Message);
62 | }
63 | }
64 |
65 | }
66 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/ColorTests.cs:
--------------------------------------------------------------------------------
1 |
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests
5 | {
6 |
7 |
8 | public class ColorTests
9 | {
10 |
11 | [Fact]
12 | public void Test_IsHexColorCode_ReturnsFalse_WhenPassedNull()
13 | {
14 | Assert.False(Color.IsHexColorCode(null));
15 | }
16 |
17 | [Fact]
18 | public void Test_IsHexColorCode_ReturnsFalse_WhenPassedAnEmptyString()
19 | {
20 | Assert.False(Color.IsHexColorCode(""));
21 | }
22 |
23 | [Fact]
24 | public void Test_IsHexColorCode_ReturnsFalse_WhenPassedAnInvalidString()
25 | {
26 | Assert.False(Color.IsHexColorCode("ffffff"));
27 | Assert.False(Color.IsHexColorCode("#fffff"));
28 | Assert.False(Color.IsHexColorCode("#gggggg"));
29 | }
30 |
31 | [Fact]
32 | public void Test_IsHexColorCode_ReturnsTrue_WhenPassedAnValidString()
33 | {
34 | Assert.True(Color.IsHexColorCode("#abcdef"));
35 | Assert.True(Color.IsHexColorCode("#ABCDEF"));
36 | Assert.True(Color.IsHexColorCode("#123456"));
37 | }
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/DimensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests.View
5 | {
6 | public class DimensionsTests
7 | {
8 | [Fact]
9 | public void Test_Construction()
10 | {
11 | Dimensions dimensions = new Dimensions(123, 456);
12 |
13 | Assert.Equal(123, dimensions.Width);
14 | Assert.Equal(456, dimensions.Height);
15 | }
16 |
17 | [Fact]
18 | public void Test_Width_ThrowsAnException_WhenANegativeIntegerIsSpecified()
19 | {
20 | try
21 | {
22 | Dimensions dimensions = new Dimensions();
23 | dimensions.Width = -100;
24 | throw new TestFailedException();
25 | }
26 | catch (ArgumentException iae)
27 | {
28 | Assert.Equal("The width must be a positive integer.", iae.Message);
29 | }
30 | }
31 |
32 | [Fact]
33 | public void Test_Height_ThrowsAnException_WhenANegativeIntegerIsSpecified()
34 | {
35 | try
36 | {
37 | Dimensions dimensions = new Dimensions();
38 | dimensions.Height = -100;
39 | throw new TestFailedException();
40 | }
41 | catch (ArgumentException iae)
42 | {
43 | Assert.Equal("The height must be a positive integer.", iae.Message);
44 | }
45 | }
46 |
47 | }
48 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/FilteredViewTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests.View
4 | {
5 |
6 | public class FilteredViewTests : AbstractTestBase
7 | {
8 |
9 | [Fact]
10 | public void Test_Construction()
11 | {
12 | SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Name", "Description");
13 | SystemContextView systemContextView = Views.CreateSystemContextView(softwareSystem, "SystemContext", "Description");
14 | FilteredView filteredView = Views.CreateFilteredView(
15 | systemContextView,
16 | "CurrentStateSystemContext",
17 | "The system context as-is.",
18 | FilterMode.Exclude,
19 | "v2", "v3"
20 | );
21 |
22 | Assert.Equal("CurrentStateSystemContext", filteredView.Key);
23 | Assert.Equal("SystemContext", filteredView.BaseViewKey);
24 | Assert.Same(systemContextView, filteredView.View);
25 | Assert.Equal("The system context as-is.", filteredView.Description);
26 | Assert.Equal(FilterMode.Exclude, filteredView.Mode);
27 | Assert.Equal(2, filteredView.Tags.Count);
28 | Assert.True(filteredView.Tags.Contains("v2"));
29 | Assert.True(filteredView.Tags.Contains("v3"));
30 | }
31 |
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/FontTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests.View
5 | {
6 |
7 |
8 | public class FontTests
9 | {
10 |
11 | private Font _font;
12 |
13 | [Fact]
14 | public void construction_WithANameOnly()
15 | {
16 | this._font = new Font("Times New Roman");
17 | Assert.Equal("Times New Roman", _font.Name);
18 | }
19 |
20 | [Fact]
21 | public void construction_WithANameAndUrl()
22 | {
23 | this._font = new Font("Open Sans", "https://fonts.googleapis.com/css?family=Open+Sans:400,700");
24 | Assert.Equal("Open Sans", _font.Name);
25 | Assert.Equal("https://fonts.googleapis.com/css?family=Open+Sans:400,700", _font.Url);
26 | }
27 |
28 | [Fact]
29 | public void test_setUrl_WithAUrl()
30 | {
31 | _font = new Font();
32 | _font.Url = "https://fonts.googleapis.com/css?family=Open+Sans:400,700";
33 | Assert.Equal("https://fonts.googleapis.com/css?family=Open+Sans:400,700", _font.Url);
34 | }
35 |
36 | [Fact]
37 | public void test_setUrl_ThrowsAnArgumentException_WhenAnInvalidUrlIsSpecified()
38 | {
39 | _font = new Font();
40 | Assert.Throws(() =>
41 | _font.Url = "www.google.com"
42 | );
43 | }
44 |
45 | [Fact]
46 | public void test_setUrl_DoesNothing_WhenANullUrlIsSpecified()
47 | {
48 | _font = new Font();
49 | _font.Url = null;
50 | Assert.Null(_font.Url);
51 | }
52 |
53 | [Fact]
54 | public void test_setUrl_DoesNothing_WhenAnEmptyUrlIsSpecified()
55 | {
56 | _font = new Font();
57 | _font.Url = " ";
58 | Assert.Null(_font.Url);
59 | }
60 |
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/RelationshipStyleTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests.View
5 | {
6 |
7 | public class RelationshipStyleTests
8 | {
9 |
10 | [Fact]
11 | public void Test_Position()
12 | {
13 | RelationshipStyle style = new RelationshipStyle();
14 | Assert.Null(style.Position);
15 |
16 | style.Position = -1;
17 | Assert.Equal(0, style.Position);
18 |
19 | style.Position = 0;
20 | Assert.Equal(0, style.Position);
21 |
22 | style.Position = 50;
23 | Assert.Equal(50, style.Position);
24 |
25 | style.Position = 100;
26 | Assert.Equal(100, style.Position);
27 |
28 | style.Position = 101;
29 | Assert.Equal(100, style.Position);
30 | }
31 |
32 | [Fact]
33 | public void Test_Opacity()
34 | {
35 | RelationshipStyle style = new RelationshipStyle();
36 | Assert.Null(style.Opacity);
37 |
38 | style.Opacity = -1;
39 | Assert.Equal(0, style.Opacity);
40 |
41 | style.Opacity = 0;
42 | Assert.Equal(0, style.Opacity);
43 |
44 | style.Opacity = 50;
45 | Assert.Equal(50, style.Opacity);
46 |
47 | style.Opacity = 100;
48 | Assert.Equal(100, style.Opacity);
49 |
50 | style.Opacity = 101;
51 | Assert.Equal(100, style.Opacity);
52 | }
53 |
54 | [Fact]
55 | public void Test_Color_SetsTheColorProperty_WhenAValidHexColorCodeIsSpecified()
56 | {
57 | RelationshipStyle style = new RelationshipStyle();
58 | style.Color = "#ffffff";
59 | Assert.Equal("#ffffff", style.Color);
60 |
61 | style.Color = "#FFFFFF";
62 | Assert.Equal("#ffffff", style.Color);
63 |
64 | style.Color = "#123456";
65 | Assert.Equal("#123456", style.Color);
66 | }
67 |
68 | [Fact]
69 | public void Test_Color_ThrowsAnException_WhenAnInvalidHexColorCodeIsSpecified()
70 | {
71 | try
72 | {
73 | RelationshipStyle style = new RelationshipStyle();
74 | style.Color = "white";
75 | throw new TestFailedException();
76 | }
77 | catch (ArgumentException ae)
78 | {
79 | Assert.Equal("'white' is not a valid hex color code.", ae.Message);
80 | }
81 | }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/SequenceCounterTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class SequenceCounterTests
7 | {
8 |
9 | [Fact]
10 | public void Test_increment_IncrementsTheCounter()
11 | {
12 | SequenceCounter counter = new SequenceCounter();
13 | Assert.Equal("0", counter.AsString());
14 |
15 | counter.Increment();
16 | Assert.Equal("1", counter.AsString());
17 |
18 | counter.Increment();
19 | Assert.Equal("2", counter.AsString());
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/SequenceNumberTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Structurizr.Core.Tests
4 | {
5 |
6 | public class SequenceNumberTests
7 | {
8 |
9 | [Fact]
10 | public void Test_Increment()
11 | {
12 | SequenceNumber sequenceNumber = new SequenceNumber();
13 | Assert.Equal("1", sequenceNumber.GetNext());
14 | Assert.Equal("2", sequenceNumber.GetNext());
15 | }
16 |
17 | [Fact]
18 | public void Test_ParallelSequences()
19 | {
20 | SequenceNumber sequenceNumber = new SequenceNumber();
21 | Assert.Equal("1", sequenceNumber.GetNext());
22 |
23 | sequenceNumber.StartParallelSequence();
24 | Assert.Equal("2", sequenceNumber.GetNext());
25 | sequenceNumber.EndParallelSequence(false);
26 |
27 | sequenceNumber.StartParallelSequence();
28 | Assert.Equal("2", sequenceNumber.GetNext());
29 | sequenceNumber.EndParallelSequence(true);
30 |
31 | Assert.Equal("3", sequenceNumber.GetNext());
32 | }
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/View/StyleTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace Structurizr.Core.Tests.View
5 | {
6 |
7 | public class StyleTests
8 | {
9 |
10 | private Styles _styles = new Styles();
11 |
12 | [Fact]
13 | public void Test_AddElementStyle_ThrowsAnException_WhenAStyleWithTheSameTagExistsAlready()
14 | {
15 | try
16 | {
17 | _styles.Add(new ElementStyle(Tags.SoftwareSystem) { Color = "#ff0000" });
18 | _styles.Add(new ElementStyle(Tags.SoftwareSystem) { Color = "#ff0000" });
19 |
20 | throw new TestFailedException();
21 | }
22 | catch (ArgumentException ae)
23 | {
24 | Assert.Equal("An element style for the tag \"Software System\" already exists.", ae.Message);
25 | }
26 | }
27 |
28 | [Fact]
29 | public void Test_AddRelationshipStyle_ThrowsAnException_WhenAStyleWithTheSameTagExistsAlready()
30 | {
31 | try
32 | {
33 | _styles.Add(new RelationshipStyle(Tags.Relationship) { Color = "#ff0000" });
34 | _styles.Add(new RelationshipStyle(Tags.Relationship) { Color = "#ff0000" });
35 |
36 | throw new TestFailedException();
37 | }
38 | catch (ArgumentException ae)
39 | {
40 | Assert.Equal("A relationship style for the tag \"Relationship\" already exists.", ae.Message);
41 | }
42 | }
43 |
44 | [Fact]
45 | public void Test_ClearElementStyles_RemovesAllElementStyles()
46 | {
47 | _styles.Add(new ElementStyle(Tags.SoftwareSystem) { Color = "#ff0000" });
48 | Assert.Equal(1, _styles.Elements.Count);
49 |
50 | _styles.ClearElementStyles();
51 | Assert.Equal(0, _styles.Elements.Count);
52 | }
53 |
54 | [Fact]
55 | public void Test_ClearRelationshipStyles_RemovesAllRelationshipStyles()
56 | {
57 | _styles.Add(new RelationshipStyle(Tags.Relationship) { Color = "#ff0000" });
58 | Assert.Equal(1, _styles.Relationships.Count);
59 |
60 | _styles.ClearRelationshipStyles();
61 | Assert.Equal(0, _styles.Relationships.Count);
62 | }
63 |
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/Structurizr.Core.Tests/WorkspaceTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 | using System;
3 |
4 | namespace Structurizr.Core.Tests
5 | {
6 |
7 |
8 | public class WorkspaceTests
9 | {
10 |
11 | private Workspace workspace = new Workspace("Name", "Description");
12 |
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/Structurizr.Core/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Structurizr.Core.Tests")]
2 |
3 | namespace Structurizr
4 | {
5 | public class AssemblyInfo
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Config/Role.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Config
2 | {
3 | public enum Role
4 | {
5 |
6 | ReadWrite,
7 | ReadOnly
8 |
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Config/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr.Config
5 | {
6 |
7 | [DataContract]
8 | public sealed class User : IEquatable
9 | {
10 |
11 | [DataMember(Name = "username", EmitDefaultValue = false)]
12 | public string Username { get; internal set; }
13 |
14 | [DataMember(Name = "role", EmitDefaultValue = true)]
15 | public Role Role { get; internal set; }
16 |
17 | internal User()
18 | {
19 | }
20 |
21 | internal User(string username, Role role)
22 | {
23 | Username = username;
24 | Role = role;
25 | }
26 |
27 | public bool Equals(User other)
28 | {
29 | if (ReferenceEquals(null, other)) return false;
30 | if (ReferenceEquals(this, other)) return true;
31 | return string.Equals(Username, other.Username);
32 | }
33 |
34 | public override bool Equals(object obj)
35 | {
36 | if (ReferenceEquals(null, obj)) return false;
37 | if (ReferenceEquals(this, obj)) return true;
38 | if (obj.GetType() != this.GetType()) return false;
39 | return Equals((User) obj);
40 | }
41 |
42 | public override int GetHashCode()
43 | {
44 | return Username.GetHashCode();
45 | }
46 |
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Config/WorkspaceConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using Newtonsoft.Json;
5 |
6 | namespace Structurizr.Config
7 | {
8 |
9 | [DataContract]
10 | public sealed class WorkspaceConfiguration
11 | {
12 |
13 | private HashSet _users;
14 |
15 | [DataMember(Name = "users", EmitDefaultValue = false)]
16 | public ISet Users
17 | {
18 | get
19 | {
20 | return new HashSet(_users);
21 | }
22 |
23 | internal set
24 | {
25 | _users = new HashSet(value);
26 | }
27 | }
28 |
29 | [JsonConstructor]
30 | internal WorkspaceConfiguration()
31 | {
32 | _users = new HashSet();
33 | }
34 |
35 | public void AddUser(string username, Role role)
36 | {
37 | if (string.IsNullOrWhiteSpace(username))
38 | {
39 | throw new ArgumentException("A username must be specified.");
40 | }
41 |
42 | _users.Add(new User(username, role));
43 | }
44 |
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Documentation/DecisionStatus.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Documentation
2 | {
3 |
4 | ///
5 | /// Represents the status of a decision.
6 | ///
7 | public enum DecisionStatus
8 | {
9 |
10 | Proposed,
11 | Accepted,
12 | Superseded,
13 | Deprecated,
14 | Rejected
15 |
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Documentation/Format.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Documentation
2 | {
3 | public enum Format
4 | {
5 |
6 | Markdown,
7 | AsciiDoc
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Structurizr.Core/Documentation/FormatFinder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 |
5 | namespace Structurizr.Documentation
6 | {
7 |
8 | internal class FormatFinder
9 | {
10 |
11 | private static ISet MARKDOWN_EXTENSIONS = new HashSet
12 | {
13 | ".md", ".markdown", ".text"
14 | };
15 |
16 | private static ISet ASCIIDOC_EXTENSIONS = new HashSet
17 | {
18 | ".asciidoc", ".adoc", ".asc"
19 | };
20 |
21 | internal static Format FindFormat(FileSystemInfo file) {
22 | if (file == null) {
23 | throw new ArgumentException("A file must be specified.");
24 | }
25 |
26 | if (MARKDOWN_EXTENSIONS.Contains(file.Extension)) {
27 | return Format.Markdown;
28 | } else if (ASCIIDOC_EXTENSIONS.Contains(file.Extension)) {
29 | return Format.AsciiDoc;
30 | } else {
31 | // just assume Markdown
32 | return Format.Markdown;
33 | }
34 |
35 | }
36 |
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Documentation/FormattedContent.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Documentation
2 | {
3 |
4 | internal class FormattedContent
5 | {
6 |
7 | internal string Content { get; }
8 | internal Format Format { get; }
9 |
10 | internal FormattedContent(string content, Format format)
11 | {
12 | Content = content;
13 | Format = format;
14 | }
15 |
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Documentation/Image.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr.Documentation
4 | {
5 |
6 | [DataContract]
7 | public sealed class Image
8 | {
9 |
10 | [DataMember(Name = "name", EmitDefaultValue = false)]
11 | public string Name { get; internal set; }
12 |
13 | [DataMember(Name = "content", EmitDefaultValue = false)]
14 | public string Content { get; private set; }
15 |
16 | [DataMember(Name = "type", EmitDefaultValue = false)]
17 | public string Type { get; private set; }
18 |
19 | internal Image() { }
20 |
21 | internal Image(string name, string content, string type)
22 | {
23 | this.Name = name;
24 | this.Content = content;
25 | this.Type = type;
26 | }
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/AbstractImpliedRelationshipsStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | public abstract class AbstractImpliedRelationshipsStrategy : IImpliedRelationshipsStrategy
5 | {
6 |
7 | protected bool ImpliedRelationshipIsAllowed(Element source, Element destination)
8 | {
9 | if (source.Equals(destination))
10 | {
11 | return false;
12 | }
13 |
14 | return !(IsChildOf(source, destination) || IsChildOf(destination, source));
15 | }
16 |
17 | private bool IsChildOf(Element e1, Element e2)
18 | {
19 | if (e1 is Person || e2 is Person) {
20 | return false;
21 | }
22 |
23 | Element parent = e2.Parent;
24 | while (parent != null) {
25 | if (parent.Id.Equals(e1.Id)) {
26 | return true;
27 | }
28 |
29 | parent = parent.Parent;
30 | }
31 |
32 | return false;
33 | }
34 |
35 | ///
36 | /// Called after a relationship has been created in the model,
37 | /// providing an opportunity to create any resulting implied relationships.
38 | ///
39 | /// the newly created Relationship
40 | public abstract void CreateImpliedRelationships(Relationship relationship);
41 |
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/CodeElementRole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Structurizr
7 | {
8 |
9 | public enum CodeElementRole
10 | {
11 |
12 | Primary,
13 | Supporting
14 |
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/ContainerInstance.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 |
5 | namespace Structurizr
6 | {
7 |
8 | ///
9 | /// Represents a deployment instance of a Container, which can be added to a DeploymentNode.
10 | ///
11 | [DataContract]
12 | public sealed class ContainerInstance : StaticStructureElementInstance
13 | {
14 |
15 | public Container Container { get; internal set; }
16 |
17 | private string _containerId;
18 |
19 | [DataMember(Name = "containerId", EmitDefaultValue = false)]
20 | public string ContainerId
21 | {
22 | get
23 | {
24 | if (Container != null)
25 | {
26 | return Container.Id;
27 | }
28 | else
29 | {
30 | return _containerId;
31 | }
32 | }
33 | set { _containerId = value; }
34 | }
35 |
36 | internal ContainerInstance() {
37 | }
38 |
39 | internal ContainerInstance(Container container, int instanceId, string environment, string deploymentGroup)
40 | {
41 | Container = container;
42 | AddTags(Structurizr.Tags.ContainerInstance);
43 | InstanceId = instanceId;
44 | Environment = environment;
45 | DeploymentGroup = deploymentGroup;
46 | }
47 |
48 | public override StaticStructureElement getElement()
49 | {
50 | return Container;
51 | }
52 |
53 | public override string CanonicalName
54 | {
55 | get { return new CanonicalNameGenerator().Generate(this); }
56 | }
57 |
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// This strategy creates implied relationships between all valid combinations of the parent elements,
8 | /// unless any relationship already exists between them.
9 | ///
10 | public class CreateImpliedRelationshipsUnlessAnyRelationshipExistsStrategy : AbstractImpliedRelationshipsStrategy
11 | {
12 | public override void CreateImpliedRelationships(Relationship relationship)
13 | {
14 | Element source = relationship.Source;
15 | Element destination = relationship.Destination;
16 |
17 | Model model = source.Model;
18 |
19 | while (source != null) {
20 | while (destination != null) {
21 | if (ImpliedRelationshipIsAllowed(source, destination)) {
22 | bool createRelationship = !source.HasEfferentRelationshipWith(destination);
23 |
24 | if (createRelationship) {
25 | model.AddRelationship(source, destination, relationship.Description, relationship.Technology, relationship.InteractionStyle, relationship.GetTagsAsSet().ToArray(), false);
26 | }
27 | }
28 |
29 | destination = destination.Parent;
30 | }
31 |
32 | destination = relationship.Destination;
33 | source = source.Parent;
34 | }
35 | }
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/CreateImpliedRelationshipsUnlessSameRelationshipExistsStrategy.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// This strategy creates implied relationships between all valid combinations of the parent elements,
8 | /// unless the same relationship already exists between them.
9 | ///
10 | public class CreateImpliedRelationshipsUnlessSameRelationshipExistsStrategy : AbstractImpliedRelationshipsStrategy
11 | {
12 | public override void CreateImpliedRelationships(Relationship relationship)
13 | {
14 | Element source = relationship.Source;
15 | Element destination = relationship.Destination;
16 |
17 | Model model = source.Model;
18 |
19 | while (source != null) {
20 | while (destination != null) {
21 | if (ImpliedRelationshipIsAllowed(source, destination)) {
22 | bool createRelationship = !source.HasEfferentRelationshipWith(destination, relationship.Description);
23 |
24 | if (createRelationship) {
25 | model.AddRelationship(source, destination, relationship.Description, relationship.Technology, relationship.InteractionStyle, relationship.GetTagsAsSet().ToArray(), false);
26 | }
27 | }
28 |
29 | destination = destination.Parent;
30 | }
31 |
32 | destination = relationship.Destination;
33 | source = source.Parent;
34 | }
35 | }
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/DefaultImpliedRelationshipsStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | ///
5 | /// The default strategy is to NOT create implied relationships.
6 | ///
7 | public class DefaultImpliedRelationshipsStrategy : AbstractImpliedRelationshipsStrategy
8 | {
9 |
10 | public override void CreateImpliedRelationships(Relationship relationship)
11 | {
12 | // do nothing
13 | }
14 |
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/DeploymentElement.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// This is the superclass for model elements that describe deployment nodes, infrastructure nodes, and container instances.
8 | ///
9 | [DataContract]
10 | public abstract class DeploymentElement : Element
11 | {
12 |
13 | internal const string DefaultDeploymentEnvironment = "Default";
14 | internal const string DefaultDeploymentGroup = "Default";
15 |
16 | [DataMember(Name = "environment", EmitDefaultValue = false)]
17 | public string Environment { get; internal set; }
18 |
19 | private Element _parent;
20 |
21 | public override Element Parent { get; set; }
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/Enterprise.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr
5 | {
6 |
7 | [DataContract]
8 | public sealed class Enterprise
9 | {
10 |
11 | ///
12 | /// The name of this enterprise.
13 | ///
14 | [DataMember(Name = "name", EmitDefaultValue = false)]
15 | public string Name { get; set; }
16 |
17 | public Enterprise(string name)
18 | {
19 | if (name == null || name.Trim().Length == 0)
20 | {
21 | throw new ArgumentException("Name must be specified.");
22 | }
23 |
24 | this.Name = name;
25 | }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/GroupableElement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr
5 | {
6 |
7 | public abstract class GroupableElement : Element
8 | {
9 |
10 | private string _group;
11 |
12 | ///
13 | /// The name of the group in which this element should be included in.
14 | ///
15 | [DataMember(Name = "group", EmitDefaultValue = false)]
16 | public string Group
17 | {
18 | get
19 | {
20 | return _group;
21 | }
22 |
23 | set
24 | {
25 | if (value == null)
26 | {
27 | _group = null;
28 | }
29 | else {
30 | _group = value.Trim();
31 |
32 | if (String.IsNullOrEmpty(_group))
33 | {
34 | _group = null;
35 | }
36 | }
37 | }
38 | }
39 |
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/IdGenerator.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | ///
5 | /// The interface that ID generators, used when creating IDs for model elements/relationships, must implement.
6 | ///
7 | public interface IdGenerator
8 | {
9 |
10 | ///
11 | /// Generates an ID for the specified model element.
12 | ///
13 | /// an Element instance
14 | /// the ID
15 | string GenerateId(Element element);
16 |
17 | ///
18 | /// Generates an ID for the specified model element.
19 | ///
20 | /// a Relationship instance
21 | /// the ID
22 | string GenerateId(Relationship relationship);
23 |
24 | ///
25 | /// Called when loading/deserializing a model, to indicate that the specified ID has been found
26 | /// (and shouldn't be reused when generating new IDs).
27 | ///
28 | /// he ID that has been found
29 | void Found(string id);
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/ImpliedRelationshipsStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | ///
5 | /// Defines the interface for strategies to create implied relationships in the model,
6 | /// after a relationship has been created.
7 | ///
8 | public interface IImpliedRelationshipsStrategy
9 | {
10 |
11 | ///
12 | /// Called after a relationship has been created in the model,
13 | /// providing an opportunity to create any resulting implied relationships.
14 | ///
15 | /// the newly created Relationship
16 | void CreateImpliedRelationships(Relationship relationship);
17 |
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/InteractionStyle.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum InteractionStyle
4 | {
5 |
6 | Synchronous,
7 | Asynchronous
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/Location.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum Location
4 | {
5 |
6 | Unspecified,
7 | Internal,
8 | External
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/Perspective.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using System.Text;
5 |
6 | namespace Structurizr
7 | {
8 |
9 | ///
10 | /// Represents an architectural perspective, that can be applied to elements and relationships.
11 | /// See https://www.viewpoints-and-perspectives.info/home/perspectives/ for more details of this concept
12 | ///
13 | [DataContract]
14 | public sealed class Perspective : IEquatable
15 | {
16 |
17 | ///
18 | /// The name of this perspective.
19 | ///
20 | [DataMember(Name = "name", EmitDefaultValue = false)]
21 | public string Name { get; internal set; }
22 |
23 | ///
24 | /// The content of this perspective.
25 | ///
26 | [DataMember(Name = "description", EmitDefaultValue = false)]
27 | public string Description { get; internal set; }
28 |
29 | internal Perspective()
30 | {
31 | }
32 |
33 | internal Perspective(string name, string description)
34 | {
35 | Name = name;
36 | Description = description;
37 | }
38 |
39 | public override bool Equals(object obj)
40 | {
41 | return Equals(obj as Perspective);
42 | }
43 |
44 | public bool Equals(Perspective other)
45 | {
46 | return other != null &&
47 | Name == other.Name;
48 | }
49 |
50 | public override int GetHashCode()
51 | {
52 | return Name.GetHashCode();
53 | }
54 |
55 | }
56 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/SequentialIntegerIdGeneratorStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// An ID generator that simply uses a sequential number when generating IDs for model elements and relationships.
8 | /// This is the default ID generator.
9 | ///
10 | public class SequentialIntegerIdGeneratorStrategy : IdGenerator
11 | {
12 |
13 | private int Id = 0;
14 |
15 | public string GenerateId(Element element)
16 | {
17 | lock(this)
18 | {
19 | return "" + ++Id;
20 | }
21 | }
22 |
23 |
24 | public string GenerateId(Relationship relationship)
25 | {
26 | lock(this)
27 | {
28 | return "" + ++Id;
29 | }
30 | }
31 |
32 | public void Found(string id)
33 | {
34 | int idAsInt = int.Parse(id);
35 | if (idAsInt > Id)
36 | {
37 | Id = idAsInt;
38 | }
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Structurizr.Core/Model/SoftwareSystemInstance.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 |
5 | namespace Structurizr
6 | {
7 |
8 | ///
9 | /// Represents a deployment instance of a Software System, which can be added to a DeploymentNode.
10 | ///
11 | [DataContract]
12 | public sealed class SoftwareSystemInstance : StaticStructureElementInstance
13 | {
14 |
15 | public SoftwareSystem SoftwareSystem { get; internal set; }
16 |
17 | private string _softwareSystemId;
18 |
19 | [DataMember(Name = "softwareSystemId", EmitDefaultValue = false)]
20 | public string SoftwareSystemId
21 | {
22 | get
23 | {
24 | if (SoftwareSystem != null)
25 | {
26 | return SoftwareSystem.Id;
27 | }
28 | else
29 | {
30 | return _softwareSystemId;
31 | }
32 | }
33 | set { _softwareSystemId = value; }
34 | }
35 |
36 | internal SoftwareSystemInstance() {
37 | }
38 |
39 | internal SoftwareSystemInstance(SoftwareSystem softwareSystem, int instanceId, string environment, string deploymentGroup)
40 | {
41 | SoftwareSystem = softwareSystem;
42 | AddTags(Structurizr.Tags.SoftwareSystemInstance);
43 | InstanceId = instanceId;
44 | Environment = environment;
45 | DeploymentGroup = deploymentGroup;
46 | }
47 |
48 | public override StaticStructureElement getElement()
49 | {
50 | return SoftwareSystem;
51 | }
52 |
53 | public override string CanonicalName
54 | {
55 | get { return new CanonicalNameGenerator().Generate(this); }
56 | }
57 |
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Model/Tags.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public sealed class Tags
4 | {
5 |
6 | public const string Element = "Element";
7 | public const string Relationship = "Relationship";
8 |
9 | public const string Person = "Person";
10 | public const string SoftwareSystem = "Software System";
11 | public const string Container = "Container";
12 | public const string Component = "Component";
13 |
14 | public const string Synchronous = "Synchronous";
15 | public const string Asynchronous = "Asynchronous";
16 |
17 | public const string DeploymentNode = "Deployment Node";
18 | public const string InfrastructureNode = "Infrastructure Node";
19 | public const string SoftwareSystemInstance = "Software System Instance";
20 | public const string ContainerInstance = "Container Instance";
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Structurizr.Core/Structurizr.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 1.1.1
7 | true
8 |
9 |
10 | The core library that can used to create software architecture models.
11 | Structurizr Limited
12 | Copyright 2017-2023
13 | https://opensource.org/licenses/Apache-2.0
14 | https://structurizr.com
15 | https://github.com/structurizr/dotnet
16 |
17 |
18 | netstandard2.0
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Structurizr.Core/Util/DictionaryUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Structurizr.Core.Util
4 | {
5 |
6 | public class DictionaryUtils
7 | {
8 |
9 | public static Dictionary Create(params string[] nameValuePairs)
10 | {
11 | Dictionary map = new Dictionary();
12 |
13 | if (nameValuePairs != null) {
14 | foreach (string nameValuePair in nameValuePairs)
15 | {
16 | string[] tokens = nameValuePair.Split('=');
17 | if (tokens.Length == 2)
18 | {
19 | map[tokens[0]] = tokens[1];
20 | }
21 | }
22 | }
23 |
24 | return map;
25 | }
26 |
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Util/ImageUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace Structurizr.Util
8 | {
9 | public class ImageUtils
10 | {
11 |
12 | public static string GetContentType(FileInfo file)
13 | {
14 | if (file == null)
15 | {
16 | throw new ArgumentException("A file must be specified.");
17 | }
18 | else if (Directory.Exists(file.FullName))
19 | {
20 | throw new ArgumentException(file.FullName + " is not a file.");
21 | }
22 | else if (!file.Exists)
23 | {
24 | throw new ArgumentException(file.FullName + " does not exist.");
25 | }
26 |
27 | string fileExtension = file.FullName.Substring(file.FullName.LastIndexOf(".") + 1).ToLower();
28 | if (fileExtension.Equals("jpg"))
29 | {
30 | fileExtension = "jpeg";
31 | }
32 |
33 | if (fileExtension == "png" || fileExtension == "jpeg" || fileExtension == "gif")
34 | {
35 | return "image/" + fileExtension;
36 | }
37 | else
38 | {
39 | throw new ArgumentException(file.FullName + " is not a supported image file.");
40 | }
41 | }
42 |
43 | public static string GetImageAsBase64(FileInfo file)
44 | {
45 | String contentType = GetContentType(file); // this does the file checks
46 | byte[] imageArray = File.ReadAllBytes(file.FullName);
47 | return Convert.ToBase64String(imageArray);
48 | }
49 |
50 | public static string GetImageAsDataUri(FileInfo file)
51 | {
52 | String contentType = GetContentType(file);
53 | String base64Content = GetImageAsBase64(file);
54 |
55 | return "data:" + contentType + ";base64," + base64Content;
56 | }
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/Structurizr.Core/Util/Url.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr.Util
4 | {
5 |
6 | public class Url
7 | {
8 |
9 | public static bool IsUrl(string urlAsString)
10 | {
11 | if (urlAsString != null && urlAsString.Trim().Length > 0)
12 | {
13 | Uri uri;
14 | return Uri.TryCreate(urlAsString, UriKind.Absolute, out uri);
15 | }
16 |
17 | return false;
18 | }
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/Animation.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr
5 | {
6 |
7 | [DataContract]
8 | public sealed class Animation
9 | {
10 |
11 | [DataMember(Name = "order", EmitDefaultValue = false)]
12 | public int Order { get; internal set; }
13 |
14 | private HashSet _elements;
15 |
16 | [DataMember(Name = "elements", EmitDefaultValue = false)]
17 | public ISet Elements
18 | {
19 | get
20 | {
21 | return new HashSet(_elements);
22 | }
23 |
24 | internal set
25 | {
26 | _elements = new HashSet(value);
27 | }
28 | }
29 |
30 | private HashSet _relationships;
31 |
32 | [DataMember(Name = "relationships", EmitDefaultValue = false)]
33 | public ISet Relationships
34 | {
35 | get
36 | {
37 | return new HashSet(_relationships);
38 | }
39 |
40 | internal set
41 | {
42 | _relationships = new HashSet(value);
43 | }
44 | }
45 |
46 | internal Animation()
47 | {
48 | _elements = new HashSet();
49 | _relationships = new HashSet();
50 | }
51 |
52 | internal Animation(int order, ISet elements, ISet relationships) : this()
53 | {
54 | Order = order;
55 |
56 | foreach (Element element in elements)
57 | {
58 | _elements.Add(element.Id);
59 | }
60 |
61 | foreach (Relationship relationship in relationships)
62 | {
63 | _relationships.Add(relationship.Id);
64 | }
65 | }
66 |
67 | }
68 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Border.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum Border
4 | {
5 |
6 | Solid,
7 | Dashed,
8 | Dotted
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/Branding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 | using Structurizr.Util;
4 |
5 | namespace Structurizr
6 | {
7 |
8 | [DataContract]
9 | public sealed class Branding
10 | {
11 |
12 | [DataMember(Name = "font", EmitDefaultValue = false)]
13 | public Font Font;
14 |
15 | private string _logo;
16 |
17 | [DataMember(Name = "logo", EmitDefaultValue = false)]
18 | public string Logo
19 | {
20 | get { return _logo; }
21 | set
22 | {
23 | if (value != null && value.Trim().Length > 0)
24 | {
25 | if (Url.IsUrl(value) || value.StartsWith("data:image/"))
26 | {
27 | _logo = value.Trim();
28 | }
29 | else {
30 | throw new ArgumentException(value + " is not a valid URL.");
31 | }
32 | }
33 | }
34 | }
35 |
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Color.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | namespace Structurizr
4 | {
5 | public class Color
6 | {
7 |
8 | public static bool IsHexColorCode(string colorAsString)
9 | {
10 | return colorAsString != null && Regex.IsMatch(colorAsString, "^#[A-Fa-f0-9]{6}");
11 | }
12 |
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/ColorPair.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr
5 | {
6 |
7 | [DataContract]
8 | public sealed class ColorPair
9 | {
10 |
11 | private string _background;
12 | private string _foreground;
13 |
14 | internal ColorPair()
15 | { }
16 |
17 | public ColorPair(string background, string foreground)
18 | {
19 | this.Background = background;
20 | this.Foreground = foreground;
21 | }
22 |
23 | [DataMember(Name = "background", EmitDefaultValue = false)]
24 | public string Background
25 | {
26 | get { return this._background; }
27 | set
28 | {
29 | if (Color.IsHexColorCode(value))
30 | {
31 | this._background = value.ToLower();
32 | }
33 | else
34 | {
35 | throw new ArgumentException("'" + value + "' is not a valid hex color code.");
36 | }
37 | }
38 | }
39 |
40 | [DataMember(Name = "foreground", EmitDefaultValue = false)]
41 | public string Foreground
42 | {
43 | get { return this._foreground; }
44 | set
45 | {
46 | if (Color.IsHexColorCode(value))
47 | {
48 | this._foreground = value.ToLower();
49 | }
50 | else
51 | {
52 | throw new ArgumentException("'" + value + "' is not a valid hex color code.");
53 | }
54 | }
55 | }
56 |
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/Dimensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.Serialization;
3 |
4 | namespace Structurizr
5 | {
6 | [DataContract]
7 | public class Dimensions
8 | {
9 |
10 | private int _width;
11 |
12 | ///
13 | /// The width (pixels).
14 | ///
15 | [DataMember(Name = "width", EmitDefaultValue = false)]
16 | public int Width
17 | {
18 | get { return _width; }
19 |
20 | set
21 | {
22 | if (value < 0)
23 | {
24 | throw new ArgumentException("The width must be a positive integer.");
25 | }
26 |
27 | _width = value;
28 | }
29 | }
30 |
31 | private int _height;
32 |
33 | ///
34 | /// The height (pixels).
35 | ///
36 | [DataMember(Name = "height", EmitDefaultValue = false)]
37 | public int Height
38 | {
39 | get { return _height; }
40 |
41 | set
42 | {
43 | if (value < 0)
44 | {
45 | throw new ArgumentException("The height must be a positive integer.");
46 | }
47 |
48 | _height = value;
49 | }
50 | }
51 |
52 | internal Dimensions()
53 | {
54 | }
55 |
56 | public Dimensions(int width, int height)
57 | {
58 | Width = width;
59 | Height = height;
60 | }
61 |
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/ElementNotPermittedInViewException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | public sealed class ElementNotPermittedInViewException : Exception
7 | {
8 |
9 | internal ElementNotPermittedInViewException(string message) : base(message)
10 | {
11 | }
12 |
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/FilterMode.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum FilterMode
4 | {
5 |
6 | Include,
7 | Exclude
8 |
9 | }
10 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/FilteredView.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Runtime.Serialization;
3 | using Newtonsoft.Json;
4 |
5 | namespace Structurizr
6 | {
7 | ///
8 | /// Represents a view on top of a view, which can be used to include or exclude specific elements.
9 | ///
10 | [DataContract]
11 | public sealed class FilteredView
12 | {
13 |
14 | [DataMember(Name="key", EmitDefaultValue=false)]
15 | public string Key { get; internal set; }
16 |
17 | public View View { get; internal set; }
18 |
19 | [DataMember(Name="description", EmitDefaultValue=false)]
20 | public string Description { get; internal set; }
21 |
22 | [DataMember(Name="mode", EmitDefaultValue=true)]
23 | public FilterMode Mode { get; internal set; }
24 |
25 | [DataMember(Name="tags", EmitDefaultValue=false)]
26 | public ISet Tags { get; internal set; }
27 |
28 | private string _baseViewKey;
29 |
30 | [DataMember(Name="baseViewKey", EmitDefaultValue=false)]
31 | public string BaseViewKey
32 | {
33 | get
34 | {
35 | if (View != null)
36 | {
37 | return View.Key;
38 | }
39 | else
40 | {
41 | return _baseViewKey;
42 | }
43 | }
44 | set { _baseViewKey = value; }
45 | }
46 |
47 | [JsonConstructor]
48 | internal FilteredView()
49 | {
50 | Mode = FilterMode.Exclude;
51 | Tags = new HashSet();
52 | }
53 |
54 | internal FilteredView(StaticView view, string key, string description, FilterMode mode, params string[] tags) : this()
55 | {
56 | View = view;
57 | Key = key;
58 | Description = description;
59 | Mode = mode;
60 |
61 | if (tags != null)
62 | {
63 | foreach (string tag in tags)
64 | {
65 | Tags.Add(tag);
66 | }
67 | }
68 | }
69 |
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Font.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.Serialization;
5 | using System.Text;
6 |
7 | namespace Structurizr
8 | {
9 |
10 | [DataContract]
11 | public sealed class Font
12 | {
13 |
14 | private string _url;
15 |
16 | [DataMember(Name = "name", EmitDefaultValue = false)]
17 | public string Name;
18 |
19 | ///
20 | /// The URL where more information about this element can be found.
21 | ///
22 | [DataMember(Name = "url", EmitDefaultValue = false)]
23 | public string Url
24 | {
25 | get
26 | {
27 | return _url;
28 | }
29 |
30 | set
31 | {
32 | if (value != null && value.Trim().Length > 0)
33 | {
34 | if (Util.Url.IsUrl(value))
35 | {
36 | this._url = value;
37 | }
38 | else
39 | {
40 | throw new ArgumentException(value + " is not a valid URL.");
41 | }
42 | }
43 | }
44 | }
45 |
46 | internal Font()
47 | {
48 | }
49 |
50 | public Font(string name)
51 | {
52 | this.Name = name;
53 | }
54 |
55 | public Font(string name, string url)
56 | {
57 | this.Name = name;
58 | this.Url = url;
59 | }
60 |
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/LayoutMergeStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | ///
5 | /// A pluggable strategy that can be used to copy layout information from one version of a view to another.
6 | ///
7 | public interface LayoutMergeStrategy
8 | {
9 |
10 | ///
11 | /// Attempts to copy the visual layout information (e.g. x,y coordinates) of elements and relationships
12 | /// from the specified source view into the specified destination view.
13 | ///
14 | /// the source view (e.g. the version stored by the Structurizr service)
15 | /// the destination View (e.g. the new version, created locally with code)
16 | void CopyLayoutInformation(View viewWithLayoutInformation, View viewWithoutLayoutInformation);
17 |
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/MetadataSymbols.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr.Core.View
2 | {
3 |
4 | ///
5 | /// The type of symbols to use when rendering metadata.
6 | ///
7 | public enum MetadataSymbols
8 | {
9 |
10 | SquareBrackets,
11 | RoundBrackets,
12 | CurlyBrackets,
13 | AngleBrackets,
14 | DoubleAngleBrackets,
15 | None
16 |
17 | }
18 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/ParallelSequenceCounter.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | internal class ParallelSequenceCounter : SequenceCounter
5 | {
6 |
7 | internal ParallelSequenceCounter(SequenceCounter parent) : base(parent)
8 | {
9 | Sequence = Parent.Sequence;
10 | }
11 |
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/RankDirection.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum RankDirection
4 | {
5 | TopBottom,
6 | BottomTop,
7 | LeftRight,
8 | RightLeft
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Routing.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum Routing
4 | {
5 | Direct,
6 | Curved,
7 | Orthogonal
8 | }
9 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/SequenceCounter.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | internal class SequenceCounter
5 | {
6 |
7 | internal readonly SequenceCounter Parent;
8 | internal int Sequence { get; set; }
9 |
10 | internal SequenceCounter()
11 | {
12 | }
13 |
14 | internal SequenceCounter(SequenceCounter parent)
15 | {
16 | Parent = parent;
17 | }
18 |
19 | internal virtual void Increment()
20 | {
21 | Sequence++;
22 | }
23 |
24 | public virtual string AsString()
25 | {
26 | return "" + Sequence;
27 | }
28 |
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/SequenceNumber.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | internal class SequenceNumber
4 | {
5 |
6 | private SequenceCounter _counter = new SequenceCounter();
7 |
8 | internal SequenceNumber()
9 | {
10 | }
11 |
12 | internal string GetNext()
13 | {
14 | _counter.Increment();
15 | return _counter.AsString();
16 | }
17 |
18 | internal void StartParallelSequence()
19 | {
20 | _counter = new ParallelSequenceCounter(_counter);
21 | }
22 |
23 | internal void EndParallelSequence(bool endAllParallelSequencesAndContinueNumbering)
24 | {
25 | if (endAllParallelSequencesAndContinueNumbering)
26 | {
27 | int sequence = _counter.Sequence;
28 | _counter = _counter.Parent;
29 | _counter.Sequence = sequence;
30 | }
31 | else
32 | {
33 | _counter = _counter.Parent;
34 | }
35 | }
36 |
37 | }
38 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Shape.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 | public enum Shape
4 | {
5 |
6 | Box,
7 | RoundedBox,
8 | Circle,
9 | Ellipse,
10 | Hexagon,
11 | Diamond,
12 | Cylinder,
13 | Pipe,
14 | Person,
15 | Robot,
16 | Folder,
17 | WebBrowser,
18 | MobileDevicePortrait,
19 | MobileDeviceLandscape,
20 | Component
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/SystemContextView.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// A system context view.
8 | ///
9 | [DataContract]
10 | public sealed class SystemContextView : StaticView
11 | {
12 |
13 | public override string Name
14 | {
15 | get
16 | {
17 | return SoftwareSystem.Name + " - System Context";
18 | }
19 | }
20 |
21 | ///
22 | /// Determines whether the enterprise boundary (to differentiate "internal" elements from "external" elements") should be visible on the resulting diagram.
23 | ///
24 | [DataMember(Name = "enterpriseBoundaryVisible", EmitDefaultValue = false)]
25 | public bool? EnterpriseBoundaryVisible { get; set; }
26 |
27 | internal SystemContextView() : base()
28 | {
29 | }
30 |
31 | internal SystemContextView(SoftwareSystem softwareSystem, string key, string description) : base(softwareSystem, key, description)
32 | {
33 | AddElement(softwareSystem, true);
34 | }
35 |
36 | protected override void CheckElementCanBeAdded(Element element)
37 | {
38 | if (element is Person || element is SoftwareSystem)
39 | {
40 | // all good
41 | }
42 | else
43 | {
44 | throw new ElementNotPermittedInViewException("Only people and software systems can be added to a system context view.");
45 | }
46 | }
47 |
48 | ///
49 | /// Adds all software systems and all people to this view.
50 | ///
51 | public override void AddAllElements()
52 | {
53 | AddAllSoftwareSystems();
54 | AddAllPeople();
55 | }
56 |
57 | ///
58 | /// Adds people and software systems that are directly related to the given element.
59 | ///
60 | public override void AddNearestNeighbours(Element element)
61 | {
62 | AddNearestNeighbours(element, typeof(SoftwareSystem));
63 | AddNearestNeighbours(element, typeof(Person));
64 | }
65 |
66 | ///
67 | /// Adds the default set of elements to this view.
68 | ///
69 | public override void AddDefaultElements()
70 | {
71 | AddNearestNeighbours(SoftwareSystem, typeof(Person));
72 | AddNearestNeighbours(SoftwareSystem, typeof(SoftwareSystem));
73 | }
74 |
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/Terminology.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr.Core.View
4 | {
5 |
6 | ///
7 | /// Provides a way for the terminology on diagrams, etc to be modified (e.g. language translations).
8 | ///
9 | [DataContract]
10 | public sealed class Terminology
11 | {
12 |
13 | [DataMember(Name = "enterprise", EmitDefaultValue = false)]
14 | public string Enterprise;
15 |
16 | [DataMember(Name = "person", EmitDefaultValue = false)]
17 | public string Person;
18 |
19 | [DataMember(Name = "softwareSystem", EmitDefaultValue = false)]
20 | public string SoftwareSystem;
21 |
22 | [DataMember(Name = "container", EmitDefaultValue = false)]
23 | public string Container;
24 |
25 | [DataMember(Name = "component", EmitDefaultValue = false)]
26 | public string Component;
27 |
28 | [DataMember(Name = "code", EmitDefaultValue = false)]
29 | public string Code;
30 |
31 | [DataMember(Name = "deploymentNode", EmitDefaultValue = false)]
32 | public string DeploymentNode;
33 |
34 | [DataMember(Name = "infrastructureNode", EmitDefaultValue = false)]
35 | public string InfrastructureNode;
36 |
37 | [DataMember(Name = "relationship", EmitDefaultValue = false)]
38 | public string Relationship;
39 |
40 | }
41 | }
--------------------------------------------------------------------------------
/Structurizr.Core/View/Vertex.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 |
3 | namespace Structurizr
4 | {
5 |
6 | ///
7 | /// The X, Y coordinate of a bend in a line.
8 | ///
9 | [DataContract]
10 | public sealed class Vertex
11 | {
12 |
13 | internal Vertex()
14 | {
15 | }
16 |
17 | internal Vertex(int x, int y)
18 | {
19 | X = x;
20 | Y = y;
21 | }
22 |
23 | ///
24 | /// The horizontal position of the vertex when rendered.
25 | ///
26 | [DataMember(Name="x", EmitDefaultValue=false)]
27 | public int? X { get; set; }
28 |
29 |
30 | ///
31 | /// The vertical position of the vertex when rendered.
32 | ///
33 | [DataMember(Name="y", EmitDefaultValue=false)]
34 | public int? Y { get; set; }
35 |
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/Structurizr.Core/View/ViewSortOrder.cs:
--------------------------------------------------------------------------------
1 | namespace Structurizr
2 | {
3 |
4 | ///
5 | /// Allows the sort order of views to be customized as follows:
6 | ///
7 | /// - Default: Views are grouped by the software system they are associated with, and then sorted by type (System Landscape, System Context, Container, Component, Dynamic and Deployment) within these groups.
8 | /// - Type: Views are sorted by type (System Landscape, System Context, Container, Component, Dynamic and Deployment).
9 | /// - Key: Views are sorted by the view key (alphabetical, ascending).
10 | ///
11 | public enum ViewSortOrder
12 | {
13 |
14 | Default,
15 | Type,
16 | Key
17 |
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/Structurizr.Core/Workspace.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 | using Structurizr.Documentation;
3 |
4 | namespace Structurizr
5 | {
6 |
7 | ///
8 | /// Represents a Structurizr workspace, which is a wrapper for a software architecture model and the associated views.
9 | ///
10 | [DataContract]
11 | public class Workspace : AbstractWorkspace
12 | {
13 |
14 | ///
15 | /// The software architecture model.
16 | ///
17 | /// The software architecture model.
18 | [DataMember(Name = "model", EmitDefaultValue = false)]
19 | public Model Model { get; set; }
20 |
21 | ///
22 | /// The set of views onto a software architecture model.
23 | ///
24 | /// The set of views onto a software architecture model.
25 | [DataMember(Name = "views", EmitDefaultValue = false)]
26 | public ViewSet Views { get; set; }
27 |
28 | ///
29 | /// The documentation associated with this workspace.
30 | ///
31 | [DataMember(Name = "documentation", EmitDefaultValue = false)]
32 | public Documentation.Documentation Documentation { get; set; }
33 |
34 | ///
35 | /// Initializes a new instance of the class.
36 | ///
37 | /// The name of the workspace..
38 | /// A short description of the workspace..
39 | public Workspace(string name, string description) : base(name, description)
40 | {
41 | this.Model = new Model();
42 | this.Views = new ViewSet(Model);
43 | this.Documentation = new Documentation.Documentation(Model);
44 | }
45 |
46 | public void Hydrate()
47 | {
48 | this.Views.Model = Model;
49 | this.Documentation.Model = Model;
50 |
51 | this.Model.Hydrate();
52 | this.Views.Hydrate();
53 | this.Documentation.Hydrate();
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Structurizr.Examples/ClientSideEncryption.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.Api;
2 | using Structurizr.Encryption;
3 |
4 | namespace Structurizr.Examples
5 | {
6 |
7 | ///
8 | /// This is an example of how to use client-side encryption.
9 | ///
10 | /// You can see the workspace online at https://structurizr.com/share/41
11 | /// (the passphrase is "password")
12 | ///
13 | public class ClientSideEncryption
14 | {
15 |
16 | private const long WorkspaceId = 41;
17 | private const string ApiKey = "key";
18 | private const string ApiSecret = "secret";
19 |
20 | static void Main()
21 | {
22 | Workspace workspace = new Workspace("Client-side encrypted workspace", "This is a client-side encrypted workspace. The passphrase is 'password'.");
23 | Model model = workspace.Model;
24 |
25 | Person user = model.AddPerson("User", "A user of my software system.");
26 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
27 | user.Uses(softwareSystem, "Uses");
28 |
29 | ViewSet viewSet = workspace.Views;
30 | SystemContextView contextView = viewSet.CreateSystemContextView(softwareSystem, "SystemContext", "An example of a System Context diagram.");
31 | contextView.AddAllSoftwareSystems();
32 | contextView.AddAllPeople();
33 |
34 | Styles styles = viewSet.Configuration.Styles;
35 | styles.Add(new ElementStyle(Tags.SoftwareSystem) { Background = "#d34407", Color = "#ffffff" });
36 | styles.Add(new ElementStyle(Tags.Person) { Background = "#f86628", Color = "#ffffff", Shape = Shape.Person });
37 |
38 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
39 | structurizrClient.EncryptionStrategy = new AesEncryptionStrategy("password");
40 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
41 | }
42 |
43 | }
44 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/CorporateBranding.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using Structurizr.Api;
3 | using Structurizr.Documentation;
4 | using Structurizr.Util;
5 |
6 | namespace Structurizr.Examples
7 | {
8 |
9 | ///
10 | /// This is a simple example that illustrates the corporate branding features of Structurizr, including:
11 | /// - A logo, which is included in diagrams and documentation.
12 | ///
13 | /// You can see the live workspace at https://structurizr.com/share/35031
14 | ///
15 | public class CorporateBranding
16 | {
17 |
18 | private const long WorkspaceId = 35031;
19 | private const string ApiKey = "key";
20 | private const string ApiSecret = "secret";
21 |
22 | static void Main()
23 | {
24 | Workspace workspace = new Workspace("Corporate Branding", "This is a model of my software system.");
25 | Model model = workspace.Model;
26 |
27 | Person user = model.AddPerson("User", "A user of my software system.");
28 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
29 | user.Uses(softwareSystem, "Uses");
30 |
31 | ViewSet views = workspace.Views;
32 | SystemContextView contextView = views.CreateSystemContextView(softwareSystem, "SystemContext", "An example of a System Context diagram.");
33 | contextView.AddAllSoftwareSystems();
34 | contextView.AddAllPeople();
35 |
36 | Styles styles = views.Configuration.Styles;
37 | styles.Add(new ElementStyle(Tags.Person) { Shape = Shape.Person });
38 |
39 | StructurizrDocumentationTemplate template = new StructurizrDocumentationTemplate(workspace);
40 | template.AddContextSection(softwareSystem, Format.Markdown, "Here is some context about the software system...\n\n");
41 |
42 | Branding branding = views.Configuration.Branding;
43 | branding.Logo = ImageUtils.GetImageAsDataUri(new FileInfo("structurizr-logo.png"));
44 |
45 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
46 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
47 | }
48 |
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0001-record-architecture-decisions.md:
--------------------------------------------------------------------------------
1 | # 1. Record architecture decisions
2 |
3 | Date: 2016-02-12
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | We need to record the architectural decisions made on this project.
12 |
13 | ## Decision
14 |
15 | We will use Architecture Decision Records, as described by Michael Nygard in this article: [http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
16 |
17 | ## Consequences
18 |
19 | See Michael Nygard's article, linked above.
20 |
21 | ---
22 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0002-implement-as-shell-scripts.md:
--------------------------------------------------------------------------------
1 | # 2. Implement as shell scripts
2 |
3 | Date: 2016-02-12
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | ADRs are plain text files stored in a subdirectory of the project.
12 |
13 | The tool needs to create new files and apply small edits to
14 | the Status section of existing files.
15 |
16 | ## Decision
17 |
18 | The tool is implemented as shell scripts that use standard Unix
19 | tools -- grep, sed, awk, etc.
20 |
21 | ## Consequences
22 |
23 | The tool won't support Windows. Being plain text files, ADRs can
24 | be created by hand and edited in any text editor. This tool just
25 | makes the process more convenient.
26 |
27 | Development will have to cope with differences between Unix
28 | variants, particularly Linux and MacOS X.
29 |
30 | ---
31 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0003-single-command-with-subcommands.md:
--------------------------------------------------------------------------------
1 | # 3. Single command with subcommands
2 |
3 | Date: 2016-02-12
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | The tool provides a number of related commands to create
12 | and manipulate architecture decision records.
13 |
14 | How can the user find out about the commands that are available?
15 |
16 | ## Decision
17 |
18 | The tool defines a single command, called `adr`.
19 |
20 | The first argument to `adr` (the subcommand) specifies the
21 | action to perform. Further arguments are interpreted by the
22 | subcommand.
23 |
24 | Running `adr` without any arguments lists the available
25 | subcommands.
26 |
27 | Subcommands are implemented as scripts in the same
28 | directory as the `adr` script. E.g. the subcommand `new` is
29 | implemented as the script `adr-new`, the subcommand `help`
30 | as the script `adr-help` and so on.
31 |
32 | Helper scripts that are part of the implementation but not
33 | subcommands follow a different naming convention, so that
34 | subcommands can be listed by filtering and transforming script
35 | file names.
36 |
37 | ## Consequences
38 |
39 | Users can more easily explore the capabilities of the tool.
40 |
41 | Users are already used to this style of command-line tool. For
42 | example, Git works this way.
43 |
44 | Each subcommand can be implemented in the most appropriate
45 | language.
46 |
47 | ---
48 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
49 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0004-markdown-format.md:
--------------------------------------------------------------------------------
1 | # 4. Markdown format
2 |
3 | Date: 2016-02-12
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | The decision records must be stored in a plain text format:
12 |
13 | * This works well with version control systems.
14 |
15 | * It allows the tool to modify the status of records and insert
16 | hyperlinks when one decision supercedes another.
17 |
18 | * Decisions can be read in the terminal, IDE, version control
19 | browser, etc.
20 |
21 | People will want to use some formatting: lists, code examples,
22 | and so on.
23 |
24 | People will want to view the decision records in a more readable
25 | format than plain text, and maybe print them out.
26 |
27 |
28 | ## Decision
29 |
30 | Record architecture decisions in [Markdown format](https://daringfireball.net/projects/markdown/).
31 |
32 | ## Consequences
33 |
34 | Decisions can be read in the terminal.
35 |
36 | Decisions will be formatted nicely and hyperlinked by the
37 | browsers of project hosting sites like GitHub and Bitbucket.
38 |
39 | Tools like [Pandoc](http://pandoc.org/) can be used to convert
40 | the decision records into HTML or PDF.
41 |
42 | ---
43 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0005-help-comments.md:
--------------------------------------------------------------------------------
1 | # 5. Help comments
2 |
3 | Date: 2016-02-13
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | The tool will have a `help` subcommand to provide documentation
12 | for users.
13 |
14 | It's nice to have usage documentation in the script files
15 | themselves, in comments. When reading the code, that's the first
16 | place to look for information about how to run a script.
17 |
18 | ## Decision
19 |
20 | Write usage documentation in comments in the source file.
21 |
22 | Distinguish between documentation comments and normal comments.
23 | Documentation comments have two hash characters at the start of
24 | the line.
25 |
26 | The `adr help` command can parse comments out from the script
27 | using the standard Unix tools `grep` and `cut`.
28 |
29 | ## Consequences
30 |
31 | No need to maintain help text in a separate file.
32 |
33 | Help text can easily be kept up to date as the script is edited.
34 |
35 | There's no automated check that the help text is up to date. The
36 | tests do not work well as documentation for users, and the help
37 | text is not easily cross-checked against the code.
38 |
39 | This won't work if any subcommands are not implemented as scripts
40 | that use '#' as a comment character.
41 |
42 | ---
43 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0006-packaging-and-distribution-in-other-version-control-repositories.md:
--------------------------------------------------------------------------------
1 | # 6. Packaging and distribution in other version control repositories
2 |
3 | Date: 2016-02-16
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | Users want to install adr-tools with their preferred package
12 | manager. For example, Ubuntu users use `apt`, RedHat users use
13 | `yum` and Mac OS X users use [Homebrew](http://brew.sh).
14 |
15 | The developers of `adr-tools` don't know how, nor have permissions,
16 | to use all these packaging and distribution systems. Therefore packaging
17 | and distribution must be done by "downstream" parties.
18 |
19 | The developers of the tool should not favour any one particular
20 | packaging and distribution solution.
21 |
22 | ## Decision
23 |
24 | The `adr-tools` project will not contain any packaging or
25 | distribution scripts and config.
26 |
27 | Packaging and distribution will be managed by other projects in
28 | separate version control repositories.
29 |
30 | ## Consequences
31 |
32 | The git repo of this project will be simpler.
33 |
34 | Eventually, users will not have to use Git to get the software.
35 |
36 | We will have to tag releases in the `adr-tools` repository so that
37 | packaging projects know what can be published and how it should be
38 | identified.
39 |
40 | We will document how users can install the software in this
41 | project's README file.
42 |
43 | ---
44 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0007-invoke-adr-config-executable-to-get-configuration.md:
--------------------------------------------------------------------------------
1 | # 7. Invoke adr-config executable to get configuration
2 |
3 | Date: 2016-12-17
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | Packagers (e.g. Homebrew developers) want to configure adr-tools to match the conventions of their installation.
12 |
13 | Currently, this is done by sourcing a file `config.sh`, which should sit beside the `adr` executable.
14 |
15 | This name is too common.
16 |
17 | The `config.sh` file is not executable, and so doesn't belong in a bin directory.
18 |
19 | ## Decision
20 |
21 | Replace `config.sh` with an executable, named `adr-config` that outputs configuration.
22 |
23 | Each script in ADR Tools will eval the output of `adr-config` to configure itself.
24 |
25 | ## Consequences
26 |
27 | Configuration within ADR Tools is a little more complicated.
28 |
29 | Packagers can write their own implementation of `adr-config` that outputs configuration that matches the platform's installation conventions, and deploy it next to the `adr` script.
30 |
31 | To make development easier, the implementation of `adr-config` in the project's src/ directory will output configuration that lets the tool to run from the src/ directory without any installation step. (Packagers should not include this script in a deployable package.)
32 |
33 | ---
34 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/adr/0008-use-iso-8601-format-for-dates.md:
--------------------------------------------------------------------------------
1 | # 8. Use ISO 8601 Format for Dates
2 |
3 | Date: 2017-02-21
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | `adr-tools` seeks to communicate the history of architectural decisions of a
12 | project. An important component of the history is the time at which a decision
13 | was made.
14 |
15 | To communicate effectively, `adr-tools` should present information as
16 | unambiguously as possible. That means that culture-neutral data formats should
17 | be preferred over culture-specific formats.
18 |
19 | Existing `adr-tools` deployments format dates as `dd/mm/yyyy` by default. That
20 | formatting is common formatting in the United Kingdom (where the `adr-tools`
21 | project was originally written), but is easily confused with the `mm/dd/yyyy`
22 | format preferred in the United States.
23 |
24 | The default date format may be overridden by setting `ADR_DATE` in `config.sh`.
25 |
26 | ## Decision
27 |
28 | `adr-tools` will use the ISO 8601 format for dates: `yyyy-mm-dd`
29 |
30 | ## Consequences
31 |
32 | Dates are displayed in a standard, culture-neutral format.
33 |
34 | The UK-style and ISO 8601 formats can be distinguished by their separator
35 | character. The UK-style dates used a slash (`/`), while the ISO dates use a
36 | hyphen (`-`).
37 |
38 | Prior to this decision, `adr-tools` was deployed using the UK format for dates.
39 | After adopting the ISO 8601 format, existing deployments of `adr-tools` must do
40 | one of the following:
41 |
42 | * Accept mixed formatting of dates within their documentation library.
43 | * Update existing documents to use ISO 8601 dates by running `adr upgrade-repository`
44 |
45 | ---
46 | This Architecture Decision Record (ADR) was written by Nat Pryce as a part of [adr-tools](https://github.com/npryce/adr-tools), and is reproduced here under the [Creative Commons Attribution 4.0 International (CC BY 4.0) license](https://creativecommons.org/licenses/by/4.0/).
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/01-introduction-and-goals.adoc:
--------------------------------------------------------------------------------
1 | == Introduction and Goals
2 |
3 | === Requirements Overview
4 |
5 | === Quality Goals
6 |
7 | === Stakeholders
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/02-architecture-constraints.adoc:
--------------------------------------------------------------------------------
1 | == Architecture Constraints
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/03-system-scope-and-context.adoc:
--------------------------------------------------------------------------------
1 | == Context and Scope
2 |
3 | image::embed:SystemContext[]
4 |
5 | === Business Context
6 |
7 | === Technical Context
8 |
9 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/04-solution-strategy.adoc:
--------------------------------------------------------------------------------
1 | == Solution Strategy
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/05-building-block-view.adoc:
--------------------------------------------------------------------------------
1 | == Building Block View
2 |
3 | === Level 1
4 |
5 | === Level 2
6 |
7 | === Level 3
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/06-runtime-view.adoc:
--------------------------------------------------------------------------------
1 | == Runtime View
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/07-deployment-view.adoc:
--------------------------------------------------------------------------------
1 | == Deployment View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/08-crosscutting-concepts.adoc:
--------------------------------------------------------------------------------
1 | == Crosscutting Concepts
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/09-architecture-decisions.adoc:
--------------------------------------------------------------------------------
1 | == Architecture Decisions
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/10-quality-requirements.adoc:
--------------------------------------------------------------------------------
1 | == Quality Requirements
2 |
3 | === Quality Tree
4 |
5 | === Quality Scenarios
6 |
7 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/11-risks-and-technical-debt.adoc:
--------------------------------------------------------------------------------
1 | == Risks and Technical Debt
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/asciidoc/12-glossary.adoc:
--------------------------------------------------------------------------------
1 | == Glossary
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/01-introduction-and-goals.md:
--------------------------------------------------------------------------------
1 | ## Introduction and Goals
2 |
3 | ### Requirements Overview
4 |
5 | ### Quality Goals
6 |
7 | ### Stakeholders
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/02-architecture-constraints.md:
--------------------------------------------------------------------------------
1 | ## Architecture Constraints
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/03-system-scope-and-context.md:
--------------------------------------------------------------------------------
1 | ## Context and Scope
2 |
3 | 
4 |
5 | ### Business Context
6 |
7 | ### Technical Context
8 |
9 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/04-solution-strategy.md:
--------------------------------------------------------------------------------
1 | ## Solution Strategy
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/05-building-block-view.md:
--------------------------------------------------------------------------------
1 | ## Building Block View
2 |
3 | ### Level 1
4 |
5 | ### Level 2
6 |
7 | ### Level 3
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/06-runtime-view.md:
--------------------------------------------------------------------------------
1 | ## Runtime View
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/07-deployment-view.md:
--------------------------------------------------------------------------------
1 | ## Deployment View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/08-crosscutting-concepts.md:
--------------------------------------------------------------------------------
1 | ## Crosscutting Concepts
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/09-architecture-decisions.md:
--------------------------------------------------------------------------------
1 | ## Architecture Decisions
2 |
3 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/10-quality-requirements.md:
--------------------------------------------------------------------------------
1 | ## Quality Requirements
2 |
3 | ### Quality Tree
4 |
5 | ### Quality Scenarios
6 |
7 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/11-risks-and-technical-debt.md:
--------------------------------------------------------------------------------
1 | ## Risks and Technical Debt
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/arc42/markdown/12-glossary.md:
--------------------------------------------------------------------------------
1 | ## Glossary
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/01-context.adoc:
--------------------------------------------------------------------------------
1 | == Context
2 |
3 | image::embed:SystemContext[]
4 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/02-functional-overview.adoc:
--------------------------------------------------------------------------------
1 | == Functional Overview
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/03-quality-attributes.adoc:
--------------------------------------------------------------------------------
1 | == Quality Attributes
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/04-constraints.adoc:
--------------------------------------------------------------------------------
1 | == Constraints
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/05-principles.adoc:
--------------------------------------------------------------------------------
1 | == Principles
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/06-software-architecture.adoc:
--------------------------------------------------------------------------------
1 | == Software Architecture
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/07-data.adoc:
--------------------------------------------------------------------------------
1 | == Data
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/08-infrastructure-architecture.adoc:
--------------------------------------------------------------------------------
1 | == Infrastructure Architecture
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/09-deployment.adoc:
--------------------------------------------------------------------------------
1 | == Deployment
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/10-development-environment.adoc:
--------------------------------------------------------------------------------
1 | == Development Environment
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/11-operation-and-support.adoc:
--------------------------------------------------------------------------------
1 | == Operations and Support
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/asciidoc/12-decision-log.adoc:
--------------------------------------------------------------------------------
1 | == Decision Log
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/01-context.md:
--------------------------------------------------------------------------------
1 | ## Context
2 |
3 | 
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/02-functional-overview.md:
--------------------------------------------------------------------------------
1 | ## Functional Overview
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/03-quality-attributes.md:
--------------------------------------------------------------------------------
1 | ## Quality Attributes
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/04-constraints.md:
--------------------------------------------------------------------------------
1 | ## Constraints
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/05-principles.md:
--------------------------------------------------------------------------------
1 | ## Principles
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/06-software-architecture.md:
--------------------------------------------------------------------------------
1 | ## Software Architecture
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/07-data.md:
--------------------------------------------------------------------------------
1 | ## Data
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/08-infrastructure-architecture.md:
--------------------------------------------------------------------------------
1 | ## Infrastructure Architecture
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/09-deployment.md:
--------------------------------------------------------------------------------
1 | ## Deployment
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/10-development-environment.md:
--------------------------------------------------------------------------------
1 | ## Development Environment
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/11-operation-and-support.md:
--------------------------------------------------------------------------------
1 | ## Operations and Support
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/structurizr/markdown/12-decision-log.md:
--------------------------------------------------------------------------------
1 | ## Decision Log
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/01-introduction.adoc:
--------------------------------------------------------------------------------
1 | == Introduction
2 |
3 | === Purpose and Scope
4 |
5 | === Audience
6 |
7 | === Status
8 |
9 | === Architectural Design Approach
10 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/02-glossary.adoc:
--------------------------------------------------------------------------------
1 | == Glossary
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/03-system-stakeholders-and-requirements.adoc:
--------------------------------------------------------------------------------
1 | == System Stakeholders and Requirements
2 |
3 | === Stakeholders
4 |
5 | === Overview of Requirements
6 |
7 | === System Scenarios
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/04-architectural-forces.adoc:
--------------------------------------------------------------------------------
1 | == Architectural Forces
2 |
3 | === Goals
4 |
5 | === Constraints
6 |
7 | === Architectural Principles
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/01-architectural-views.adoc:
--------------------------------------------------------------------------------
1 | == Architectural Views
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/02-context-view.adoc:
--------------------------------------------------------------------------------
1 | === Context View
2 |
3 | image::embed:SystemContext[]
4 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/03-functional-view.adoc:
--------------------------------------------------------------------------------
1 | === Functional View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/04-information-view.adoc:
--------------------------------------------------------------------------------
1 | === Information View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/05-concurrency-view.adoc:
--------------------------------------------------------------------------------
1 | === Concurrency View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/06-deployment-view.adoc:
--------------------------------------------------------------------------------
1 | === Deployment View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/07-development-view.adoc:
--------------------------------------------------------------------------------
1 | === Development View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/05-architectural-views/08-operational-view.adoc:
--------------------------------------------------------------------------------
1 | === Operational View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/06-system-qualities.adoc:
--------------------------------------------------------------------------------
1 | == System Qualities
2 |
3 | === Performance and Scalability
4 |
5 | === Security
6 |
7 | === Availability and Resilience
8 |
9 | === Evolution
10 |
11 | === Other Qualities
12 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/asciidoc/07-appendices.adoc:
--------------------------------------------------------------------------------
1 | == Appendices
2 |
3 | === Decisions and Alternatives
4 |
5 | === Questions and Answers
6 |
7 | === References
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/01-introduction.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | ### Purpose and Scope
4 |
5 | ### Audience
6 |
7 | ### Status
8 |
9 | ### Architectural Design Approach
10 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/02-glossary.md:
--------------------------------------------------------------------------------
1 | ## Glossary
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/03-system-stakeholders-and-requirements.md:
--------------------------------------------------------------------------------
1 | ## System Stakeholders and Requirements
2 |
3 | ### Stakeholders
4 |
5 | ### Overview of Requirements
6 |
7 | ### System Scenarios
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/04-architectural-forces.md:
--------------------------------------------------------------------------------
1 | ## Architectural Forces
2 |
3 | ### Goals
4 |
5 | ### Constraints
6 |
7 | ### Architectural Principles
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/01-architectural-views.md:
--------------------------------------------------------------------------------
1 | ## Architectural Views
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/02-context-view.md:
--------------------------------------------------------------------------------
1 | ### Context View
2 |
3 | 
4 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/03-functional-view.md:
--------------------------------------------------------------------------------
1 | ### Functional View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/04-information-view.md:
--------------------------------------------------------------------------------
1 | ### Information View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/05-concurrency-view.md:
--------------------------------------------------------------------------------
1 | ### Concurrency View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/06-deployment-view.md:
--------------------------------------------------------------------------------
1 | ### Deployment View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/07-development-view.md:
--------------------------------------------------------------------------------
1 | ### Development View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/05-architectural-views/08-operational-view.md:
--------------------------------------------------------------------------------
1 | ### Operational View
2 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/06-system-qualities.md:
--------------------------------------------------------------------------------
1 | ## System Qualities
2 |
3 | ### Performance and Scalability
4 |
5 | ### Security
6 |
7 | ### Availability and Resilience
8 |
9 | ### Evolution
10 |
11 | ### Other Qualities
12 |
--------------------------------------------------------------------------------
/Structurizr.Examples/Documentation/viewpointsandperspectives/markdown/07-appendices.md:
--------------------------------------------------------------------------------
1 | ## Appendices
2 |
3 | ### Decisions and Alternatives
4 |
5 | ### Questions and Answers
6 |
7 | ### References
8 |
--------------------------------------------------------------------------------
/Structurizr.Examples/FilteredViews.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.Api;
2 |
3 | namespace Structurizr.Examples
4 | {
5 |
6 | ///
7 | /// An example of how to use filtered views to show "before" and "after" views of a software system.
8 | ///
9 | /// You can see the live diagrams at https://structurizr.com/public/19911
10 | ///
11 | public class FilteredViews
12 | {
13 |
14 | private const long WorkspaceId = 19911;
15 | private const string ApiKey = "";
16 | private const string ApiSecret = "";
17 |
18 | private const string CurrentState = "Current State";
19 | private const string FutureState = "Future State";
20 |
21 | static void Main()
22 | {
23 | Workspace workspace = new Workspace("Filtered Views", "An example of using filtered views.");
24 | Model model = workspace.Model;
25 |
26 | Person user = model.AddPerson("User", "A description of the user.");
27 | SoftwareSystem softwareSystemA = model.AddSoftwareSystem("Software System A", "A description of software system A.");
28 | SoftwareSystem softwareSystemB = model.AddSoftwareSystem("Software System B", "A description of software system B.");
29 | softwareSystemB.AddTags(FutureState);
30 |
31 | user.Uses(softwareSystemA, "Uses for tasks 1 and 2").AddTags(CurrentState);
32 | user.Uses(softwareSystemA, "Uses for task 1").AddTags(FutureState);
33 | user.Uses(softwareSystemB, "Uses for task 2").AddTags(FutureState);
34 |
35 | ViewSet views = workspace.Views;
36 | SystemLandscapeView systemLandscapeView = views.CreateSystemLandscapeView("EnterpriseContext", "An example Enterprise Context diagram.");
37 | systemLandscapeView.AddAllElements();
38 |
39 | views.CreateFilteredView(systemLandscapeView, "CurrentState", "The current context.", FilterMode.Exclude, FutureState);
40 | views.CreateFilteredView(systemLandscapeView, "FutureState", "The future state context after Software System B is live.", FilterMode.Exclude, CurrentState);
41 |
42 | Styles styles = views.Configuration.Styles;
43 | styles.Add(new ElementStyle(Tags.Element) { Color = "#ffffff" });
44 | styles.Add(new ElementStyle(Tags.SoftwareSystem) { Background = "#91a437", Shape = Shape.RoundedBox });
45 | styles.Add(new ElementStyle(Tags.Person) { Background = "#6a7b15", Shape = Shape.Person });
46 |
47 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
48 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
49 | }
50 |
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/FinancialRiskSystem/context.adoc:
--------------------------------------------------------------------------------
1 | == Context
2 |
3 | A global investment bank based in London, New York and Singapore trades (buys and sells) financial products with other banks (counterparties). When share prices on the stock markets move up or down, the bank either makes money or loses it. At the end of the working day, the bank needs to gain a view of how much risk they are exposed to (e.g. of losing money) by running some calculations on the data held about their trades. The bank has an existing Trade Data System (TDS) and Reference Data System (RDS) but need a new Risk System.
4 |
5 | image::embed:Context[]
6 |
7 | === Trade Data System
8 |
9 | The Trade Data System maintains a store of all trades made by the bank. It is already configured to generate a file-based XML export of trade data at the close of business (5pm) in New York. The export includes the following information for every trade made by the bank:
10 |
11 | * Trade ID
12 | * Date
13 | * Current trade value in US dollars
14 | * Counterparty ID
15 |
16 | === Reference Data System
17 |
18 | The Reference Data System maintains all of the reference data needed by the bank. This includes information about counterparties; each of which represents an individual, a bank, etc. A file-based XML export is also available and includes basic information about each counterparty. A new organisation-wide reference data system is due for completion in the next 3 months, with the current system eventually being decommissioned.
--------------------------------------------------------------------------------
/Structurizr.Examples/FinancialRiskSystem/context.md:
--------------------------------------------------------------------------------
1 | ## Context
2 |
3 | A global investment bank based in London, New York and Singapore trades (buys and sells) financial products with other banks (counterparties). When share prices on the stock markets move up or down, the bank either makes money or loses it. At the end of the working day, the bank needs to gain a view of how much risk they are exposed to (e.g. of losing money) by running some calculations on the data held about their trades. The bank has an existing Trade Data System (TDS) and Reference Data System (RDS) but need a new Risk System.
4 |
5 | 
6 |
7 | ### Trade Data System
8 |
9 | The Trade Data System maintains a store of all trades made by the bank. It is already configured to generate a file-based XML export of trade data at the close of business (5pm) in New York. The export includes the following information for every trade made by the bank:
10 |
11 | - Trade ID
12 | - Date
13 | - Current trade value in US dollars
14 | - Counterparty ID
15 |
16 | ### Reference Data System
17 |
18 | The Reference Data System maintains all of the reference data needed by the bank. This includes information about counterparties; each of which represents an individual, a bank, etc. A file-based XML export is also available and includes basic information about each counterparty. A new organisation-wide reference data system is due for completion in the next 3 months, with the current system eventually being decommissioned.
--------------------------------------------------------------------------------
/Structurizr.Examples/FinancialRiskSystem/functional-overview.md:
--------------------------------------------------------------------------------
1 | ## Functional Overview
2 |
3 | The high-level functional requirements for the new Risk System are as follows.
4 |
5 | 
6 |
7 | 1. Import trade data from the Trade Data System.
8 | 2. Import counterparty data from the Reference Data System.
9 | 3. Join the two sets of data together, enriching the trade data with information about the counterparty.
10 | 4. For each counterparty, calculate the risk that the bank is exposed to.
11 | 5. Generate a report that can be imported into Microsoft Excel containing the risk figures for all counterparties known by the bank.
12 | 6. Distribute the report to the business users before the start of the next trading day (9am) in Singapore.
13 | 7. Provide a way for a subset of the business users to configure and maintain the external parameters used by the risk calculations.
14 |
--------------------------------------------------------------------------------
/Structurizr.Examples/FinancialRiskSystem/images/functional-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Examples/FinancialRiskSystem/images/functional-overview.png
--------------------------------------------------------------------------------
/Structurizr.Examples/GettingStarted.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.Api;
2 |
3 | namespace Structurizr.Examples
4 | {
5 |
6 | ///
7 | /// A "getting started" example that illustrates how to
8 | /// create a software architecture diagram using code.
9 | ///
10 | /// The live workspace is available to view at https://structurizr.com/share/25441
11 | ///
12 | class GettingStarted
13 | {
14 |
15 | private const long WorkspaceId = 25441;
16 | private const string ApiKey = "key";
17 | private const string ApiSecret = "secret";
18 |
19 | static void Main()
20 | {
21 | Workspace workspace = new Workspace("Getting Started", "This is a model of my software system.");
22 | Model model = workspace.Model;
23 |
24 | Person user = model.AddPerson("User", "A user of my software system.");
25 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
26 | user.Uses(softwareSystem, "Uses");
27 |
28 | ViewSet viewSet = workspace.Views;
29 | SystemContextView contextView = viewSet.CreateSystemContextView(softwareSystem, "SystemContext", "An example of a System Context diagram.");
30 | contextView.AddAllSoftwareSystems();
31 | contextView.AddAllPeople();
32 |
33 | Styles styles = viewSet.Configuration.Styles;
34 | styles.Add(new ElementStyle(Tags.SoftwareSystem) { Background = "#1168bd", Color = "#ffffff" });
35 | styles.Add(new ElementStyle(Tags.Person) { Background = "#08427b", Color = "#ffffff", Shape = Shape.Person });
36 |
37 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
38 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
39 | }
40 |
41 | }
42 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/StylingElements.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.Api;
2 |
3 | namespace Structurizr.Examples
4 | {
5 |
6 | ///
7 | /// An example of how to style elements on diagrams.
8 | ///
9 | /// The live workspace is available to view at https://structurizr.com/share/36111
10 | ///
11 | class StylingElements
12 | {
13 |
14 | private const long WorkspaceId = 36111;
15 | private const string ApiKey = "key";
16 | private const string ApiSecret = "secret";
17 |
18 | static void Main()
19 | {
20 | Workspace workspace = new Workspace("Styling Elements", "This is a model of my software system.");
21 | Model model = workspace.Model;
22 |
23 | Person user = model.AddPerson("User", "A user of my software system.");
24 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
25 | Container webApplication = softwareSystem.AddContainer("Web Application", "My web application.", "Java and Spring MVC");
26 | Container database = softwareSystem.AddContainer("Database", "My database.", "Relational database schema");
27 | user.Uses(webApplication, "Uses", "HTTPS");
28 | webApplication.Uses(database, "Reads from and writes to", "JDBC");
29 |
30 | ViewSet views = workspace.Views;
31 | ContainerView containerView = views.CreateContainerView(softwareSystem, "containers", "An example of a container diagram.");
32 | containerView.AddAllElements();
33 |
34 | Styles styles = workspace.Views.Configuration.Styles;
35 |
36 | // example 1
37 | // styles.Add(new ElementStyle(Tags.Element) { Background = "#438dd5", Color = "#ffffff" });
38 |
39 | // example 2
40 | // styles.Add(new ElementStyle(Tags.Element) { Color = "#ffffff" });
41 | // styles.Add(new ElementStyle(Tags.Person) { Background = "#08427b" });
42 | // styles.Add(new ElementStyle(Tags.Container) { Background = "#438dd5" });
43 |
44 | // example 3
45 | // styles.Add(new ElementStyle(Tags.Element) { Color = "#ffffff" });
46 | // styles.Add(new ElementStyle(Tags.Person) { Background = "#08427b" , Shape = Shape.Person });
47 | // styles.Add(new ElementStyle(Tags.Container) { Background = "#438dd5" });
48 | // database.AddTags("Database");
49 | // styles.Add(new ElementStyle("Database") { Shape = Shape.Cylinder });
50 |
51 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
52 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
53 | }
54 |
55 | }
56 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/StylingRelationships.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Structurizr.Api;
3 |
4 | namespace Structurizr.Examples
5 | {
6 |
7 | ///
8 | /// An example of how to style relationships on diagrams.
9 | ///
10 | /// The live workspace is available to view at https://structurizr.com/share/36131
11 | ///
12 | class StylingRelationships
13 | {
14 |
15 | private const long WorkspaceId = 36131;
16 | private const string ApiKey = "key";
17 | private const string ApiSecret = "secret";
18 |
19 | static void Main()
20 | {
21 | Workspace workspace = new Workspace("Styling Relationships", "This is a model of my software system.");
22 | Model model = workspace.Model;
23 |
24 | Person user = model.AddPerson("User", "A user of my software system.");
25 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
26 | Container webApplication = softwareSystem.AddContainer("Web Application", "My web application.", "Java and Spring MVC");
27 | Container database = softwareSystem.AddContainer("Database", "My database.", "Relational database schema");
28 | user.Uses(webApplication, "Uses", "HTTPS");
29 | webApplication.Uses(database, "Reads from and writes to", "JDBC");
30 |
31 | ViewSet views = workspace.Views;
32 | ContainerView containerView = views.CreateContainerView(softwareSystem, "containers", "An example of a container diagram.");
33 | containerView.AddAllElements();
34 |
35 | Styles styles = workspace.Views.Configuration.Styles;
36 |
37 | // example 1
38 | // styles.Add(new RelationshipStyle(Tags.Relationship) { Color = "#ff0000" });
39 |
40 | // example 2
41 | // model.Relationships.Where(r => "HTTPS".Equals(r.Technology)).ToList().ForEach(r => r.AddTags("HTTPS"));
42 | // model.Relationships.Where(r => "JDBC".Equals(r.Technology)).ToList().ForEach(r => r.AddTags("JDBC"));
43 | // styles.Add(new RelationshipStyle("HTTPS") { Color = "#ff0000" });
44 | // styles.Add(new RelationshipStyle("JDBC") { Color = "#0000ff" });
45 |
46 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
47 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/Theme.cs:
--------------------------------------------------------------------------------
1 | using Structurizr.Api;
2 |
3 | namespace Structurizr.Examples
4 | {
5 |
6 | ///
7 | /// This is an example of how to use an external theme.
8 | ///
9 | /// The live workspace is available to view at https://structurizr.com/share/38898
10 | ///
11 | class Theme
12 | {
13 |
14 | private const long WorkspaceId = 38898;
15 | private const string ApiKey = "";
16 | private const string ApiSecret = "";
17 |
18 | static void Main()
19 | {
20 | Workspace workspace = new Workspace("Theme", "This is a model of my software system.");
21 | Model model = workspace.Model;
22 |
23 | Person user = model.AddPerson("User", "A user of my software system.");
24 | SoftwareSystem softwareSystem = model.AddSoftwareSystem("Software System", "My software system.");
25 | user.Uses(softwareSystem, "Uses");
26 |
27 | ViewSet viewSet = workspace.Views;
28 | SystemContextView contextView = viewSet.CreateSystemContextView(softwareSystem, "SystemContext", "An example of a System Context diagram.");
29 | contextView.AddAllSoftwareSystems();
30 | contextView.AddAllPeople();
31 |
32 | // add a theme
33 | viewSet.Configuration.Theme = "https://raw.githubusercontent.com/structurizr/dotnet/master/Structurizr.Examples/Theme/theme.json";
34 |
35 | StructurizrClient structurizrClient = new StructurizrClient(ApiKey, ApiSecret);
36 | structurizrClient.PutWorkspace(WorkspaceId, workspace);
37 | }
38 |
39 | }
40 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/Theme/theme.json:
--------------------------------------------------------------------------------
1 | {
2 | "elements": [
3 | {
4 | "tag": "Software System",
5 | "background": "#1168bd",
6 | "color": "#ffffff"
7 | },
8 | {
9 | "tag": "Person",
10 | "background": "#08427b",
11 | "color": "#ffffff",
12 | "shape": "Person"
13 | }
14 | ],
15 | "relationships": []
16 | }
--------------------------------------------------------------------------------
/Structurizr.Examples/structurizr-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/Structurizr.Examples/structurizr-logo.png
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.0.{build}
2 | pull_requests:
3 | do_not_increment_build_number: true
4 | image: Visual Studio 2017
5 | build_script:
6 | - ps: >-
7 | dotnet restore
8 |
9 | dotnet build
10 |
11 |
12 | dotnet clean /p:Configuration=Release
13 |
14 | if ($env:APPVEYOR_REPO_TAG -Eq "true") {
15 | dotnet msbuild "/t:Restore;Pack" /p:Configuration=Release /p:Version=$env:APPVEYOR_REPO_TAG_NAME
16 | } else {
17 | dotnet msbuild "/t:Restore;Pack" /p:Configuration=Release /p:VersionSuffix=pre${env:APPVEYOR_BUILD_NUMBER}-$($env:APPVEYOR_REPO_COMMIT.Substring(0,8))
18 | }
19 | test_script:
20 | - ps: dotnet test .\Structurizr.Core.Tests\Structurizr.Core.Tests.csproj
21 | - ps: dotnet test .\Structurizr.Client.Tests\Structurizr.Client.Tests.csproj
22 | artifacts:
23 | - path: '*\bin\Release\*.nupkg'
--------------------------------------------------------------------------------
/docs/api-client.md:
--------------------------------------------------------------------------------
1 | # API client
2 |
3 | The Structurizr for .NET library includes a client for the [Structurizr web API](https://api.structurizr.com), which allows you to get and put workspaces using JSON over HTTPS. This page provides a quick overview of how to use the API client.
4 |
5 | ## Configuration
6 |
7 | To configure the API client, simply provide values for the API key and API secret programmatically when creating a ```StructurizrClient``` instance. Each workspace has its own API key and secret, the values for which can be found on [your dashboard](https://structurizr.com/dashboard).
8 |
9 | ```c#
10 | StructurizrClient structurizrClient = new StructurizrClient("key", "secret");
11 | ```
12 |
13 | If you're using the [on-premises installation](https://structurizr.com/help/on-premises-ui), there is a three argument version of the constructor where you can also specify the API URL.
14 |
15 | ```c#
16 | StructurizrClient structurizrClient = new StructurizrClient("url", "key", "secret");
17 | ```
18 |
19 | ## Usage
20 |
21 | The following operations are available on the API client.
22 |
23 | ### 1. GetWorkspace
24 |
25 | This allows you to get the content of a workspace.
26 |
27 | ```c#
28 | Workspace workspace = structurizrClient.GetWorkspace(1234);
29 | ```
30 |
31 | By default, a copy of the workspace (as JSON) is archived to the current working directory. You can modify this behaviour by setting the ```WorkspaceArchiveLocation``` property. A ```null``` value will disable archiving.
32 |
33 | ### 2. PutWorkspace
34 |
35 | This allows you to overwrite an existing workspace. If the ```MergeFromRemote``` property (on the ```StructurizrClient``` instance) is set to ```true``` (this is the default), any layout information (i.e. the location of boxes on diagrams) is preserved where possible (i.e. where diagram elements haven't been renamed).
36 |
37 | ```c#
38 | structurizrClient.PutWorkspace(1234, workspace);
39 | ```
40 |
41 | ### 3. LockWorkspace
42 |
43 | If your workspace supports sharing (not available with the Free Plan), you can optionally attempt to lock your workspace before writing to it, to prevent concurrent updates.
44 |
45 | ```c#
46 | structurizrClient.LockWorkspace(1234);
47 | ```
48 |
49 | This method returns a boolean; ```true``` if the workspace could be locked, ```false``` otherwise.
50 |
51 | ### 4. UnlockWorkspace
52 |
53 | Similarly, you can unlock a workspace.
54 |
55 | ```c#
56 | structurizrClient.UnlockWorkspace(1234);
57 | ```
58 |
59 | This method also returns a boolean; ```true``` if the workspace could be unlocked, ```false``` otherwise.
60 |
61 |
--------------------------------------------------------------------------------
/docs/binaries.md:
--------------------------------------------------------------------------------
1 | # Binaries
2 |
3 | The "Structurizr for .NET" binaries are hosted on [NuGet](https://www.nuget.org/profiles/structurizr) as follows:
4 |
5 | Name | Description
6 | --------------------- | ---------------------------------------------------------------------------------------------------------------------------
7 | Structurizr.Core | The basic library that can used to create software architecture models.
8 | Structurizr.Client | The API client for publishing models on the Structurizr cloud service and on-premises installation.
--------------------------------------------------------------------------------
/docs/client-side-encryption.md:
--------------------------------------------------------------------------------
1 | # Client-side encryption
2 |
3 | > Note: this page describes a feature that is not available to use with Structurizr's Free Plan.
4 |
5 | The JSON representation of your workspace is stored on the Structurizr servers using AES encryption with a 128-bit key, a random salt and a server-side passphrase. For additional peace of mind, you can choose to encrypt your workspace with your own passphrase on the client before uploading it to Structurizr. In order to view a client-side encrypted workspace, you will be asked to enter your passphrase when you open the workspace in your web browser. The passphrase is then used to decrypt the workspace in your web browser - at no point does the passphrase leave your computer.
6 |
7 | To use client-side encryption, simply create an instance of ```AesEncryptionStrategy``` and associate it with your ```StructurizrClient``` instance. For example:
8 |
9 | ```c#
10 | StructurizrClient structurizrClient = new StructurizrClient("key", "secret");
11 | structurizrClient.EncryptionStrategy = new AesEncryptionStrategy("password");
12 | structurizrClient.PutWorkspace(1234, workspace);
13 | ```
14 |
15 | The default key size is 128 bits and the default iteration count is 1000. An alternative constructor for AesEncryptionStrategy
takes the following parameters:
16 |
17 | - The key size (number of bits; e.g. 128, 192 or 256).
18 | - The iteration count (used when generating keys).
19 | - The passphrase.
20 |
21 | In addition, a random salt and initialization vector are generated automatically for you, using .NET's ```RandomNumberGenerator``` class.
22 |
23 | See [ClientSideEncryption.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/ClientSideEncryption.cs) for a full example, and [https://structurizr.com/share/41](https://structurizr.com/share/41) to access the workspace.
--------------------------------------------------------------------------------
/docs/container-diagram.md:
--------------------------------------------------------------------------------
1 | # Container diagram
2 |
3 | Once you understand how your system fits in to the overall IT environment, a really useful next step is to illustrate the high-level technology choices with a Container diagram. A "container" is something like a web application, desktop application, mobile app, database, file system, etc. Essentially, a container is a separately deployable unit that executes code or stores data.
4 |
5 | The Container diagram shows the high-level shape of the software architecture and how responsibilities are distributed across it. It also shows the major technology choices and how the containers communicate with one another. It's a simple, high-level technology focussed diagram that is useful for software developers and support/operations staff alike.
6 |
7 | ## Example
8 |
9 | As an example, a Container diagram for a simplified, fictional Internet Banking System might look something like this. In summary, it shows that the Internet Banking System is made up a Web Application and a Database. It also shows the relationship between the Web Application and the Mainframe Banking System.
10 |
11 | 
12 |
13 | With Structurizr for .NET, you can create this diagram with code like the following:
14 |
15 | ```c#
16 | Container webApplication = internetBankingSystem.AddContainer("Web Application", "Provides all of the Internet banking functionality to customers.", "Java and Spring MVC");
17 | Container database = internetBankingSystem.AddContainer("Database", "Stores interesting data.", "Relational Database Schema");
18 |
19 | customer.Uses(webApplication, "HTTPS");
20 | webApplication.Uses(database, "Reads from and writes to", "JDBC");
21 | webApplication.Uses(mainframeBankingSystem, "Uses", "XML/HTTPS");
22 |
23 | ContainerView containerView = views.CreateContainerView(internetBankingSystem, "Containers", "The container diagram for the Internet Banking System.");
24 | containerView.Add(customer);
25 | containerView.AddAllContainers();
26 | containerView.Add(mainframeBankingSystem);
27 | ```
28 |
29 | See [BigBankPlc.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/BigBankPlc.cs) for the full code, and [https://structurizr.com/share/36141#Containers](https://structurizr.com/share/36141#Containers) for the diagram.
--------------------------------------------------------------------------------
/docs/corporate-branding.md:
--------------------------------------------------------------------------------
1 | # Corporate branding
2 |
3 | > Note: this page describes a feature that is not available to use with Structurizr's Free Plan.
4 |
5 | In addition to [styling diagram elements](styling-elements.md) and [relationships](styling-relationships.md), some corporate branding can be added to diagrams and documentation. This includes:
6 |
7 | - A font (font name and optional web font stylesheet URL).
8 | - A logo (a URL to an image file or a data URI).
9 |
10 | Here's an example diagram that hasn't been styled, aside from setting the shape of the ```Person``` elements.
11 |
12 | 
13 |
14 | And here's what the documentation looks like.
15 |
16 | 
17 |
18 | You can add branding to an existing workspace, as follows:
19 |
20 | ```c#
21 | Branding branding = views.Configuration.Branding;
22 | branding.Logo = ImageUtils.GetImageAsDataUri(new FileInfo("structurizr-logo.png"));
23 | ```
24 |
25 | ## Diagrams
26 |
27 | If no colours have been specified via diagram element styles, colour pairs 1-4 will be used when rendering people, software systems, containers and components respectively. Here's the same diagram, now with added branding. Notice that the logo is now also shown in the bottom left corner.
28 |
29 | 
30 |
31 | ## Documentation
32 |
33 | With documentation, the colour pairs are mapped onto the navigation links at the top of the page, while the first colour pair is used when rendering hyperlinks. Again, the logo is shown.
34 |
35 | 
36 |
37 | See [CorporateBranding.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/CorporateBranding.cs) for a full example, and [https://structurizr.com/share/35031](https://structurizr.com/share/35031) to access the workspace.
38 |
--------------------------------------------------------------------------------
/docs/dynamic-diagram.md:
--------------------------------------------------------------------------------
1 | # Dynamic diagram
2 |
3 | In addition to the diagrams showing static structure, you can also create a simple Dynamic diagram. This can be useful when you want to show how elements in a static model collaborate at runtime to implement a user story, use case, feature, etc.
4 |
5 | The Dynamic diagram in Structurizr is based upon a [UML communication diagram](https://en.wikipedia.org/wiki/Communication_diagram) (previously known as a "UML collaboration diagram"). This is similar to a [UML sequence diagram](https://en.wikipedia.org/wiki/Sequence_diagram) although it allows a free-form arrangement of diagram elements with numbered interactions to indicate ordering.
6 |
7 | > Note: this page describes a feature that is not available to use with Structurizr's Free Plan. You can, however, render Dynamic diagrams using the [PlantUMLWriter](plantuml.md).
8 |
9 | ## Example
10 |
11 | As an example, a Dynamic diagram describing the customer sign in process for a simplified, fictional Internet Banking System might look something like this. In summary, it shows the components involved in the sign in process, and the interactions between them.
12 |
13 | 
14 |
15 | With Structurizr for .NET, you can create this diagram with code like the following:
16 |
17 | ```c#
18 | DynamicView dynamicView = views.CreateDynamicView(webApplication, "SignIn", "Summarises how the sign in feature works.");
19 | dynamicView.Add(customer, "Requests /signin from", signinController);
20 | dynamicView.Add(customer, "Submits credentials to", signinController);
21 | dynamicView.Add(signinController, "Calls isAuthenticated() on", securityComponent);
22 | dynamicView.Add(securityComponent, "select * from users u where username = ?", database);
23 | ```
24 |
25 | See [BigBankPlc.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/BigBankPlc.cs) for the full code, and [https://structurizr.com/share/36141#SignIn](https://structurizr.com/share/36141#SignIn) for the diagram.
26 |
27 | ### Adding relationships
28 |
29 | In order to add a relationship between two elements to a dynamic view, that relationship must already exist between the two elements in the static view.
30 |
31 | ### Parallel behaviour
32 |
33 | Showing parallel behaviour is also possible using the ```startParallelSequence()``` and ```endParallelSequence()``` methods on the ```DynamicView``` class. See [MicroservicesExample.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/MicroservicesExample.cs) and [https://structurizr.com/share/4241#CustomerUpdateEvent](https://structurizr.com/share/4241#CustomerUpdateEvent) for an example.
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | # Frequently asked questions
2 |
3 | ## Why are many classes sealed with internal members, and not open to extension?
4 |
5 | First and foremost, this repo is a client library for the [Structurizr cloud service and on-premises installation](https://structurizr.com). It allows you to write .NET code to create an in-memory object graph representing a software architecture model and views (a "workspace"), serialize that to JSON, and upload it via a web API. The workspace has an [OpenAPI definition](https://github.com/structurizr/json/blob/master/structurizr.yaml), but this library also implements a number of rules (think of them as the "business logic") to ensure that the workspace is valid. These rules include, for example, ensuring that all containers with a software system have unique names, and that you can't add components to a system context view.
6 |
7 | Unsealing the classes and leaving the them open for extension allows you to bypass/break these rules, which will likely lead to the serialized workspace definitions being incompatible with the Structurizr cloud service and on-premises installation. The output of this library also needs to be compatible with all of the other client libraries.
8 |
9 | You are welcome to fork this library for your own purposes. Alternatively, you can build a thin wrapper around the library, to provide your own custom functionality, or perhaps a more fluent API ... many teams have done this.
10 |
11 | ## Can I submit a pull request?
12 |
13 | It depends on the nature of the change. Please open an issue first to discuss it.
14 |
--------------------------------------------------------------------------------
/docs/filtered-views.md:
--------------------------------------------------------------------------------
1 | # Filtered views
2 |
3 | A filtered view represents a view on top of another view, which can be used to include or exclude specific elements and/or relationships, based upon their tag. The benefit of using filtered views is that element and relationship positions are shared between the views.
4 |
5 | Filtered views can be created on top of static views only; i.e. Enterprise Context, System Context, Container and Component views.
6 |
7 | ## Example
8 |
9 | As an example, let's imagine an organisation where a User uses Software System A for tasks 1 and 2.
10 |
11 | 
12 |
13 | And, in the future, Software System B will be introduced to fulfil task 2.
14 |
15 | 
16 |
17 | With Structurizr for .NET, you can illustrate this by defining a single context diagram with two filtered views on top; one showing the current state and the other showing future state.
18 |
19 | ```c#
20 | Person user = model.AddPerson("User", "A description of the user.");
21 | SoftwareSystem softwareSystemA = model.AddSoftwareSystem("Software System A", "A description of software system A.");
22 | SoftwareSystem softwareSystemB = model.AddSoftwareSystem("Software System B", "A description of software system B.");
23 | softwareSystemB.AddTags(FutureState);
24 |
25 | user.Uses(softwareSystemA, "Uses for tasks 1 and 2").AddTags(CurrentState);
26 | user.Uses(softwareSystemA, "Uses for task 1").AddTags(FutureState);
27 | user.Uses(softwareSystemB, "Uses for task 2").AddTags(FutureState);
28 |
29 | ViewSet views = workspace.Views;
30 | EnterpriseContextView enterpriseContextView = views.CreateEnterpriseContextView("EnterpriseContext", "An example Enterprise Context diagram.");
31 | enterpriseContextView.AddAllElements();
32 |
33 | views.CreateFilteredView(enterpriseContextView, "CurrentState", "The current context.", FilterMode.Exclude, FutureState);
34 | views.CreateFilteredView(enterpriseContextView, "FutureState", "The future state context after Software System B is live.", FilterMode.Exclude, CurrentState);
35 | ```
36 |
37 | In summary, you create a view with all of the elements and relationships that you want to show, and then create one or more filtered views on top, specifying the tags that you'd like to include or exclude.
38 |
39 | See [FilteredViews.cs](https://github.com/structurizr/dotnet/tree/master/Structurizr.Examples/FilteredViews.cs) for the full code, and [https://structurizr.com/share/19911](https://structurizr.com/share/19911) for the diagram.
--------------------------------------------------------------------------------
/docs/health-checks.md:
--------------------------------------------------------------------------------
1 | # HTTP-based health checks
2 |
3 | Structurizr's health checks feature allows you to supplement your deployment models with HTTP-based health checks to get an "at a glance" view of the health of your software systems. See [Structurizr - Health Checks](https://structurizr.com/help/health-checks) for more details.
4 |
5 | When defining your software architecture model using the client library, HTTP-based health checks can be added to the Container Instances in your deployment model. Each health check is defined by a name, an endpoint URL, a polling interval (e.g. 60 seconds), a timeout (e.g. 1000 milliseconds), and optionally one or more HTTP headers.
6 |
7 | [HttpHealthChecks.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/HttpHealthChecks.cs) shows an example of how to setup the health checks, and the result can be see online at [https://structurizr.com/share/39441/health](https://structurizr.com/share/39441/health).
--------------------------------------------------------------------------------
/docs/images/basic-concepts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/basic-concepts.png
--------------------------------------------------------------------------------
/docs/images/component-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/component-diagram-1.png
--------------------------------------------------------------------------------
/docs/images/container-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/container-diagram-1.png
--------------------------------------------------------------------------------
/docs/images/corporate-branding-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/corporate-branding-1.png
--------------------------------------------------------------------------------
/docs/images/corporate-branding-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/corporate-branding-2.png
--------------------------------------------------------------------------------
/docs/images/corporate-branding-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/corporate-branding-3.png
--------------------------------------------------------------------------------
/docs/images/corporate-branding-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/corporate-branding-4.png
--------------------------------------------------------------------------------
/docs/images/deployment-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/deployment-diagram-1.png
--------------------------------------------------------------------------------
/docs/images/documentation-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/documentation-1.png
--------------------------------------------------------------------------------
/docs/images/documentation-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/documentation-2.png
--------------------------------------------------------------------------------
/docs/images/documentation-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/documentation-3.png
--------------------------------------------------------------------------------
/docs/images/dynamic-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/dynamic-diagram-1.png
--------------------------------------------------------------------------------
/docs/images/filtered-views-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/filtered-views-1.png
--------------------------------------------------------------------------------
/docs/images/filtered-views-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/filtered-views-2.png
--------------------------------------------------------------------------------
/docs/images/getting-started-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/getting-started-1.png
--------------------------------------------------------------------------------
/docs/images/getting-started-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/getting-started-2.png
--------------------------------------------------------------------------------
/docs/images/getting-started-diagram-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/getting-started-diagram-key.png
--------------------------------------------------------------------------------
/docs/images/implied-relationships-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/implied-relationships-1.png
--------------------------------------------------------------------------------
/docs/images/readme-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/readme-1.png
--------------------------------------------------------------------------------
/docs/images/structurizr-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/structurizr-banner.png
--------------------------------------------------------------------------------
/docs/images/structurizr-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/structurizr-overview.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-1.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-2.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-3.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-4.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-5.png
--------------------------------------------------------------------------------
/docs/images/styling-elements-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-elements-6.png
--------------------------------------------------------------------------------
/docs/images/styling-relationships-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-relationships-1.png
--------------------------------------------------------------------------------
/docs/images/styling-relationships-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-relationships-2.png
--------------------------------------------------------------------------------
/docs/images/styling-relationships-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-relationships-3.png
--------------------------------------------------------------------------------
/docs/images/styling-relationships-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/styling-relationships-4.png
--------------------------------------------------------------------------------
/docs/images/system-context-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/system-context-diagram-1.png
--------------------------------------------------------------------------------
/docs/images/system-landscape-diagram-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/structurizr/dotnet/9a7f478792c333507294e3b23863092b3d698273/docs/images/system-landscape-diagram-1.png
--------------------------------------------------------------------------------
/docs/model.md:
--------------------------------------------------------------------------------
1 | # Model
2 |
3 | This is the definition of the software architecture model, consisting of people, software systems, containers, components, code elements and deployment nodes, plus the relationships between them.
4 |
5 | All of the .NET classes representing people, software systems, containers, components, etc, and the functionality related to creating a software architecture model can be found in the [Structurizr](https://github.com/structurizr/dotnet/tree/master/Structurizr.Core/Model) namespace.
6 |
7 | An empty model is created for you when you create a workspace.
8 |
9 | ```c#
10 | Workspace workspace = new Workspace("Getting Started", "This is a model of my software system.");
11 | Model model = workspace.Model;
12 | ```
13 |
14 | Once you have a reference to a ```Model``` instance, you can add elements to it manually or automatically, using static analysis and reflection techniques.
15 |
16 | ## 1. Manual model creation
17 |
18 | Manually adding elements to the model is the simplest way to use the Structurizr for Java client library. This can be done using the various public ```Add*``` methods that you'll find on ```Model```, ```SoftwareSystem```, ```Container```, ```Component```, etc.
19 |
20 | ## 2. Automatic extraction
21 |
22 | You can also extract components (and add them to a ```Container``` instance) automatically from a given codebase, using a number of different component finder strategies. See [Component finder](https://github.com/structurizr/dotnet-extensions/blob/master/Structurizr.Analysis/Analysis/ComponentFinder.cs) for more details.
23 |
24 | Although there is nothing included in the Structurizr for .NET library to support this, you could also choose to parse an external definition of your software architecture (e.g. an AWS infrastructure topology, another Architecture Description Language, etc) and create model elements accordingly.
--------------------------------------------------------------------------------
/docs/nuget.md:
--------------------------------------------------------------------------------
1 | # NuGet
2 |
3 | To create NuGet multi-target NuGet packages:
4 |
5 | 1. Open the Visual Studio Command Prompt
6 | 1. Change to the directory containing the .csproj file
7 | 1. Run (e.g.) ```msbuild /t:pack /p:Version=0.8.0 /p:Configuration=Debug```
--------------------------------------------------------------------------------
/docs/styling-relationships.md:
--------------------------------------------------------------------------------
1 | # Styling relationships
2 |
3 | By default, all relationships are rendered as dashed grey lines as shown in the example diagram below.
4 |
5 | 
6 |
7 | However, the following characteristics of the relationships can be customized:
8 |
9 | - Line thickness (pixels)
10 | - Colour (HTML hex value)
11 | - Dashed (true or false)
12 | - Routing (Direct or Orthogonal; see the [Routing](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/Routing.cs) enum)
13 | - Font size (pixels)
14 | - Width (of the description, in pixels)
15 | - Position (of the description along the line, as a percentage from start to end)
16 | - Opacity (an integer between 0 and 100)
17 |
18 | ## Tagging relationships
19 |
20 | All relationships within a software architecture model can have one or more tags associated with them. A tag is simply a free-format string. By default, the Java client library adds the ```"Relationship"``` tag to relationships. As we'll see shortly, you can add your own custom tags to relationships using the ```AddTags()``` method on the relationship.
21 |
22 | ## Colour
23 |
24 | To style a relationship, simply create a [RelationshipStyle](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/RelationshipStyle.cs) for a particular tag and specify the characteristics that you would like to change. For example, you can change the colour of all relationships as follows.
25 |
26 | ```java
27 | Styles styles = workspace.Views.Configuration.Styles;
28 | styles.Add(new RelationshipStyle(Tags.Relationship) { Color = "#ff0000" });
29 | ```
30 |
31 | 
32 |
33 | You can also change the colour of specific relationships, based upon their tag, as follows.
34 |
35 | ```java
36 | model.Relationships.Where(r => "HTTPS".Equals(r.Technology)).ToList().ForEach(r => r.AddTags("HTTPS"));
37 | model.Relationships.Where(r => "JDBC".Equals(r.Technology)).ToList().ForEach(r => r.AddTags("JDBC"));
38 | styles.Add(new RelationshipStyle("HTTPS") { Color = "#ff0000" });
39 | styles.Add(new RelationshipStyle("JDBC") { Color = "#0000ff" });
40 | ```
41 |
42 | 
43 |
44 | ## Diagram key
45 |
46 | Structurizr will automatically add all relationship styles to a diagram key.
47 |
48 | 
49 |
50 | You can find the code for this example at [StylingRelationships.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/StylingRelationships.cs) and the live example workspace at [https://structurizr.com/share/36131](https://structurizr.com/share/36131).
--------------------------------------------------------------------------------
/docs/system-context-diagram.md:
--------------------------------------------------------------------------------
1 | # System Context diagram
2 |
3 | A System Context diagram is a good starting point for diagramming and documenting a software system, allowing you to step back and see the big picture. Draw a diagram showing your system as a box in the centre, surrounded by its users and the other systems that it interacts with.
4 |
5 | Detail isn't important here as this is your zoomed out view showing a big picture of the system landscape. The focus should be on people (actors, roles, personas, etc) and software systems rather than technologies, protocols and other low-level details. It's the sort of diagram that you could show to non-technical people.
6 |
7 | ## Example
8 |
9 | As an example, a System Context diagram for a simplified, fictional Internet Banking System might look something like this. In summary, it shows that customers of the bank use the Internet Banking System, which itself uses the internal Mainframe Banking System.
10 |
11 | 
12 |
13 | With Structurizr for .NET, you can create this diagram with code like the following:
14 |
15 | ```c#
16 | Person customer = model.AddPerson(Location.External, "Customer", "A customer of the bank.");
17 |
18 | SoftwareSystem internetBankingSystem = model.AddSoftwareSystem(Location.Internal, "Internet Banking System", "Allows customers to view information about their bank accounts and make payments.");
19 | customer.Uses(internetBankingSystem, "Uses");
20 |
21 | SoftwareSystem mainframeBankingSystem = model.AddSoftwareSystem(Location.Internal, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.");
22 | internetBankingSystem.Uses(mainframeBankingSystem, "Uses");
23 |
24 | SystemContextView systemContextView = views.CreateSystemContextView(internetBankingSystem, "SystemContext", "The system context diagram for the Internet Banking System.");
25 | systemContextView.AddNearestNeighbours(internetBankingSystem);
26 | ```
27 |
28 | See [BigBankPlc.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/BigBankPlc.cs) for the full code, and [https://structurizr.com/share/36141#SystemContext](https://structurizr.com/share/36141#SystemContext) for the diagram.
--------------------------------------------------------------------------------
/docs/system-landscape-diagram.md:
--------------------------------------------------------------------------------
1 | # System Landscape diagram
2 |
3 | A System Landscape diagram is really the same as the [System Context diagram](system-context-diagram.md), without a focus on a specific software system. It can help to provide a broader view of the people and software systems that are related to and reside within a given enterprise (e.g. a business or organisation).
4 |
5 | ## Example
6 |
7 | As an example, a System Landscape diagram for a simplified, fictional Internet Banking System might look something like this. In summary, it shows more than just the immediate relationships of the Internet Banking System.
8 |
9 | 
10 |
11 | With Structurizr for .NET, you can create this diagram with code like the following:
12 |
13 | ```c#
14 | Person customer = model.AddPerson(Location.External, "Customer", "A customer of the bank.");
15 |
16 | SoftwareSystem internetBankingSystem = model.AddSoftwareSystem(Location.Internal, "Internet Banking System", "Allows customers to view information about their bank accounts and make payments.");
17 | customer.Uses(internetBankingSystem, "Uses");
18 |
19 | SoftwareSystem mainframeBankingSystem = model.AddSoftwareSystem(Location.Internal, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.");
20 | internetBankingSystem.Uses(mainframeBankingSystem, "Uses");
21 |
22 | SoftwareSystem atm = model.AddSoftwareSystem(Location.Internal, "ATM", "Allows customers to withdraw cash.");
23 | atm.Uses(mainframeBankingSystem, "Uses");
24 | customer.Uses(atm, "Withdraws cash using");
25 |
26 | Person bankStaff = model.AddPerson(Location.Internal, "Bank Staff", "Staff within the bank.");
27 | bankStaff.Uses(mainframeBankingSystem, "Uses");
28 |
29 | EnterpriseContextView enterpriseContextView = views.CreateSystemLandscapeView("EnterpriseContext", "The system landscape diagram for the Internet Banking System.");
30 | enterpriseContextView.AddAllElements();
31 | ```
32 |
33 | See [BigBankPlc.cs](https://github.com/structurizr/dotnet/blob/master/Structurizr.Examples/BigBankPlc.cs) for the full code, and [https://structurizr.com/share/36141#EnterpriseContext](https://structurizr.com/share/36141#EnterpriseContext) for the diagram.
--------------------------------------------------------------------------------
/docs/usage-patterns.md:
--------------------------------------------------------------------------------
1 | # Usage patterns
2 |
3 | ## Single program
4 |
5 | The simplest way to create a software architecture model is to write a single C# program that first creates the model elements (people, software systems, containers and components) before subsequently creating the required views and uploading the workspace to Structurizr. If you have a particularly large model, or you'd like to share common elements between models, then one approach is to modularise your program appropriately.
6 |
7 | ## Multiple programs
8 |
9 | Another approach is to write a collection of C# programs, that are each responsible for creating a different part of the software architecture model. This is especially useful if you need to use the component finder with different assemblies. You can then write a script, or use your build script, to run these C# programs in sequence. Intermediate versions of the workspace can be saved to and loaded from disk using the [WorkspaceUtils](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/Util/WorkspaceUtils.cs) class. For example:
10 |
11 | 1. Program 1: Create the basic model elements (people, software systems and containers) and the relationships between them.
12 | 2. Program 2: Add components for container 1 (e.g. run the component finder).
13 | 3. Program 3: Add components for container 2 (e.g. run the component finder with a different assembly path).
14 | 4. Program 4: Create views.
15 | 5. Program 5: Add styling.
16 | 6. Program 6: Upload to Structurizr.
17 |
18 | In this example, the first program would write the initial version of the workspace to a local file on disk, which subsequent programs then load and add to, before writing the workspace back to disk.
--------------------------------------------------------------------------------
/docs/views.md:
--------------------------------------------------------------------------------
1 | # Views
2 |
3 | Once you've [added elements to a model](model.md), you can create one or more views to visualise parts of the model, which can subsequently be rendered as diagrams by a number of different tools.
4 |
5 | Structurizr for .NET supports all of the view types described in the [C4 model](https://c4model.com), and the .NET classes implementing these views can be found in the [Structurizr](https://github.com/structurizr/dotnet/tree/master/Structurizr.Core/View) namespace as follows:
6 |
7 | * [SystemContextView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/SystemContextView.cs)
8 | * [ContainerView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/ContainerView.cs)
9 | * [ComponentView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/ComponentView.cs)
10 | * [SystemLandscapeView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/SystemLandscapeView.cs)
11 | * [DynamicView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/DynamicView.cs)
12 | * [DeploymentView](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/DeploymentView.cs)
13 |
14 | ## Creating views
15 |
16 | All views are associated with a [ViewSet](https://github.com/structurizr/dotnet/blob/master/Structurizr.Core/View/ViewSet.cs), which is created for you when you create a workspace.
17 |
18 | ```java
19 | Workspace workspace = new Workspace("Getting Started", "This is a model of my software system.");
20 | ViewSet views = workspace.Views;
21 | ```
22 |
23 | Use the various ```Create*View``` methods on the ```ViewSet``` class to create views.
24 |
25 |
--------------------------------------------------------------------------------
/nuget.bat:
--------------------------------------------------------------------------------
1 | dotnet test .\Structurizr.Core.Tests\Structurizr.Core.Tests.csproj
2 | dotnet test .\Structurizr.Client.Tests\Structurizr.Client.Tests.csproj
3 |
4 | dotnet msbuild "/t:rebuild;pack" /p:Version=0.9.7 /p:Configuration=Debug .\Structurizr.Core\Structurizr.Core.csproj
5 | dotnet msbuild "/t:rebuild;pack" /p:Version=0.9.7 /p:Configuration=Debug .\Structurizr.Client\Structurizr.Client.csproj
--------------------------------------------------------------------------------