add flight read models

This commit is contained in:
meysamhadeli 2022-07-16 01:27:58 +04:30
parent a6f7bd46d5
commit 47b7493ba0
24 changed files with 249 additions and 39 deletions

View File

@ -56,6 +56,21 @@ authorization: bearer {{Authenticate.response.body.access_token}}
GET {{flight-api}} GET {{flight-api}}
### ###
###
# @name Create_Seat
Post {{api-gateway}}/api/v1/flight/seat
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
{
"seatNumber": "12H9",
"type": 1,
"class": 1,
"flightId": 1
}
###
### ###
# @name Reserve_Seat # @name Reserve_Seat
@ -66,7 +81,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
{ {
"flightId": 1, "flightId": 1,
"seatNumber": "12C" "seatNumber": "12H9"
} }
### ###
@ -181,9 +196,9 @@ Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}} authorization: bearer {{Authenticate.response.body.access_token}}
{ {
"name": "airbus", "name": "airbus2",
"model": "320", "model": "322",
"manufacturingYear": 2010 "manufacturingYear": 2012
} }
### ###

View File

@ -7,3 +7,5 @@ public record FlightUpdated(long Id) : IIntegrationEvent;
public record FlightDeleted(long Id) : IIntegrationEvent; public record FlightDeleted(long Id) : IIntegrationEvent;
public record AircraftCreated(long Id) : IIntegrationEvent; public record AircraftCreated(long Id) : IIntegrationEvent;
public record AirportCreated(long Id) : IIntegrationEvent; public record AirportCreated(long Id) : IIntegrationEvent;
public record SeatCreated(long Id) : IIntegrationEvent;
public record SeatReserved(long Id) : IIntegrationEvent;

View File

@ -1,10 +1,11 @@
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.IdsGenerator; using BuildingBlocks.IdsGenerator;
using Flight.Aircrafts.Dtos; using Flight.Aircrafts.Dtos;
using MediatR; using MediatR;
namespace Flight.Aircrafts.Features.CreateAircraft; namespace Flight.Aircrafts.Features.CreateAircraft;
public record CreateAircraftCommand(string Name, string Model, int ManufacturingYear) : IRequest<AircraftResponseDto>, IInternalCommand public record CreateAircraftCommand(string Name, string Model, int ManufacturingYear) : ICommand<AircraftResponseDto>, IInternalCommand
{ {
public long Id { get; set; } = SnowFlakIdGenerator.NewId(); public long Id { get; set; } = SnowFlakIdGenerator.NewId();
} }

View File

@ -1,10 +1,11 @@
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.IdsGenerator; using BuildingBlocks.IdsGenerator;
using Flight.Airports.Dtos; using Flight.Airports.Dtos;
using MediatR; using MediatR;
namespace Flight.Airports.Features.CreateAirport; namespace Flight.Airports.Features.CreateAirport;
public record CreateAirportCommand(string Name, string Address, string Code) : IRequest<AirportResponseDto>, IInternalCommand public record CreateAirportCommand(string Name, string Address, string Code) : ICommand<AirportResponseDto>, IInternalCommand
{ {
public long Id { get; set; } = SnowFlakIdGenerator.NewId(); public long Id { get; set; } = SnowFlakIdGenerator.NewId();
} }

View File

@ -3,6 +3,7 @@ using Flight.Aircrafts.Models.Reads;
using Flight.Airports.Models; using Flight.Airports.Models;
using Flight.Airports.Models.Reads; using Flight.Airports.Models.Reads;
using Flight.Flights.Models.Reads; using Flight.Flights.Models.Reads;
using Flight.Seats.Models.Reads;
using Humanizer; using Humanizer;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MongoDB.Driver; using MongoDB.Driver;
@ -16,9 +17,11 @@ public class FlightReadDbContext : MongoDbContext
Flight = GetCollection<FlightReadModel>(nameof(Flight).Underscore()); Flight = GetCollection<FlightReadModel>(nameof(Flight).Underscore());
Aircraft = GetCollection<AircraftReadModel>(nameof(Aircraft).Underscore()); Aircraft = GetCollection<AircraftReadModel>(nameof(Aircraft).Underscore());
Airport = GetCollection<AirportReadModel>(nameof(Airport).Underscore()); Airport = GetCollection<AirportReadModel>(nameof(Airport).Underscore());
Seat = GetCollection<SeatReadModel>(nameof(Seat).Underscore());
} }
public IMongoCollection<FlightReadModel> Flight { get; } public IMongoCollection<FlightReadModel> Flight { get; }
public IMongoCollection<AircraftReadModel> Aircraft { get; } public IMongoCollection<AircraftReadModel> Aircraft { get; }
public IMongoCollection<AirportReadModel> Airport { get; } public IMongoCollection<AirportReadModel> Airport { get; }
public IMongoCollection<SeatReadModel> Seat { get; }
} }

View File

@ -9,6 +9,9 @@ using Flight.Flights.Events.Domain;
using Flight.Flights.Features.CreateFlight.Reads; using Flight.Flights.Features.CreateFlight.Reads;
using Flight.Flights.Features.DeleteFlight.Reads; using Flight.Flights.Features.DeleteFlight.Reads;
using Flight.Flights.Features.UpdateFlight.Reads; using Flight.Flights.Features.UpdateFlight.Reads;
using Flight.Seats.Events;
using Flight.Seats.Features.CreateSeat.Reads;
using Flight.Seats.Features.ReserveSeat.Reads;
namespace Flight; namespace Flight;
@ -24,6 +27,8 @@ public sealed class EventMapper : IEventMapper
FlightDeletedDomainEvent e => new FlightDeleted(e.Id), FlightDeletedDomainEvent e => new FlightDeleted(e.Id),
AirportCreatedDomainEvent e => new AirportCreated(e.Id), AirportCreatedDomainEvent e => new AirportCreated(e.Id),
AircraftCreatedDomainEvent e => new AircraftCreated(e.Id), AircraftCreatedDomainEvent e => new AircraftCreated(e.Id),
SeatCreatedDomainEvent e => new SeatCreated(e.Id),
SeatReservedDomainEvent e => new SeatReserved(e.Id),
_ => null _ => null
}; };
} }
@ -40,6 +45,8 @@ public sealed class EventMapper : IEventMapper
e.ArriveDate, e.ArriveAirportId, e.DurationMinutes, e.FlightDate, e.Status, e.Price, e.IsDeleted), e.ArriveDate, e.ArriveAirportId, e.DurationMinutes, e.FlightDate, e.Status, e.Price, e.IsDeleted),
AircraftCreatedDomainEvent e => new CreateAircraftMongoCommand(e.Id, e.Name, e.Model, e.ManufacturingYear, e.IsDeleted), AircraftCreatedDomainEvent e => new CreateAircraftMongoCommand(e.Id, e.Name, e.Model, e.ManufacturingYear, e.IsDeleted),
AirportCreatedDomainEvent e => new CreateAirportMongoCommand(e.Id, e.Name, e.Address, e.Code, e.IsDeleted), AirportCreatedDomainEvent e => new CreateAirportMongoCommand(e.Id, e.Name, e.Address, e.Code, e.IsDeleted),
SeatCreatedDomainEvent e => new CreateSeatMongoCommand(e.Id, e.SeatNumber, e.Type, e.Class, e.FlightId, e.IsDeleted),
SeatReservedDomainEvent e => new ReserveSeatMongoCommand(e.Id, e.SeatNumber, e.Type, e.Class, e.FlightId, e.IsDeleted),
_ => null _ => null
}; };
} }

View File

@ -16,7 +16,6 @@
<Folder Include="Airports\Exceptions" /> <Folder Include="Airports\Exceptions" />
<Folder Include="Data\Migrations" /> <Folder Include="Data\Migrations" />
<Folder Include="Enum" /> <Folder Include="Enum" />
<Folder Include="Seats\Features\CreateSeat" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -8,20 +8,19 @@ using Flight.Data;
using Flight.Flights.Dtos; using Flight.Flights.Dtos;
using Flight.Flights.Exceptions; using Flight.Flights.Exceptions;
using MapsterMapper; using MapsterMapper;
using MediatR; using MongoDB.Driver;
using Microsoft.EntityFrameworkCore;
namespace Flight.Flights.Features.GetAvailableFlights; namespace Flight.Flights.Features.GetAvailableFlights;
public class GetAvailableFlightsQueryHandler : IQueryHandler<GetAvailableFlightsQuery, IEnumerable<FlightResponseDto>> public class GetAvailableFlightsQueryHandler : IQueryHandler<GetAvailableFlightsQuery, IEnumerable<FlightResponseDto>>
{ {
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly FlightReadDbContext _flightReadDbContext;
public GetAvailableFlightsQueryHandler(IMapper mapper, FlightDbContext flightDbContext) public GetAvailableFlightsQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext)
{ {
_mapper = mapper; _mapper = mapper;
_flightDbContext = flightDbContext; _flightReadDbContext = flightReadDbContext;
} }
public async Task<IEnumerable<FlightResponseDto>> Handle(GetAvailableFlightsQuery query, public async Task<IEnumerable<FlightResponseDto>> Handle(GetAvailableFlightsQuery query,
@ -29,7 +28,8 @@ public class GetAvailableFlightsQueryHandler : IQueryHandler<GetAvailableFlights
{ {
Guard.Against.Null(query, nameof(query)); Guard.Against.Null(query, nameof(query));
var flight = await _flightDbContext.Flights.ToListAsync(cancellationToken); var flight = (await _flightReadDbContext.Flight.AsQueryable().ToListAsync(cancellationToken))
.Where(x => !x.IsDeleted);
if (!flight.Any()) if (!flight.Any())
throw new FlightNotFountException(); throw new FlightNotFountException();

View File

@ -10,18 +10,16 @@ using Swashbuckle.AspNetCore.Annotations;
namespace Flight.Flights.Features.GetFlightById; namespace Flight.Flights.Features.GetFlightById;
[Route(BaseApiPath + "/flight")] [Route(BaseApiPath + "/flight")]
public class GetFlightByIdEndpoint: BaseController public class GetFlightByIdEndpoint : BaseController
{ {
// [Authorize] [Authorize]
[HttpGet("{id}")] [HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[SwaggerOperation(Summary = "Get flight by id", Description = "Get flight by id")] [SwaggerOperation(Summary = "Get flight by id", Description = "Get flight by id")]
public async Task<ActionResult> GetById([FromRoute] GetFlightByIdQuery query, CancellationToken cancellationToken) public async Task<ActionResult> GetById([FromRoute] GetFlightByIdQuery query, CancellationToken cancellationToken)
{ {
throw new Exception();
var result = await Mediator.Send(query, cancellationToken); var result = await Mediator.Send(query, cancellationToken);
return Ok(result); return Ok(result);
} }
} }

View File

@ -6,20 +6,20 @@ using Flight.Data;
using Flight.Flights.Dtos; using Flight.Flights.Dtos;
using Flight.Flights.Exceptions; using Flight.Flights.Exceptions;
using MapsterMapper; using MapsterMapper;
using MediatR; using MongoDB.Driver;
using Microsoft.EntityFrameworkCore; using MongoDB.Driver.Linq;
namespace Flight.Flights.Features.GetFlightById; namespace Flight.Flights.Features.GetFlightById;
public class GetFlightByIdQueryHandler : IQueryHandler<GetFlightByIdQuery, FlightResponseDto> public class GetFlightByIdQueryHandler : IQueryHandler<GetFlightByIdQuery, FlightResponseDto>
{ {
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly FlightReadDbContext _flightReadDbContext;
public GetFlightByIdQueryHandler(IMapper mapper, FlightDbContext flightDbContext) public GetFlightByIdQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext)
{ {
_mapper = mapper; _mapper = mapper;
_flightDbContext = flightDbContext; _flightReadDbContext = flightReadDbContext;
} }
public async Task<FlightResponseDto> Handle(GetFlightByIdQuery query, CancellationToken cancellationToken) public async Task<FlightResponseDto> Handle(GetFlightByIdQuery query, CancellationToken cancellationToken)
@ -27,7 +27,7 @@ public class GetFlightByIdQueryHandler : IQueryHandler<GetFlightByIdQuery, Fligh
Guard.Against.Null(query, nameof(query)); Guard.Against.Null(query, nameof(query));
var flight = var flight =
await _flightDbContext.Flights.SingleOrDefaultAsync(x => x.Id == query.Id, cancellationToken); await _flightReadDbContext.Flight.AsQueryable().SingleOrDefaultAsync(x => x.Id == query.Id, cancellationToken);
if (flight is null) if (flight is null)
throw new FlightNotFountException(); throw new FlightNotFountException();

View File

@ -3,4 +3,4 @@ using Flight.Seats.Models;
namespace Flight.Seats.Events; namespace Flight.Seats.Events;
public record SeatCreatedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : IDomainEvent; public record SeatCreatedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId, bool IsDeleted) : IDomainEvent;

View File

@ -0,0 +1,6 @@
using BuildingBlocks.Core.Event;
using Flight.Seats.Models;
namespace Flight.Seats.Events;
public record SeatReservedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId, bool IsDeleted) : IDomainEvent;

View File

@ -1,11 +1,11 @@
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.IdsGenerator; using BuildingBlocks.IdsGenerator;
using Flight.Seats.Dtos; using Flight.Seats.Dtos;
using Flight.Seats.Models; using Flight.Seats.Models;
using MediatR;
namespace Flight.Seats.Features.CreateSeat; namespace Flight.Seats.Features.CreateSeat;
public record CreateSeatCommand(string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : IRequest<SeatResponseDto> public record CreateSeatCommand(string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : ICommand<SeatResponseDto>, IInternalCommand
{ {
public long Id { get; set; } = SnowFlakIdGenerator.NewId(); public long Id { get; set; } = SnowFlakIdGenerator.NewId();
} }

View File

@ -40,8 +40,6 @@ public class CreateSeatCommandHandler : IRequestHandler<CreateSeatCommand, SeatR
var newSeat = await _flightDbContext.Seats.AddAsync(seatEntity, cancellationToken); var newSeat = await _flightDbContext.Seats.AddAsync(seatEntity, cancellationToken);
await _flightDbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<SeatResponseDto>(newSeat.Entity); return _mapper.Map<SeatResponseDto>(newSeat.Entity);
} }
} }

View File

@ -0,0 +1,25 @@
using BuildingBlocks.Core.Event;
using Flight.Seats.Models;
namespace Flight.Seats.Features.CreateSeat.Reads;
public class CreateSeatMongoCommand : InternalCommand
{
public CreateSeatMongoCommand(long id, string seatNumber, SeatType type, SeatClass @class,
long flightId, bool isDeleted)
{
Id = id;
SeatNumber = seatNumber;
Type = type;
Class = @class;
FlightId = flightId;
IsDeleted = isDeleted;
}
public long Id { get; }
public string SeatNumber { get; }
public SeatType Type { get; }
public SeatClass Class { get; }
public long FlightId { get; }
public bool IsDeleted { get; }
}

View File

@ -0,0 +1,44 @@
using System.Threading;
using System.Threading.Tasks;
using Ardalis.GuardClauses;
using BuildingBlocks.Core.CQRS;
using Flight.Data;
using Flight.Seats.Exceptions;
using Flight.Seats.Models.Reads;
using MapsterMapper;
using MediatR;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
namespace Flight.Seats.Features.CreateSeat.Reads;
public class CreateSeatMongoCommandHandler : ICommandHandler<CreateSeatMongoCommand>
{
private readonly FlightReadDbContext _flightReadDbContext;
private readonly IMapper _mapper;
public CreateSeatMongoCommandHandler(
FlightReadDbContext flightReadDbContext,
IMapper mapper)
{
_flightReadDbContext = flightReadDbContext;
_mapper = mapper;
}
public async Task<Unit> Handle(CreateSeatMongoCommand command, CancellationToken cancellationToken)
{
Guard.Against.Null(command, nameof(command));
var seatReadModel = _mapper.Map<SeatReadModel>(command);
var seat = await _flightReadDbContext.Seat.AsQueryable()
.FirstOrDefaultAsync(x => x.Id == seatReadModel.Id, cancellationToken);
if (seat is not null)
throw new SeatAlreadyExistException();
await _flightReadDbContext.Seat.InsertOneAsync(seatReadModel, cancellationToken: cancellationToken);
return Unit.Value;
}
}

View File

@ -1,7 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using BuildingBlocks.Core.CQRS;
using Flight.Seats.Dtos; using Flight.Seats.Dtos;
using MediatR; using MediatR;
namespace Flight.Seats.Features.GetAvailableSeats; namespace Flight.Seats.Features.GetAvailableSeats;
public record GetAvailableSeatsQuery(long FlightId) : IRequest<IEnumerable<SeatResponseDto>>; public record GetAvailableSeatsQuery(long FlightId) : IQuery<IEnumerable<SeatResponseDto>>;

View File

@ -8,19 +8,19 @@ using Flight.Seats.Dtos;
using Flight.Seats.Exceptions; using Flight.Seats.Exceptions;
using MapsterMapper; using MapsterMapper;
using MediatR; using MediatR;
using Microsoft.EntityFrameworkCore; using MongoDB.Driver;
namespace Flight.Seats.Features.GetAvailableSeats; namespace Flight.Seats.Features.GetAvailableSeats;
public class GetAvailableSeatsQueryHandler : IRequestHandler<GetAvailableSeatsQuery, IEnumerable<SeatResponseDto>> public class GetAvailableSeatsQueryHandler : IRequestHandler<GetAvailableSeatsQuery, IEnumerable<SeatResponseDto>>
{ {
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly FlightReadDbContext _flightReadDbContext;
public GetAvailableSeatsQueryHandler(IMapper mapper, FlightDbContext flightDbContext) public GetAvailableSeatsQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext)
{ {
_mapper = mapper; _mapper = mapper;
_flightDbContext = flightDbContext; _flightReadDbContext = flightReadDbContext;
} }
@ -28,7 +28,8 @@ public class GetAvailableSeatsQueryHandler : IRequestHandler<GetAvailableSeatsQu
{ {
Guard.Against.Null(query, nameof(query)); Guard.Against.Null(query, nameof(query));
var seats = await _flightDbContext.Seats.Where(x => x.FlightId == query.FlightId).ToListAsync(cancellationToken); var seats = (await _flightReadDbContext.Seat.AsQueryable().ToListAsync(cancellationToken))
.Where(x => !x.IsDeleted);
if (!seats.Any()) if (!seats.Any())
throw new AllSeatsFullException(); throw new AllSeatsFullException();

View File

@ -0,0 +1,25 @@
using BuildingBlocks.Core.Event;
using Flight.Seats.Models;
namespace Flight.Seats.Features.ReserveSeat.Reads;
public class ReserveSeatMongoCommand : InternalCommand
{
public ReserveSeatMongoCommand(long id, string seatNumber, SeatType type, SeatClass @class, long flightId,
bool isDeleted)
{
Id = id;
SeatNumber = seatNumber;
Type = type;
Class = @class;
FlightId = flightId;
IsDeleted = isDeleted;
}
public long Id { get; }
public string SeatNumber { get; }
public SeatType Type { get; }
public SeatClass Class { get; }
public long FlightId { get; }
public bool IsDeleted { get; }
}

View File

@ -0,0 +1,40 @@
using System.Threading;
using System.Threading.Tasks;
using Ardalis.GuardClauses;
using BuildingBlocks.Core.CQRS;
using Flight.Data;
using Flight.Seats.Models.Reads;
using MapsterMapper;
using MediatR;
using MongoDB.Driver;
namespace Flight.Seats.Features.ReserveSeat.Reads;
public class ReserveSeatMongoCommandHandler : ICommandHandler<ReserveSeatMongoCommand>
{
private readonly FlightReadDbContext _flightReadDbContext;
private readonly IMapper _mapper;
public ReserveSeatMongoCommandHandler(
FlightReadDbContext flightReadDbContext,
IMapper mapper)
{
_flightReadDbContext = flightReadDbContext;
_mapper = mapper;
}
public async Task<Unit> Handle(ReserveSeatMongoCommand command, CancellationToken cancellationToken)
{
Guard.Against.Null(command, nameof(command));
var seatReadModel = _mapper.Map<SeatReadModel>(command);
await _flightReadDbContext.Seat.UpdateOneAsync(
x => x.SeatId == seatReadModel.SeatId,
Builders<SeatReadModel>.Update
.Set(x => x.IsDeleted, seatReadModel.IsDeleted),
cancellationToken: cancellationToken);
return Unit.Value;
}
}

View File

@ -1,6 +1,6 @@
using BuildingBlocks.Core.CQRS;
using Flight.Seats.Dtos; using Flight.Seats.Dtos;
using MediatR;
namespace Flight.Seats.Features.ReserveSeat; namespace Flight.Seats.Features.ReserveSeat;
public record ReserveSeatCommand(long FlightId, string SeatNumber) : IRequest<SeatResponseDto>; public record ReserveSeatCommand(long FlightId, string SeatNumber) : ICommand<SeatResponseDto>, IInternalCommand;

View File

@ -1,5 +1,9 @@
using BuildingBlocks.IdsGenerator;
using Flight.Seats.Dtos; using Flight.Seats.Dtos;
using Flight.Seats.Features.CreateSeat.Reads;
using Flight.Seats.Features.ReserveSeat.Reads;
using Flight.Seats.Models; using Flight.Seats.Models;
using Flight.Seats.Models.Reads;
using Mapster; using Mapster;
namespace Flight.Seats.Features; namespace Flight.Seats.Features;
@ -9,6 +13,10 @@ public class SeatMappings : IRegister
public void Register(TypeAdapterConfig config) public void Register(TypeAdapterConfig config)
{ {
config.NewConfig<Seat, SeatResponseDto>(); config.NewConfig<Seat, SeatResponseDto>();
config.NewConfig<CreateSeatMongoCommand, SeatReadModel>()
.Map(d => d.Id, s => SnowFlakIdGenerator.NewId())
.Map(d => d.SeatId, s => s.Id);
config.NewConfig<ReserveSeatMongoCommand, SeatReadModel>()
.Map(d => d.SeatId, s => s.Id);
} }
} }

View File

@ -0,0 +1,12 @@
namespace Flight.Seats.Models.Reads;
public class SeatReadModel
{
public long Id { get; init; }
public long SeatId { get; init; }
public string SeatNumber { get; init; }
public SeatType Type { get; init; }
public SeatClass Class { get; init; }
public long FlightId { get; init; }
public bool IsDeleted { get; init; }
}

View File

@ -1,12 +1,14 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using BuildingBlocks.Core.Model; using BuildingBlocks.Core.Model;
using Flight.Seats.Events;
namespace Flight.Seats.Models; namespace Flight.Seats.Models;
public class Seat : Aggregate<long> public class Seat : Aggregate<long>
{ {
public static Seat Create(long id, string seatNumber, SeatType type, SeatClass @class, long flightId) public static Seat Create(long id, string seatNumber, SeatType type, SeatClass @class, long flightId,
bool isDeleted = false)
{ {
var seat = new Seat() var seat = new Seat()
{ {
@ -14,9 +16,20 @@ public class Seat : Aggregate<long>
Class = @class, Class = @class,
Type = type, Type = type,
SeatNumber = seatNumber, SeatNumber = seatNumber,
FlightId = flightId FlightId = flightId,
IsDeleted = isDeleted
}; };
var @event = new SeatCreatedDomainEvent(
seat.Id,
seat.SeatNumber,
seat.Type,
seat.Class,
seat.FlightId,
isDeleted);
seat.AddDomainEvent(@event);
return seat; return seat;
} }
@ -24,6 +37,17 @@ public class Seat : Aggregate<long>
{ {
seat.IsDeleted = true; seat.IsDeleted = true;
seat.LastModified = DateTime.Now; seat.LastModified = DateTime.Now;
var @event = new SeatReservedDomainEvent(
seat.Id,
seat.SeatNumber,
seat.Type,
seat.Class,
seat.FlightId,
seat.IsDeleted);
seat.AddDomainEvent(@event);
return Task.FromResult(this); return Task.FromResult(this);
} }