namespace BloatedHandler.Bloated; public class DispatchShipmentHandler : ICommandHandler<DispatchShipment> { private readonly Db _db; private readonly IEmailer _emailer; private readonly IEventPublisher _eventPublisher; private readonly ILogger _logger; public DispatchShipmentHandler(Db db, IEmailer emailer, IEventPublisher eventPublisher, ILogger logger) { _db = db; _emailer = emailer; _eventPublisher = eventPublisher; _logger = logger; } public void Handle(DispatchShipment command) { var shipment = _db.GetById(command.ShipmentId); if (shipment == null) { throw new InvalidOperationException("Shipment not found."); } if (shipment.Status != ShipmentStatus.Ready) { throw new InvalidOperationException("Shipment is not ready for dispatch."); } shipment.Status = ShipmentStatus.Dispatched; shipment.DispatchedAt = DateTime.UtcNow; _db.Save(shipment); _emailer.NotifyCustomer(shipment); _eventPublisher.Publish(new ShipmentDispatched(shipment.Id, shipment.DispatchedAt)); _logger.Log($"Shipment {shipment.Id} dispatched."); } } public class DispatchShipment { public DispatchShipment(object shipmentId) { ShipmentId = shipmentId; } public object ShipmentId { get; set; } } public class Shipment { public Shipment(DateTime dispatchedAt, Guid id) { DispatchedAt = dispatchedAt; Id = id; } public ShipmentStatus Status { get; set; } public DateTime DispatchedAt { get; set; } public Guid Id { get; set; } } public class ShipmentDispatched { public ShipmentDispatched(Guid id, object dispatchedAt) { throw new NotImplementedException(); } } public enum ShipmentStatus { Ready, Dispatched } public interface ILogger { void Log(string s); } public interface IEventPublisher { void Publish(ShipmentDispatched shipmentDispatched); } public interface IEmailer { void NotifyCustomer(object shipment); } public interface Db { void Save(object shipment); Shipment GetById(object shipmentId); } public interface ICommandHandler<T> { }