diff --git a/Route.sln b/Route.sln new file mode 100644 index 0000000..e661097 --- /dev/null +++ b/Route.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Route", "Route\Route.csproj", "{4BD60E88-C077-4C5A-8563-81758B30D637}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Route.sln b/Route.sln new file mode 100644 index 0000000..e661097 --- /dev/null +++ b/Route.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Route", "Route\Route.csproj", "{4BD60E88-C077-4C5A-8563-81758B30D637}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Route/ExampleAggregates.cs b/Route/ExampleAggregates.cs new file mode 100644 index 0000000..2e02151 --- /dev/null +++ b/Route/ExampleAggregates.cs @@ -0,0 +1,100 @@ +namespace RouteExample1; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + public List Locations { get; } = new(); + public int AlarmCount { get; private set; } + public DateTime LastAlarmDate = DateTime.MinValue; + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public void AddLocation(Location location) + { + location.AddToRoute(RouteId); + Locations.Add(location.LocationId); + } + + public void Consume(AlarmTriggered alarmTriggered) + { + if (Locations.Contains(alarmTriggered.LocationId) && LastAlarmDate < alarmTriggered.Date) + { + AlarmCount++; + LastAlarmDate = alarmTriggered.Date; + } + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coors{ get; } + public Guid? RouteId { get; private set; } + public Guid? VendingMachineId { get; private set; } + + public Location(Guid locationId, string name, LatLong coors, Guid? routeId = null) + { + LocationId = locationId; + Name = name; + Coors = coors; + RouteId = routeId; + } + + public void AddToRoute(Guid routeId) + { + RouteId = routeId; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + vendingMachine.SetLocation(LocationId); + VendingMachineId = vendingMachine.VendingMachineId; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public Guid LocationId { get; private set; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachineId) + { + VendingMachineId = vendingMachineId; + } + + public void SetLocation(Guid locationId) + { + LocationId = locationId; + } + + public void Alarm(DateTime date) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, LocationId, date)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var location = new Location(Guid.NewGuid(), "Location 1", new LatLong(1, 1)); + location.AddToRoute(route.RouteId); + + var vendingMachine = new VendingMachine(Guid.Empty); + vendingMachine.SetLocation(location.LocationId); + + vendingMachine.Alarm(DateTime.Now); + } +} \ No newline at end of file diff --git a/Route.sln b/Route.sln new file mode 100644 index 0000000..e661097 --- /dev/null +++ b/Route.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Route", "Route\Route.csproj", "{4BD60E88-C077-4C5A-8563-81758B30D637}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Route/ExampleAggregates.cs b/Route/ExampleAggregates.cs new file mode 100644 index 0000000..2e02151 --- /dev/null +++ b/Route/ExampleAggregates.cs @@ -0,0 +1,100 @@ +namespace RouteExample1; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + public List Locations { get; } = new(); + public int AlarmCount { get; private set; } + public DateTime LastAlarmDate = DateTime.MinValue; + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public void AddLocation(Location location) + { + location.AddToRoute(RouteId); + Locations.Add(location.LocationId); + } + + public void Consume(AlarmTriggered alarmTriggered) + { + if (Locations.Contains(alarmTriggered.LocationId) && LastAlarmDate < alarmTriggered.Date) + { + AlarmCount++; + LastAlarmDate = alarmTriggered.Date; + } + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coors{ get; } + public Guid? RouteId { get; private set; } + public Guid? VendingMachineId { get; private set; } + + public Location(Guid locationId, string name, LatLong coors, Guid? routeId = null) + { + LocationId = locationId; + Name = name; + Coors = coors; + RouteId = routeId; + } + + public void AddToRoute(Guid routeId) + { + RouteId = routeId; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + vendingMachine.SetLocation(LocationId); + VendingMachineId = vendingMachine.VendingMachineId; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public Guid LocationId { get; private set; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachineId) + { + VendingMachineId = vendingMachineId; + } + + public void SetLocation(Guid locationId) + { + LocationId = locationId; + } + + public void Alarm(DateTime date) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, LocationId, date)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var location = new Location(Guid.NewGuid(), "Location 1", new LatLong(1, 1)); + location.AddToRoute(route.RouteId); + + var vendingMachine = new VendingMachine(Guid.Empty); + vendingMachine.SetLocation(location.LocationId); + + vendingMachine.Alarm(DateTime.Now); + } +} \ No newline at end of file diff --git a/Route/ExampleHierarchy.cs b/Route/ExampleHierarchy.cs new file mode 100644 index 0000000..6ddf865 --- /dev/null +++ b/Route/ExampleHierarchy.cs @@ -0,0 +1,101 @@ +namespace RouteExample2; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + + public int AlarmCount => Locations.Sum(x => x.VendingMachine?.NewAlarms.Count ?? 0); + public DateTime LastAlarmDate => Locations.Max(x => x.VendingMachine?.NewAlarms.Max(y => y.Date) ?? DateTime.MinValue); + + private List Locations { get; } = new(); + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public Guid AddLocation(string name, LatLong coords) + { + var locationId = Guid.NewGuid(); + Locations.Add(new Location(locationId, name, coords)); + return locationId; + } + + public Guid AddVendingMachineToLocation(Guid locationId) + { + var location = Locations.SingleOrDefault(x => x.LocationId == locationId); + if (location == null) + { + throw new InvalidOperationException("Location is not associated to route."); + } + + var vendingMachineId = Guid.NewGuid(); + location.AssociateVendingMachine(new VendingMachine(vendingMachineId)); + return vendingMachineId; + } + + public void Alarm(Guid vendingMachineId, DateTime date) + { + var location = Locations.SingleOrDefault(x => x.VendingMachine != null && x.VendingMachine.VendingMachineId == vendingMachineId); + if (location == null) + { + throw new InvalidOperationException("Vending machine is not associated to route."); + } + + location.VendingMachine!.AddAlarm(location.LocationId, date); + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coords{ get; } + public VendingMachine? VendingMachine { get; private set; } + + public Location(Guid locationId, string name, LatLong coords) + { + LocationId = locationId; + Name = name; + Coords = coords; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + VendingMachine = vendingMachine; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachine) + { + VendingMachineId = vendingMachine; + } + + public void AddAlarm(Guid locationId, DateTime dateTime) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, locationId, dateTime)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var locationId = route.AddLocation("Location 1", new LatLong(1, 1)); + var vendingMachineId = route.AddVendingMachineToLocation(locationId); + + route.Alarm(vendingMachineId, DateTime.UtcNow); + } +} diff --git a/Route.sln b/Route.sln new file mode 100644 index 0000000..e661097 --- /dev/null +++ b/Route.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Route", "Route\Route.csproj", "{4BD60E88-C077-4C5A-8563-81758B30D637}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Route/ExampleAggregates.cs b/Route/ExampleAggregates.cs new file mode 100644 index 0000000..2e02151 --- /dev/null +++ b/Route/ExampleAggregates.cs @@ -0,0 +1,100 @@ +namespace RouteExample1; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + public List Locations { get; } = new(); + public int AlarmCount { get; private set; } + public DateTime LastAlarmDate = DateTime.MinValue; + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public void AddLocation(Location location) + { + location.AddToRoute(RouteId); + Locations.Add(location.LocationId); + } + + public void Consume(AlarmTriggered alarmTriggered) + { + if (Locations.Contains(alarmTriggered.LocationId) && LastAlarmDate < alarmTriggered.Date) + { + AlarmCount++; + LastAlarmDate = alarmTriggered.Date; + } + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coors{ get; } + public Guid? RouteId { get; private set; } + public Guid? VendingMachineId { get; private set; } + + public Location(Guid locationId, string name, LatLong coors, Guid? routeId = null) + { + LocationId = locationId; + Name = name; + Coors = coors; + RouteId = routeId; + } + + public void AddToRoute(Guid routeId) + { + RouteId = routeId; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + vendingMachine.SetLocation(LocationId); + VendingMachineId = vendingMachine.VendingMachineId; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public Guid LocationId { get; private set; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachineId) + { + VendingMachineId = vendingMachineId; + } + + public void SetLocation(Guid locationId) + { + LocationId = locationId; + } + + public void Alarm(DateTime date) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, LocationId, date)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var location = new Location(Guid.NewGuid(), "Location 1", new LatLong(1, 1)); + location.AddToRoute(route.RouteId); + + var vendingMachine = new VendingMachine(Guid.Empty); + vendingMachine.SetLocation(location.LocationId); + + vendingMachine.Alarm(DateTime.Now); + } +} \ No newline at end of file diff --git a/Route/ExampleHierarchy.cs b/Route/ExampleHierarchy.cs new file mode 100644 index 0000000..6ddf865 --- /dev/null +++ b/Route/ExampleHierarchy.cs @@ -0,0 +1,101 @@ +namespace RouteExample2; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + + public int AlarmCount => Locations.Sum(x => x.VendingMachine?.NewAlarms.Count ?? 0); + public DateTime LastAlarmDate => Locations.Max(x => x.VendingMachine?.NewAlarms.Max(y => y.Date) ?? DateTime.MinValue); + + private List Locations { get; } = new(); + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public Guid AddLocation(string name, LatLong coords) + { + var locationId = Guid.NewGuid(); + Locations.Add(new Location(locationId, name, coords)); + return locationId; + } + + public Guid AddVendingMachineToLocation(Guid locationId) + { + var location = Locations.SingleOrDefault(x => x.LocationId == locationId); + if (location == null) + { + throw new InvalidOperationException("Location is not associated to route."); + } + + var vendingMachineId = Guid.NewGuid(); + location.AssociateVendingMachine(new VendingMachine(vendingMachineId)); + return vendingMachineId; + } + + public void Alarm(Guid vendingMachineId, DateTime date) + { + var location = Locations.SingleOrDefault(x => x.VendingMachine != null && x.VendingMachine.VendingMachineId == vendingMachineId); + if (location == null) + { + throw new InvalidOperationException("Vending machine is not associated to route."); + } + + location.VendingMachine!.AddAlarm(location.LocationId, date); + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coords{ get; } + public VendingMachine? VendingMachine { get; private set; } + + public Location(Guid locationId, string name, LatLong coords) + { + LocationId = locationId; + Name = name; + Coords = coords; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + VendingMachine = vendingMachine; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachine) + { + VendingMachineId = vendingMachine; + } + + public void AddAlarm(Guid locationId, DateTime dateTime) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, locationId, dateTime)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var locationId = route.AddLocation("Location 1", new LatLong(1, 1)); + var vendingMachineId = route.AddVendingMachineToLocation(locationId); + + route.Alarm(vendingMachineId, DateTime.UtcNow); + } +} diff --git a/Route/NoAggregate.cs b/Route/NoAggregate.cs new file mode 100644 index 0000000..270928a --- /dev/null +++ b/Route/NoAggregate.cs @@ -0,0 +1,102 @@ +namespace RouteExample4; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + + public int AlarmCount => Locations.Sum(x => x.VendingMachine?.NewAlarms.Count ?? 0); + public DateTime LastAlarmDate => Locations.Max(x => x.VendingMachine?.NewAlarms.Max(y => y.Date) ?? DateTime.MinValue); + + public List Locations { get; } = new(); + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public Guid AddLocation(string name, LatLong coords) + { + var locationId = Guid.NewGuid(); + Locations.Add(new Location(locationId, name, coords)); + return locationId; + } + + public Guid AddVendingMachineToLocation(Guid locationId) + { + var location = Locations.SingleOrDefault(x => x.LocationId == locationId); + if (location == null) + { + throw new InvalidOperationException("Location is not associated to route."); + } + + var vendingMachineId = Guid.NewGuid(); + location.AssociateVendingMachine(new VendingMachine(vendingMachineId)); + return vendingMachineId; + } + + public void Alarm(Guid vendingMachineId, DateTime date) + { + var location = Locations.SingleOrDefault(x => x.VendingMachine != null && x.VendingMachine.VendingMachineId == vendingMachineId); + if (location == null) + { + throw new InvalidOperationException("Vending machine is not associated to route."); + } + + location.VendingMachine!.AddAlarm(location.LocationId, date); + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coords{ get; } + public VendingMachine? VendingMachine { get; private set; } + + public Location(Guid locationId, string name, LatLong coords) + { + LocationId = locationId; + Name = name; + Coords = coords; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + VendingMachine = vendingMachine; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachine) + { + VendingMachineId = vendingMachine; + } + + public void AddAlarm(Guid locationId, DateTime dateTime) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, locationId, dateTime)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var locationId = route.AddLocation("Location 1", new LatLong(1, 1)); + route.AddVendingMachineToLocation(locationId); + + var vendingMachine = route.Locations.Single(x => x.LocationId == locationId).VendingMachine; + vendingMachine!.AddAlarm(locationId, DateTime.UtcNow); + } +} diff --git a/Route.sln b/Route.sln new file mode 100644 index 0000000..e661097 --- /dev/null +++ b/Route.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Route", "Route\Route.csproj", "{4BD60E88-C077-4C5A-8563-81758B30D637}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BD60E88-C077-4C5A-8563-81758B30D637}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Route/ExampleAggregates.cs b/Route/ExampleAggregates.cs new file mode 100644 index 0000000..2e02151 --- /dev/null +++ b/Route/ExampleAggregates.cs @@ -0,0 +1,100 @@ +namespace RouteExample1; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + public List Locations { get; } = new(); + public int AlarmCount { get; private set; } + public DateTime LastAlarmDate = DateTime.MinValue; + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public void AddLocation(Location location) + { + location.AddToRoute(RouteId); + Locations.Add(location.LocationId); + } + + public void Consume(AlarmTriggered alarmTriggered) + { + if (Locations.Contains(alarmTriggered.LocationId) && LastAlarmDate < alarmTriggered.Date) + { + AlarmCount++; + LastAlarmDate = alarmTriggered.Date; + } + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coors{ get; } + public Guid? RouteId { get; private set; } + public Guid? VendingMachineId { get; private set; } + + public Location(Guid locationId, string name, LatLong coors, Guid? routeId = null) + { + LocationId = locationId; + Name = name; + Coors = coors; + RouteId = routeId; + } + + public void AddToRoute(Guid routeId) + { + RouteId = routeId; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + vendingMachine.SetLocation(LocationId); + VendingMachineId = vendingMachine.VendingMachineId; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public Guid LocationId { get; private set; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachineId) + { + VendingMachineId = vendingMachineId; + } + + public void SetLocation(Guid locationId) + { + LocationId = locationId; + } + + public void Alarm(DateTime date) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, LocationId, date)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var location = new Location(Guid.NewGuid(), "Location 1", new LatLong(1, 1)); + location.AddToRoute(route.RouteId); + + var vendingMachine = new VendingMachine(Guid.Empty); + vendingMachine.SetLocation(location.LocationId); + + vendingMachine.Alarm(DateTime.Now); + } +} \ No newline at end of file diff --git a/Route/ExampleHierarchy.cs b/Route/ExampleHierarchy.cs new file mode 100644 index 0000000..6ddf865 --- /dev/null +++ b/Route/ExampleHierarchy.cs @@ -0,0 +1,101 @@ +namespace RouteExample2; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + + public int AlarmCount => Locations.Sum(x => x.VendingMachine?.NewAlarms.Count ?? 0); + public DateTime LastAlarmDate => Locations.Max(x => x.VendingMachine?.NewAlarms.Max(y => y.Date) ?? DateTime.MinValue); + + private List Locations { get; } = new(); + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public Guid AddLocation(string name, LatLong coords) + { + var locationId = Guid.NewGuid(); + Locations.Add(new Location(locationId, name, coords)); + return locationId; + } + + public Guid AddVendingMachineToLocation(Guid locationId) + { + var location = Locations.SingleOrDefault(x => x.LocationId == locationId); + if (location == null) + { + throw new InvalidOperationException("Location is not associated to route."); + } + + var vendingMachineId = Guid.NewGuid(); + location.AssociateVendingMachine(new VendingMachine(vendingMachineId)); + return vendingMachineId; + } + + public void Alarm(Guid vendingMachineId, DateTime date) + { + var location = Locations.SingleOrDefault(x => x.VendingMachine != null && x.VendingMachine.VendingMachineId == vendingMachineId); + if (location == null) + { + throw new InvalidOperationException("Vending machine is not associated to route."); + } + + location.VendingMachine!.AddAlarm(location.LocationId, date); + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coords{ get; } + public VendingMachine? VendingMachine { get; private set; } + + public Location(Guid locationId, string name, LatLong coords) + { + LocationId = locationId; + Name = name; + Coords = coords; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + VendingMachine = vendingMachine; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachine) + { + VendingMachineId = vendingMachine; + } + + public void AddAlarm(Guid locationId, DateTime dateTime) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, locationId, dateTime)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var locationId = route.AddLocation("Location 1", new LatLong(1, 1)); + var vendingMachineId = route.AddVendingMachineToLocation(locationId); + + route.Alarm(vendingMachineId, DateTime.UtcNow); + } +} diff --git a/Route/NoAggregate.cs b/Route/NoAggregate.cs new file mode 100644 index 0000000..270928a --- /dev/null +++ b/Route/NoAggregate.cs @@ -0,0 +1,102 @@ +namespace RouteExample4; + +public class Route +{ + public Guid RouteId { get; } + public string Name { get; } + + public int AlarmCount => Locations.Sum(x => x.VendingMachine?.NewAlarms.Count ?? 0); + public DateTime LastAlarmDate => Locations.Max(x => x.VendingMachine?.NewAlarms.Max(y => y.Date) ?? DateTime.MinValue); + + public List Locations { get; } = new(); + + public Route(Guid routeId, string name) + { + RouteId = routeId; + Name = name; + } + + public Guid AddLocation(string name, LatLong coords) + { + var locationId = Guid.NewGuid(); + Locations.Add(new Location(locationId, name, coords)); + return locationId; + } + + public Guid AddVendingMachineToLocation(Guid locationId) + { + var location = Locations.SingleOrDefault(x => x.LocationId == locationId); + if (location == null) + { + throw new InvalidOperationException("Location is not associated to route."); + } + + var vendingMachineId = Guid.NewGuid(); + location.AssociateVendingMachine(new VendingMachine(vendingMachineId)); + return vendingMachineId; + } + + public void Alarm(Guid vendingMachineId, DateTime date) + { + var location = Locations.SingleOrDefault(x => x.VendingMachine != null && x.VendingMachine.VendingMachineId == vendingMachineId); + if (location == null) + { + throw new InvalidOperationException("Vending machine is not associated to route."); + } + + location.VendingMachine!.AddAlarm(location.LocationId, date); + } +} + +public class Location +{ + public Guid LocationId { get; } + public string Name { get; } + public LatLong Coords{ get; } + public VendingMachine? VendingMachine { get; private set; } + + public Location(Guid locationId, string name, LatLong coords) + { + LocationId = locationId; + Name = name; + Coords = coords; + } + + public void AssociateVendingMachine(VendingMachine vendingMachine) + { + VendingMachine = vendingMachine; + } +} + +public class VendingMachine +{ + public Guid VendingMachineId { get; } + public List NewAlarms { get; } = new(); + + public VendingMachine(Guid vendingMachine) + { + VendingMachineId = vendingMachine; + } + + public void AddAlarm(Guid locationId, DateTime dateTime) + { + NewAlarms.Add(new AlarmTriggered(VendingMachineId, locationId, dateTime)); + } +} + +public record LatLong(double Lat, double Lng); +public record AlarmTriggered(Guid VendingMachineId, Guid LocationId, DateTime Date); + +public class Example +{ + public void Usage() + { + var route = new Route(Guid.NewGuid(), "Route 1"); + + var locationId = route.AddLocation("Location 1", new LatLong(1, 1)); + route.AddVendingMachineToLocation(locationId); + + var vendingMachine = route.Locations.Single(x => x.LocationId == locationId).VendingMachine; + vendingMachine!.AddAlarm(locationId, DateTime.UtcNow); + } +} diff --git a/Route/Route.csproj b/Route/Route.csproj new file mode 100644 index 0000000..6836c68 --- /dev/null +++ b/Route/Route.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + +