Add Value Objects

This commit is contained in:
amir.gholami 2023-05-21 19:29:06 +03:30
parent 0d8f52b573
commit 5c5be8eef8
15 changed files with 174 additions and 33 deletions

View File

@ -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<CreateAircraftResult>,
IInternalCommand
@ -96,7 +97,7 @@ internal class CreateAircraftHandler : IRequestHandler<CreateAircraft, CreateAir
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;

View File

@ -4,14 +4,15 @@ namespace Flight.Aircrafts.Models;
using System;
using Features.CreatingAircraft.V1;
using ValueObjects;
public record Aircraft : Aggregate<Guid>
{
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
{

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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<Airport> Airports { get;}
public static List<Aircraft> Aircrafts { get;}
public static List<Seat> Seats { get;}
public static List<Airport> Airports { get; }
public static List<Aircraft> Aircrafts { get; }
public static List<Seat> Seats { get; }
public static List<Flight> Flights { get; }
@ -27,9 +28,9 @@ public static class InitialData
Aircrafts = new List<Aircraft>
{
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))
};

View 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;
}
}

View File

@ -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>
{
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);

View File

@ -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<UserCreated>
{
@ -44,8 +45,8 @@ public class RegisterNewUserHandler : IConsumer<UserCreated>
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);

View File

@ -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<CompleteRegisterPassengerResult>,
@ -104,7 +105,7 @@ internal class CompleteRegisterPassengerCommandHandler : ICommandHandler<Complet
}
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);

View File

@ -3,24 +3,25 @@ using BuildingBlocks.Core.Model;
namespace Passenger.Passengers.Models;
using Features.CompletingRegisterPassenger.V1;
using global::Passenger.Passengers.Models.ValueObjects;
using Identity.Consumers.RegisteringNewUser.V1;
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
{
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<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 };
@ -40,8 +41,8 @@ public record Passenger : Aggregate<Guid>
}
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; }
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}