Skip to content

Commit

Permalink
Simplified C# AaC by making it stronly-typed throughout
Browse files Browse the repository at this point in the history
  • Loading branch information
SlavaVedernikov committed Oct 3, 2024
1 parent 66b0e67 commit 16ccc26
Show file tree
Hide file tree
Showing 74 changed files with 276 additions and 166 deletions.
23 changes: 12 additions & 11 deletions C4InterFlow.Automation/Writers/CSharpCodeWriter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using C4InterFlow.Structures;
using System.Text;
using YamlDotNet.Core;

namespace C4InterFlow.Automation.Writers
{
Expand All @@ -23,7 +24,7 @@ public partial class Containers
public partial class {containerName} : IContainerInstance
{{
public static Container Instance => new Container(
Utils.GetStructureAlias<{AnyCodeWriter.GetName(containerName)}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({containerName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
ContainerType = ContainerType.{(!string.IsNullOrEmpty(type) ? type : "None")},
Description = {(!string.IsNullOrEmpty(description) ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Expand Down Expand Up @@ -102,7 +103,7 @@ public string GetSoftwareSystemCode(string architectureNamespace, string name, s
public partial class {softwareSystemName} : ISoftwareSystemInstance
{{
public static SoftwareSystem Instance => new SoftwareSystem(
Utils.GetStructureAlias<{AnyCodeWriter.GetName(softwareSystemName)}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({softwareSystemName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
Description = {(!string.IsNullOrEmpty(description) ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Boundary = Boundary.{(!string.IsNullOrEmpty(boundary) ? boundary : "Internal")}
Expand Down Expand Up @@ -130,7 +131,7 @@ public string GetActorCode(string architectureNamespace, string type, string nam
public class {actorName} : I{type}Instance
{{
public static {type} Instance => new {type}(
Utils.GetStructureAlias<{AnyCodeWriter.GetName(actorName)}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({actorName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
Description = {(description != null ? description : "\"\"")},
}};
Expand Down Expand Up @@ -159,7 +160,7 @@ public partial class Components
public partial class {componentName} : IComponentInstance
{{
public static Component Instance => new Component(
Utils.GetStructureAlias<{componentName}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({componentName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
ComponentType = ComponentType.{componentType},
Description = {(!string.IsNullOrEmpty(description) ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Expand Down Expand Up @@ -236,13 +237,13 @@ public partial class Interfaces
public partial class {componentInterfaceName} : IInterfaceInstance
{{
public static Interface Instance => new Interface(
Utils.GetStructureAlias<{componentInterfaceName}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({componentInterfaceName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
Description = {(description != null ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Path = {(path != null ? AnyCodeWriter.EnsureDoubleQuotes(path) : "\"\"")},
IsPrivate = {(isPrivate != null ? isPrivate.ToString().ToLower() : "false")},
Protocol = {(protocol != null ? AnyCodeWriter.EnsureDoubleQuotes(protocol) : "\"\"")},
Flow = new Flow(Utils.GetStructureAlias<{componentInterfaceName}>()),
Flow = new Flow(Interface.GetAlias<{componentInterfaceName}>()),
Input = {(input != null ? input : "\"\"")},
InputTemplate = {(inputTemplate != null ? inputTemplate : "\"\"")},
Output = {(output != null ? output : "\"\"")},
Expand Down Expand Up @@ -278,10 +279,10 @@ public partial class Interfaces
public partial class {containerInterfaceName} : IInterfaceInstance
{{
public static Interface Instance => new Interface(
Utils.GetStructureAlias<{containerInterfaceName}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({containerInterfaceName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
Description = {(description != null ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Flow = new Flow(Utils.GetStructureAlias<{containerInterfaceName}>()),
Flow = new Flow(Interface.GetAlias<{containerInterfaceName}>()),
Protocol = {(protocol != null ? AnyCodeWriter.EnsureDoubleQuotes(protocol) : "\"\"")},
Input = {(input != null ? input : "\"\"")},
InputTemplate = {(inputTemplate != null ? inputTemplate : "\"\"")},
Expand Down Expand Up @@ -312,10 +313,10 @@ public partial class Interfaces
public partial class {softwareSystemInterfaceName} : IInterfaceInstance
{{
public static Interface Instance => new Interface(
Utils.GetStructureAlias<{softwareSystemInterfaceName}>(), {AnyCodeWriter.EnsureDoubleQuotes(label)})
typeof({softwareSystemInterfaceName}), {AnyCodeWriter.EnsureDoubleQuotes(label)})
{{
Description = {(description != null ? AnyCodeWriter.EnsureDoubleQuotes(description) : "\"\"")},
Flow = new Flow(Utils.GetStructureAlias<{softwareSystemInterfaceName}>()),
Flow = new Flow(Interface.GetAlias<{softwareSystemInterfaceName}>()),
Protocol = {(protocol != null ? AnyCodeWriter.EnsureDoubleQuotes(protocol) : "\"\"")},
Input = {(input != null ? input : "\"\"")},
InputTemplate = {(inputTemplate != null ? inputTemplate : "\"\"")},
Expand Down Expand Up @@ -493,7 +494,7 @@ private string GetFormattedParams(string @params)

public string GetUseFlowCode(string alias)
{
return $"\t.Use(\"{alias}\")";
return $"\t.Use<{alias}>()";
}

public string GetBusinessProcessCode(string architectureNamespace, string name, string label, string businessActivitiesCode, string? description = null)
Expand Down
21 changes: 20 additions & 1 deletion C4InterFlow/Structures/Component.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace C4InterFlow.Structures;
using C4InterFlow.Structures.Interfaces;

namespace C4InterFlow.Structures;

/// <summary>
/// The word "component" is a hugely overloaded term in the software development industry, but in this context a
Expand All @@ -17,6 +19,10 @@ public record Component : Structure
public string Container { get; init; }
public Note[]? Notes { get; init; }

public Component(Type type) : this(GetAlias(type), Utils.GetLabelFromAlias(GetAlias(type)))
{ }
public Component(Type type, string label) : this(GetAlias(type), label)
{ }
public Component(string alias) : this(alias, Utils.GetLabelFromAlias(alias))
{ }
public Component(string alias, string label) : this(Utils.GetContainerAlias(alias), alias, label)
Expand All @@ -27,4 +33,17 @@ public Component(string container, string alias, string label) : base(alias, lab
ComponentType = ComponentType.None;
}

public static string GetAlias<T>() where T : IComponentInstance
{
return Utils.GetStructureAlias<T>();
}

public static string GetAlias(Type type)
{
if (!typeof(IComponentInstance).IsAssignableFrom(type))
throw new ArgumentException($"Expected '{typeof(IComponentInstance).FullName}' type, but '{type.FullName}' type provided.", nameof(type));

return Utils.GetStructureAlias(type);
}

}
21 changes: 20 additions & 1 deletion C4InterFlow/Structures/Container.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace C4InterFlow.Structures;
using C4InterFlow.Structures.Interfaces;

namespace C4InterFlow.Structures;

/// <summary>
/// Not Docker! In the C4 model, a container represents an application or a data store. A container is something
Expand All @@ -17,6 +19,10 @@ public record Container : Structure
public string? Technology { get; init; }
public string SoftwareSystem { get; init; }

public Container(Type type) : this(GetAlias(type), Utils.GetLabelFromAlias(GetAlias(type)))
{ }
public Container(Type type, string label) : this(GetAlias(type), label)
{ }
public Container(string alias) : this(alias, Utils.GetLabelFromAlias(alias))
{ }
public Container(string alias, string label) : this(Utils.GetSoftwareSystemAlias(alias), alias, label)
Expand All @@ -26,4 +32,17 @@ public Container(string system, string alias, string label) : base(alias, label)
SoftwareSystem = system;
ContainerType = ContainerType.None;
}

public static string GetAlias<T>() where T : IContainerInstance
{
return Utils.GetStructureAlias<T>();
}

public static string GetAlias(Type type)
{
if (!typeof(IContainerInstance).IsAssignableFrom(type))
throw new ArgumentException($"Expected '{typeof(IContainerInstance).FullName}' type, but '{type.FullName}' type provided.", nameof(type));

return Utils.GetStructureAlias(type);
}
}
25 changes: 24 additions & 1 deletion C4InterFlow/Structures/Entity.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using C4InterFlow.Structures.Interfaces;
using System.ComponentModel;

namespace C4InterFlow.Structures
{
Expand All @@ -22,12 +23,34 @@ public enum EntityType

public record Entity : Structure
{
public Entity(Type type, EntityType entityType) : this(GetAlias(type), Utils.GetLabelFromAlias(GetAlias(type)), entityType)
{ }
public Entity(Type type, string label, EntityType entityType) : this(GetAlias(type), label, entityType)
{ }
public Entity(string alias, EntityType entityType) : this(alias, Utils.GetLabelFromAlias(alias), entityType)
{ }
public Entity(string alias, string label, EntityType entityType) : this(Utils.GetContainerAlias(alias), alias, label, entityType)
{ }
public Entity(string container, string alias, string label, EntityType entityType)
: base(alias, label)
{
EntityType = entityType;
Container = container;
}

public static string GetAlias<T>() where T : IEntityInstance
{
return Utils.GetStructureAlias<T>();
}

public static string GetAlias(Type type)
{
if (!typeof(IEntityInstance).IsAssignableFrom(type))
throw new ArgumentException($"Expected '{typeof(IEntityInstance).FullName}' type, but '{type.FullName}' type provided.", nameof(type));

return Utils.GetStructureAlias(type);
}

public EntityType EntityType { get; init; }
public string Container { get; init; }
public string[] ComposedOfMany { get; init; }
Expand Down
5 changes: 5 additions & 0 deletions C4InterFlow/Structures/Flow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

using C4InterFlow.Structures.Interfaces;
using System.Text.RegularExpressions;

namespace C4InterFlow.Structures
Expand Down Expand Up @@ -513,6 +514,10 @@ public Flow Return(string value)
return this;
}

public Flow Use<T>() where T : IInterfaceInstance
{
return Use(Interface.GetAlias<T>());
}
public Flow Use(string interfaceAlias)
{
var flowType = FlowType.Use;
Expand Down
21 changes: 20 additions & 1 deletion C4InterFlow/Structures/Interface.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
namespace C4InterFlow.Structures
using C4InterFlow.Structures.Interfaces;

namespace C4InterFlow.Structures
{
public record Interface : Structure
{
public Interface(Type type) : this(GetAlias(type), Utils.GetLabelFromAlias(GetAlias(type)))
{ }
public Interface(Type type, string label) : this(GetAlias(type), label)
{ }
public Interface(string alias) : this(alias, Utils.GetLabelFromAlias(alias))
{ }
public Interface(string alias, string label) : this(Utils.GetInterfaceOwnerAlias(alias), alias, label)
Expand All @@ -11,6 +17,19 @@ public Interface(string owner, string alias, string label) : base(alias, label)
Owner = owner;
}

public static string GetAlias<T>() where T : IInterfaceInstance
{
return Utils.GetStructureAlias<T>();
}

public static string GetAlias(Type type)
{
if (!typeof(IInterfaceInstance).IsAssignableFrom(type))
throw new ArgumentException($"Expected '{typeof(IInterfaceInstance).FullName}' type, but '{type.FullName}' type provided.", nameof(type));

return Utils.GetStructureAlias(type);
}

public string Protocol { get; init; }
public bool IsPrivate { get; init; }
public string Path { get; init; }
Expand Down
21 changes: 20 additions & 1 deletion C4InterFlow/Structures/SoftwareSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace C4InterFlow.Structures;
using C4InterFlow.Structures.Interfaces;

namespace C4InterFlow.Structures;

/// <summary>
/// A software system is the highest level of abstraction and describes something that delivers value to its users,
Expand All @@ -9,6 +11,10 @@
/// </summary>
public sealed record SoftwareSystem : Structure
{
public SoftwareSystem(Type type) : this(GetAlias(type), Utils.GetLabelFromAlias(GetAlias(type)))
{ }
public SoftwareSystem(Type type, string label) : this(GetAlias(type), label)
{ }
public SoftwareSystem(string alias) : this(alias, Utils.GetLabelFromAlias(alias))
{ }
public SoftwareSystem(string alias, string label) : base(alias, label)
Expand All @@ -24,4 +30,17 @@ public SoftwareSystem(string alias, string label, string description, Boundary b
Description = description;
Boundary = boundary;
}

public static string GetAlias<T>() where T : ISoftwareSystemInstance
{
return Utils.GetStructureAlias<T>();
}

public static string GetAlias(Type type)
{
if (!typeof(ISoftwareSystemInstance).IsAssignableFrom(type))
throw new ArgumentException($"Expected '{typeof(ISoftwareSystemInstance).FullName}' type, but '{type.FullName}' type provided.", nameof(type));

return Utils.GetStructureAlias(type);
}
}
7 changes: 6 additions & 1 deletion C4InterFlow/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ public static string GetContainerAlias(string alias)

public static string GetStructureAlias<T>()
{
return typeof(T).FullName?.Replace('+', '.') ?? string.Empty;
return GetStructureAlias(typeof(T));
}

public static string GetStructureAlias(Type type)
{
return type.FullName?.Replace('+', '.') ?? string.Empty;
}

public static string GetSoftwareSystemAlias(string alias)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace DotNetEShop.SoftwareSystems
{
public partial class BasketApi : ISoftwareSystemInstance
{
public static SoftwareSystem Instance => new SoftwareSystem(Utils.GetStructureAlias<BasketApi>(), "Basket Api")
public static SoftwareSystem Instance => new SoftwareSystem(typeof(BasketApi), "Basket Api")
{
Description = "",
Boundary = Boundary.Internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class Containers
{
public partial class Data : IContainerInstance
{
public static Container Instance => new Container(Utils.GetStructureAlias<Data>(), "Data")
public static Container Instance => new Container(typeof(Data), "Data")
{
ContainerType = ContainerType.None,
Description = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public partial class Components
{
public partial class RedisBasketRepository : IComponentInstance
{
public static Component Instance => new Component(Utils.GetStructureAlias<RedisBasketRepository>(), "Redis Basket Repository")
public static Component Instance => new Component(typeof(RedisBasketRepository), "Redis Basket Repository")
{
ComponentType = ComponentType.None,
Description = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ public partial class Interfaces
{
public partial class DeleteBasketAsync : IInterfaceInstance
{
public static Interface Instance => new Interface(Utils.GetStructureAlias<DeleteBasketAsync>(), "Delete Basket Async")
public static Interface Instance => new Interface(typeof(DeleteBasketAsync), "Delete Basket Async")
{
Description = "",
Path = "",
IsPrivate = false,
Protocol = "",
Flow = new Flow(Utils.GetStructureAlias<DeleteBasketAsync>())
.Use("DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository.Interfaces.GetBasketKey")
.Use("DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase.Interfaces.KeyDeleteAsync"),
Flow = new Flow(Interface.GetAlias<DeleteBasketAsync>())
.Use<DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository.Interfaces.GetBasketKey>()
.Use<DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase.Interfaces.KeyDeleteAsync>(),
Input = "",
InputTemplate = "",
Output = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ public partial class Interfaces
{
public partial class GetBasketAsync : IInterfaceInstance
{
public static Interface Instance => new Interface(Utils.GetStructureAlias<GetBasketAsync>(), "Get Basket Async")
public static Interface Instance => new Interface(typeof(GetBasketAsync), "Get Basket Async")
{
Description = "",
Path = "",
IsPrivate = false,
Protocol = "",
Flow = new Flow(Utils.GetStructureAlias<GetBasketAsync>())
.Use("DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository.Interfaces.GetBasketKey")
.Use("DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase.Interfaces.StringGetLeaseAsync")
Flow = new Flow(Interface.GetAlias<GetBasketAsync>())
.Use<DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository.Interfaces.GetBasketKey>()
.Use<DotNetEShop.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase.Interfaces.StringGetLeaseAsync>()
.Return(@"JsonSerializer.Deserialize"),
Input = "",
InputTemplate = "",
Expand Down
Loading

0 comments on commit 16ccc26

Please sign in to comment.