diff --git a/src/Services/Flight/src/Flight/Aircrafts/Features/CreatingAircraft/V1/CreateAircraft.cs b/src/Services/Flight/src/Flight/Aircrafts/Features/CreatingAircraft/V1/CreateAircraft.cs index 338a638..0345498 100644 --- a/src/Services/Flight/src/Flight/Aircrafts/Features/CreatingAircraft/V1/CreateAircraft.cs +++ b/src/Services/Flight/src/Flight/Aircrafts/Features/CreatingAircraft/V1/CreateAircraft.cs @@ -7,10 +7,9 @@ using Ardalis.GuardClauses; using BuildingBlocks.Core.CQRS; using BuildingBlocks.Core.Event; using BuildingBlocks.Web; -using Exceptions; -using Models; using Data; using Duende.IdentityServer.EntityFramework.Entities; +using Exceptions; using FluentValidation; using MapsterMapper; using MassTransit; @@ -19,6 +18,8 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.EntityFrameworkCore; +using Models; +using Models.ValueObjects; public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand, IInternalCommand @@ -96,7 +97,7 @@ internal class CreateAircraftHandler : IRequestHandler { - public string Name { get; private set; } - public string Model { get; private set; } - public int ManufacturingYear { get; private set; } + public NameValue Name { get; private set; } + public ModelValue Model { get; private set; } + public ManufacturingYearValue ManufacturingYear { get; private set; } - public static Aircraft Create(Guid id, string name, string model, int manufacturingYear, bool isDeleted = false) + public static Aircraft Create(Guid id, NameValue name, ModelValue model, ManufacturingYearValue manufacturingYear, bool isDeleted = false) { var aircraft = new Aircraft { diff --git a/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ManufacturingYearValue.cs b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ManufacturingYearValue.cs new file mode 100644 index 0000000..5d67e9c --- /dev/null +++ b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ManufacturingYearValue.cs @@ -0,0 +1,18 @@ +namespace Flight.Aircrafts.Models.ValueObjects; +using System; + +public record ManufacturingYearValue : GenericValueObject +{ + public ManufacturingYearValue(int value) : base(value) + { + if (value < 1900 || value > DateTime.Now.Year) + { + throw new ArgumentException("Manufacturing year is invalid."); + } + } + + public static ManufacturingYearValue Of(int value) + { + return new ManufacturingYearValue(value); + } +} diff --git a/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ModelValue.cs b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ModelValue.cs new file mode 100644 index 0000000..4284baa --- /dev/null +++ b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/ModelValue.cs @@ -0,0 +1,17 @@ +namespace Flight.Aircrafts.Models.ValueObjects; +using System; +public record ModelValue : GenericValueObject +{ + public ModelValue(string value) : base(value) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Model cannot be empty or whitespace."); + } + } + + public static ModelValue Of(string value) + { + return new ModelValue(value); + } +} diff --git a/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/NameValue.cs b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/NameValue.cs new file mode 100644 index 0000000..9ef89b7 --- /dev/null +++ b/src/Services/Flight/src/Flight/Aircrafts/Models/ValueObjects/NameValue.cs @@ -0,0 +1,18 @@ +namespace Flight.Aircrafts.Models.ValueObjects; +using System; + +public record NameValue : GenericValueObject +{ + public NameValue(string value) : base(value) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Name cannot be empty or whitespace."); + } + } + + public static NameValue Of(string value) + { + return new NameValue(value); + } +} diff --git a/src/Services/Flight/src/Flight/Data/Seed/InitialData.cs b/src/Services/Flight/src/Flight/Data/Seed/InitialData.cs index 2953dd7..3fe9c95 100644 --- a/src/Services/Flight/src/Flight/Data/Seed/InitialData.cs +++ b/src/Services/Flight/src/Flight/Data/Seed/InitialData.cs @@ -1,9 +1,10 @@ -namespace Flight.Data.Seed; +namespace Flight.Data.Seed; using System; using System.Collections.Generic; using System.Linq; using Aircrafts.Models; +using Aircrafts.Models.ValueObjects; using Airports.Models; using Flights.Models; using MassTransit; @@ -11,9 +12,9 @@ using Seats.Models; public static class InitialData { - public static List Airports { get;} - public static List Aircrafts { get;} - public static List Seats { get;} + public static List Airports { get; } + public static List Aircrafts { get; } + public static List Seats { get; } public static List Flights { get; } @@ -27,9 +28,9 @@ public static class InitialData Aircrafts = new List { - Aircraft.Create(new Guid("3c5c0000-97c6-fc34-fcd3-08db322230c8"), "Boeing 737", "B737", 2005), - Aircraft.Create(new Guid("3c5c0000-97c6-fc34-2e04-08db322230c9"), "Airbus 300", "A300", 2000), - Aircraft.Create(new Guid("3c5c0000-97c6-fc34-2e11-08db322230c9"), "Airbus 320", "A320", 2003) + Aircraft.Create(new Guid("3c5c0000-97c6-fc34-fcd3-08db322230c8"), NameValue.Of("Boeing 737"), ModelValue.Of("B737"), ManufacturingYearValue.Of(2005)), + Aircraft.Create(new Guid("3c5c0000-97c6-fc34-2e04-08db322230c9"), NameValue.Of("Airbus 300"), ModelValue.Of("A300"), ManufacturingYearValue.Of(2000)), + Aircraft.Create(new Guid("3c5c0000-97c6-fc34-2e11-08db322230c9"), NameValue.Of("Airbus 320"), ModelValue.Of("A320"), ManufacturingYearValue.Of(2003)) }; diff --git a/src/Services/Flight/src/Flight/GenericValueObject.cs b/src/Services/Flight/src/Flight/GenericValueObject.cs new file mode 100644 index 0000000..9088ed7 --- /dev/null +++ b/src/Services/Flight/src/Flight/GenericValueObject.cs @@ -0,0 +1,13 @@ +namespace Flight; +public record GenericValueObject(T Value) +{ + public override string ToString() + { + return Value.ToString(); + } + + public static implicit operator T(GenericValueObject valueObject) + { + return valueObject.Value; + } +} diff --git a/src/Services/Flight/tests/UnitTest/Common/DbContextFactory.cs b/src/Services/Flight/tests/UnitTest/Common/DbContextFactory.cs index 97fccd7..d8cc94b 100644 --- a/src/Services/Flight/tests/UnitTest/Common/DbContextFactory.cs +++ b/src/Services/Flight/tests/UnitTest/Common/DbContextFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Flight.Data; using Flight.Flights.Enums; @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; namespace Unit.Test.Common; +using global::Flight.Aircrafts.Models.ValueObjects; using MassTransit; public static class DbContextFactory @@ -45,9 +46,9 @@ public static class DbContextFactory var aircrafts = new List { - global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft1, "Boeing 737", "B737", 2005), - global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft2, "Airbus 300", "A300", 2000), - global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft3, "Airbus 320", "A320", 2003) + global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft1, NameValue.Of("Boeing 737"), ModelValue.Of("B737"), ManufacturingYearValue.Of(2005)), + global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft2, NameValue.Of("Airbus 300"), ModelValue.Of("A300"), ManufacturingYearValue.Of(2000)), + global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft3, NameValue.Of("Airbus 320"), ModelValue.Of("A320"), ManufacturingYearValue.Of(2003)) }; context.Aircraft.AddRange(aircrafts); diff --git a/src/Services/Passenger/src/Passenger/Identity/Consumers/RegisteringNewUser/V1/RegisterNewUser.cs b/src/Services/Passenger/src/Passenger/Identity/Consumers/RegisteringNewUser/V1/RegisterNewUser.cs index 27456a8..cae62d6 100644 --- a/src/Services/Passenger/src/Passenger/Identity/Consumers/RegisteringNewUser/V1/RegisterNewUser.cs +++ b/src/Services/Passenger/src/Passenger/Identity/Consumers/RegisteringNewUser/V1/RegisterNewUser.cs @@ -5,12 +5,13 @@ using BuildingBlocks.Contracts.EventBus.Messages; using BuildingBlocks.Core; using BuildingBlocks.Core.Event; using BuildingBlocks.Web; +using Data; using Humanizer; using MassTransit; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Data; +using Passenger.Passengers.Models.ValueObjects; public class RegisterNewUserHandler : IConsumer { @@ -44,8 +45,8 @@ public class RegisterNewUserHandler : IConsumer return; } - var passenger = Passengers.Models.Passenger.Create(NewId.NextGuid(), context.Message.Name, - context.Message.PassportNumber); + var passenger = Passengers.Models.Passenger.Create(NewId.NextGuid(), NameValue.Of(context.Message.Name), + PassportNumberValue.Of(context.Message.PassportNumber)); await _passengerDbContext.AddAsync(passenger); diff --git a/src/Services/Passenger/src/Passenger/Passengers/Features/CompletingRegisterPassenger/V1/CompleteRegisterPassenger.cs b/src/Services/Passenger/src/Passenger/Passengers/Features/CompletingRegisterPassenger/V1/CompleteRegisterPassenger.cs index d6bdf12..5681936 100644 --- a/src/Services/Passenger/src/Passenger/Passengers/Features/CompletingRegisterPassenger/V1/CompleteRegisterPassenger.cs +++ b/src/Services/Passenger/src/Passenger/Passengers/Features/CompletingRegisterPassenger/V1/CompleteRegisterPassenger.cs @@ -4,18 +4,19 @@ using Ardalis.GuardClauses; using BuildingBlocks.Core.CQRS; using BuildingBlocks.Core.Event; using BuildingBlocks.Web; -using Exceptions; -using FluentValidation; -using MapsterMapper; -using Microsoft.EntityFrameworkCore; using Data; using Dtos; using Duende.IdentityServer.EntityFramework.Entities; +using Exceptions; +using FluentValidation; +using MapsterMapper; using MassTransit; using MediatR; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; +using Microsoft.EntityFrameworkCore; +using Passenger.Passengers.Models.ValueObjects; public record CompleteRegisterPassenger (string PassportNumber, Enums.PassengerType PassengerType, int Age) : ICommand, @@ -104,7 +105,7 @@ internal class CompleteRegisterPassengerCommandHandler : ICommandHandler { - public Passenger CompleteRegistrationPassenger(Guid id, string name, string passportNumber, Enums.PassengerType passengerType, int age, bool isDeleted = false) + public Passenger CompleteRegistrationPassenger(Guid id, NameValue name, PassportNumberValue passportNumber, Enums.PassengerType passengerType, AgeValue age, bool isDeleted = false) { var passenger = new Passenger { + Id = id, Name = name, PassportNumber = passportNumber, PassengerType = passengerType, Age = age, - Id = id, IsDeleted = isDeleted }; var @event = new PassengerRegistrationCompletedDomainEvent(passenger.Id, passenger.Name, passenger.PassportNumber, - passenger.PassengerType, passenger.Age, passenger.IsDeleted); + passenger.PassengerType, passenger.Age.Value, passenger.IsDeleted); passenger.AddDomainEvent(@event); @@ -28,7 +29,7 @@ public record Passenger : Aggregate } - public static Passenger Create(Guid id, string name, string passportNumber, bool isDeleted = false) + public static Passenger Create(Guid id, NameValue name, PassportNumberValue passportNumber, bool isDeleted = false) { var passenger = new Passenger { Id = id, Name = name, PassportNumber = passportNumber, IsDeleted = isDeleted }; @@ -40,8 +41,8 @@ public record Passenger : Aggregate } - public string PassportNumber { get; private set; } - public string Name { get; private set; } + public PassportNumberValue PassportNumber { get; private set; } + public NameValue Name { get; private set; } public Enums.PassengerType PassengerType { get; private set; } - public int Age { get; private set; } + public AgeValue Age { get; private set; } } diff --git a/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/AgeValue.cs b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/AgeValue.cs new file mode 100644 index 0000000..5354395 --- /dev/null +++ b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/AgeValue.cs @@ -0,0 +1,18 @@ +namespace Passenger.Passengers.Models.ValueObjects; +using System; + +public record AgeValue : GenericValueObject +{ + public AgeValue(int value) : base(value) + { + if (value < 0) + { + throw new ArgumentException("Age cannot be negative."); + } + Value = value; + } + public static AgeValue Of(int value) + { + return new AgeValue(value); + } +} diff --git a/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/GenericValueObject.cs b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/GenericValueObject.cs new file mode 100644 index 0000000..ee0353a --- /dev/null +++ b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/GenericValueObject.cs @@ -0,0 +1,13 @@ +namespace Passenger.Passengers.Models.ValueObjects; +public record GenericValueObject(T Value) +{ + public override string ToString() + { + return Value.ToString(); + } + + public static implicit operator T(GenericValueObject valueObject) + { + return valueObject.Value; + } +} diff --git a/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/NameValue.cs b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/NameValue.cs new file mode 100644 index 0000000..b34b381 --- /dev/null +++ b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/NameValue.cs @@ -0,0 +1,18 @@ +namespace Passenger.Passengers.Models.ValueObjects; +using System; + +public record NameValue : GenericValueObject +{ + public NameValue(string value) : base(value) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Name cannot be empty or whitespace."); + } + Value = value; + } + public static NameValue Of(string value) + { + return new NameValue(value); + } +} diff --git a/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/PassportNumberValue.cs b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/PassportNumberValue.cs new file mode 100644 index 0000000..436f388 --- /dev/null +++ b/src/Services/Passenger/src/Passenger/Passengers/Models/ValueObjects/PassportNumberValue.cs @@ -0,0 +1,19 @@ +namespace Passenger.Passengers.Models.ValueObjects; +using System; + + +public record PassportNumberValue : GenericValueObject +{ + public PassportNumberValue(string value) : base(value) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Passport number cannot be empty or whitespace."); + } + Value = value; + } + public static PassportNumberValue Of(string value) + { + return new PassportNumberValue(value); + } +}