mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-05-03 03:11:51 +08:00
Add Value Objects
This commit is contained in:
parent
0d8f52b573
commit
5c5be8eef8
@ -7,10 +7,9 @@ using Ardalis.GuardClauses;
|
|||||||
using BuildingBlocks.Core.CQRS;
|
using BuildingBlocks.Core.CQRS;
|
||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Exceptions;
|
|
||||||
using Models;
|
|
||||||
using Data;
|
using Data;
|
||||||
using Duende.IdentityServer.EntityFramework.Entities;
|
using Duende.IdentityServer.EntityFramework.Entities;
|
||||||
|
using Exceptions;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using MapsterMapper;
|
using MapsterMapper;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
@ -19,6 +18,8 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Models;
|
||||||
|
using Models.ValueObjects;
|
||||||
|
|
||||||
public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<CreateAircraftResult>,
|
public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<CreateAircraftResult>,
|
||||||
IInternalCommand
|
IInternalCommand
|
||||||
@ -96,7 +97,7 @@ internal class CreateAircraftHandler : IRequestHandler<CreateAircraft, CreateAir
|
|||||||
throw new AircraftAlreadyExistException();
|
throw new AircraftAlreadyExistException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var aircraftEntity = Aircraft.Create(request.Id, request.Name, request.Model, request.ManufacturingYear);
|
var aircraftEntity = Aircraft.Create(request.Id, NameValue.Of(request.Name), ModelValue.Of(request.Model), ManufacturingYearValue.Of(request.ManufacturingYear));
|
||||||
|
|
||||||
var newAircraft = (await _flightDbContext.Aircraft.AddAsync(aircraftEntity, cancellationToken))?.Entity;
|
var newAircraft = (await _flightDbContext.Aircraft.AddAsync(aircraftEntity, cancellationToken))?.Entity;
|
||||||
|
|
||||||
|
|||||||
@ -4,14 +4,15 @@ namespace Flight.Aircrafts.Models;
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Features.CreatingAircraft.V1;
|
using Features.CreatingAircraft.V1;
|
||||||
|
using ValueObjects;
|
||||||
|
|
||||||
public record Aircraft : Aggregate<Guid>
|
public record Aircraft : Aggregate<Guid>
|
||||||
{
|
{
|
||||||
public string Name { get; private set; }
|
public NameValue Name { get; private set; }
|
||||||
public string Model { get; private set; }
|
public ModelValue Model { get; private set; }
|
||||||
public int ManufacturingYear { 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
|
var aircraft = new Aircraft
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
namespace Flight.Aircrafts.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public record ManufacturingYearValue : GenericValueObject<int>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
namespace Flight.Aircrafts.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
public record ModelValue : GenericValueObject<string>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
namespace Flight.Aircrafts.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public record NameValue : GenericValueObject<string>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,10 @@
|
|||||||
namespace Flight.Data.Seed;
|
namespace Flight.Data.Seed;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Aircrafts.Models;
|
using Aircrafts.Models;
|
||||||
|
using Aircrafts.Models.ValueObjects;
|
||||||
using Airports.Models;
|
using Airports.Models;
|
||||||
using Flights.Models;
|
using Flights.Models;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
@ -11,9 +12,9 @@ using Seats.Models;
|
|||||||
|
|
||||||
public static class InitialData
|
public static class InitialData
|
||||||
{
|
{
|
||||||
public static List<Airport> Airports { get;}
|
public static List<Airport> Airports { get; }
|
||||||
public static List<Aircraft> Aircrafts { get;}
|
public static List<Aircraft> Aircrafts { get; }
|
||||||
public static List<Seat> Seats { get;}
|
public static List<Seat> Seats { get; }
|
||||||
public static List<Flight> Flights { get; }
|
public static List<Flight> Flights { get; }
|
||||||
|
|
||||||
|
|
||||||
@ -27,9 +28,9 @@ public static class InitialData
|
|||||||
|
|
||||||
Aircrafts = new List<Aircraft>
|
Aircrafts = new List<Aircraft>
|
||||||
{
|
{
|
||||||
Aircraft.Create(new Guid("3c5c0000-97c6-fc34-fcd3-08db322230c8"), "Boeing 737", "B737", 2005),
|
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"), "Airbus 300", "A300", 2000),
|
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"), "Airbus 320", "A320", 2003)
|
Aircraft.Create(new Guid("3c5c0000-97c6-fc34-2e11-08db322230c9"), NameValue.Of("Airbus 320"), ModelValue.Of("A320"), ManufacturingYearValue.Of(2003))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
src/Services/Flight/src/Flight/GenericValueObject.cs
Normal file
13
src/Services/Flight/src/Flight/GenericValueObject.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace Flight;
|
||||||
|
public record GenericValueObject<T>(T Value)
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator T(GenericValueObject<T> valueObject)
|
||||||
|
{
|
||||||
|
return valueObject.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Flight.Flights.Enums;
|
using Flight.Flights.Enums;
|
||||||
@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Unit.Test.Common;
|
namespace Unit.Test.Common;
|
||||||
|
|
||||||
|
using global::Flight.Aircrafts.Models.ValueObjects;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
|
|
||||||
public static class DbContextFactory
|
public static class DbContextFactory
|
||||||
@ -45,9 +46,9 @@ public static class DbContextFactory
|
|||||||
|
|
||||||
var aircrafts = new List<global::Flight.Aircrafts.Models.Aircraft>
|
var aircrafts = new List<global::Flight.Aircrafts.Models.Aircraft>
|
||||||
{
|
{
|
||||||
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft1, "Boeing 737", "B737", 2005),
|
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft1, NameValue.Of("Boeing 737"), ModelValue.Of("B737"), ManufacturingYearValue.Of(2005)),
|
||||||
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft2, "Airbus 300", "A300", 2000),
|
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft2, NameValue.Of("Airbus 300"), ModelValue.Of("A300"), ManufacturingYearValue.Of(2000)),
|
||||||
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft3, "Airbus 320", "A320", 2003)
|
global::Flight.Aircrafts.Models.Aircraft.Create(_aircraft3, NameValue.Of("Airbus 320"), ModelValue.Of("A320"), ManufacturingYearValue.Of(2003))
|
||||||
};
|
};
|
||||||
|
|
||||||
context.Aircraft.AddRange(aircrafts);
|
context.Aircraft.AddRange(aircrafts);
|
||||||
|
|||||||
@ -5,12 +5,13 @@ using BuildingBlocks.Contracts.EventBus.Messages;
|
|||||||
using BuildingBlocks.Core;
|
using BuildingBlocks.Core;
|
||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
|
using Data;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Data;
|
using Passenger.Passengers.Models.ValueObjects;
|
||||||
|
|
||||||
public class RegisterNewUserHandler : IConsumer<UserCreated>
|
public class RegisterNewUserHandler : IConsumer<UserCreated>
|
||||||
{
|
{
|
||||||
@ -44,8 +45,8 @@ public class RegisterNewUserHandler : IConsumer<UserCreated>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var passenger = Passengers.Models.Passenger.Create(NewId.NextGuid(), context.Message.Name,
|
var passenger = Passengers.Models.Passenger.Create(NewId.NextGuid(), NameValue.Of(context.Message.Name),
|
||||||
context.Message.PassportNumber);
|
PassportNumberValue.Of(context.Message.PassportNumber));
|
||||||
|
|
||||||
await _passengerDbContext.AddAsync(passenger);
|
await _passengerDbContext.AddAsync(passenger);
|
||||||
|
|
||||||
|
|||||||
@ -4,18 +4,19 @@ using Ardalis.GuardClauses;
|
|||||||
using BuildingBlocks.Core.CQRS;
|
using BuildingBlocks.Core.CQRS;
|
||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Exceptions;
|
|
||||||
using FluentValidation;
|
|
||||||
using MapsterMapper;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Data;
|
using Data;
|
||||||
using Dtos;
|
using Dtos;
|
||||||
using Duende.IdentityServer.EntityFramework.Entities;
|
using Duende.IdentityServer.EntityFramework.Entities;
|
||||||
|
using Exceptions;
|
||||||
|
using FluentValidation;
|
||||||
|
using MapsterMapper;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Passenger.Passengers.Models.ValueObjects;
|
||||||
|
|
||||||
public record CompleteRegisterPassenger
|
public record CompleteRegisterPassenger
|
||||||
(string PassportNumber, Enums.PassengerType PassengerType, int Age) : ICommand<CompleteRegisterPassengerResult>,
|
(string PassportNumber, Enums.PassengerType PassengerType, int Age) : ICommand<CompleteRegisterPassengerResult>,
|
||||||
@ -104,7 +105,7 @@ internal class CompleteRegisterPassengerCommandHandler : ICommandHandler<Complet
|
|||||||
}
|
}
|
||||||
|
|
||||||
var passengerEntity = passenger.CompleteRegistrationPassenger(passenger.Id, passenger.Name,
|
var passengerEntity = passenger.CompleteRegistrationPassenger(passenger.Id, passenger.Name,
|
||||||
passenger.PassportNumber, request.PassengerType, request.Age);
|
passenger.PassportNumber, request.PassengerType, AgeValue.Of(request.Age));
|
||||||
|
|
||||||
var updatePassenger = _passengerDbContext.Passengers.Update(passengerEntity);
|
var updatePassenger = _passengerDbContext.Passengers.Update(passengerEntity);
|
||||||
|
|
||||||
|
|||||||
@ -3,24 +3,25 @@ using BuildingBlocks.Core.Model;
|
|||||||
namespace Passenger.Passengers.Models;
|
namespace Passenger.Passengers.Models;
|
||||||
|
|
||||||
using Features.CompletingRegisterPassenger.V1;
|
using Features.CompletingRegisterPassenger.V1;
|
||||||
|
using global::Passenger.Passengers.Models.ValueObjects;
|
||||||
using Identity.Consumers.RegisteringNewUser.V1;
|
using Identity.Consumers.RegisteringNewUser.V1;
|
||||||
|
|
||||||
public record Passenger : Aggregate<Guid>
|
public record Passenger : Aggregate<Guid>
|
||||||
{
|
{
|
||||||
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
|
var passenger = new Passenger
|
||||||
{
|
{
|
||||||
|
Id = id,
|
||||||
Name = name,
|
Name = name,
|
||||||
PassportNumber = passportNumber,
|
PassportNumber = passportNumber,
|
||||||
PassengerType = passengerType,
|
PassengerType = passengerType,
|
||||||
Age = age,
|
Age = age,
|
||||||
Id = id,
|
|
||||||
IsDeleted = isDeleted
|
IsDeleted = isDeleted
|
||||||
};
|
};
|
||||||
|
|
||||||
var @event = new PassengerRegistrationCompletedDomainEvent(passenger.Id, passenger.Name, passenger.PassportNumber,
|
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);
|
passenger.AddDomainEvent(@event);
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ public record Passenger : Aggregate<Guid>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 };
|
var passenger = new Passenger { Id = id, Name = name, PassportNumber = passportNumber, IsDeleted = isDeleted };
|
||||||
|
|
||||||
@ -40,8 +41,8 @@ public record Passenger : Aggregate<Guid>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string PassportNumber { get; private set; }
|
public PassportNumberValue PassportNumber { get; private set; }
|
||||||
public string Name { get; private set; }
|
public NameValue Name { get; private set; }
|
||||||
public Enums.PassengerType PassengerType { get; private set; }
|
public Enums.PassengerType PassengerType { get; private set; }
|
||||||
public int Age { get; private set; }
|
public AgeValue Age { get; private set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
namespace Passenger.Passengers.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public record AgeValue : GenericValueObject<int>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
namespace Passenger.Passengers.Models.ValueObjects;
|
||||||
|
public record GenericValueObject<T>(T Value)
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator T(GenericValueObject<T> valueObject)
|
||||||
|
{
|
||||||
|
return valueObject.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
namespace Passenger.Passengers.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public record NameValue : GenericValueObject<string>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
namespace Passenger.Passengers.Models.ValueObjects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
public record PassportNumberValue : GenericValueObject<string>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user