Newer
Older
BloatedHandler / PipelineHandler.cs
@Derek Comartin Derek Comartin 27 days ago 4 KB Non functional example
namespace BloatedHandler.Pipeline;

public class Shipment
{
    public Guid Id { get; private set; }
    public ShipmentStatus Status { get; private set; }
    public DateTime? DispatchedAt { get; private set; }

    public void Dispatch()
    {
        if (Status != ShipmentStatus.Ready)
            throw new InvalidOperationException("Shipment is not ready.");

        Status = ShipmentStatus.Dispatched;
        DispatchedAt = DateTime.UtcNow;
    }
}

public interface IShipmentDispatchStep
{
    void Execute(DispatchShipmentContext context, NextStepDelegate next);
}
public delegate Task NextStepDelegate(DispatchShipmentContext context);

public class ShipmentDispatchPipeline
{
    private readonly List<IShipmentDispatchStep> _steps;

    public ShipmentDispatchPipeline(IEnumerable<IShipmentDispatchStep> steps)
    {
        _steps = steps.ToList();
    }

    public async Task ExecuteAsync(Guid shipmentId)
    {

    }
}


public class DispatchShipmentHandler : ICommandHandler<DispatchShipment>
{
    private readonly ShipmentDispatchPipeline _pipeline;

    public DispatchShipmentHandler(ShipmentDispatchPipeline pipeline)
    {
        _pipeline = pipeline;
    }

    public async Task Handle(DispatchShipment command)
    {
        await _pipeline.ExecuteAsync(command.ShipmentId);
    }
}

public class DispatchShipmentContext
{
    public Guid ShipmentId { get; set; }
    public Shipment Shipment { get; set; }
    public List<object> Events { get; } = new();
}

public class LoadShipmentStep : IShipmentDispatchStep
{
    private readonly DB _db;

    public LoadShipmentStep(DB repository)
    {
        _db = repository;
    }

    public void Execute(DispatchShipmentContext context, NextStepDelegate next)
    {
        var shipment = _db.GetById(context.ShipmentId);
        if (shipment == null)
        {
            throw new InvalidOperationException("Shipment not found.");
        }

        context.Shipment = shipment;
        
        next(context);
        
        _db.Save(context.Shipment);
    }
}

public class DispatchShipmentLogicStep : IShipmentDispatchStep
{
    public void Execute(DispatchShipmentContext context, NextStepDelegate next)
    {
        context.Shipment.Dispatch();
        context.Events.Add(new ShipmentDispatched(context.Shipment.Id, context.Shipment.DispatchedAt!.Value));
        
        next(context);
    }
}

public class PublishEventStep : IShipmentDispatchStep
{
    private readonly IEventPublisher _eventPublisher;

    public PublishEventStep(IEventPublisher eventPublisher)
    {
        _eventPublisher = eventPublisher;
    }

    public void Execute(DispatchShipmentContext context, NextStepDelegate next)
    {
        foreach (var @event in context.Events)
        {
            _eventPublisher.Publish(@event);
        }
        
        next(context);
    }
}

public class ShipmentDispatchedCustomerEmail
{
    private readonly IEmailer _emailer;
    private readonly DB _repository;

    public ShipmentDispatchedCustomerEmail(IEmailer emailer, DB repository)
    {
        _emailer = emailer;
        _repository = repository;
    }

    public void Handle(ShipmentDispatched evnt)
    {
        var shipment = _repository.GetById(evnt.ShipmentId);
        _emailer.NotifyCustomer(shipment);
    }
}





















public class DispatchShipment
{
    public DispatchShipment(Guid shipmentId)
    {
        ShipmentId = shipmentId;
    }

    public Guid ShipmentId { get; set; }
}


public class ShipmentDispatched
{
    public Guid ShipmentId { get; }
    public object DispatchedAt { get; }

    public ShipmentDispatched(Guid shipmentId, object dispatchedAt)
    {
        ShipmentId = shipmentId;
        DispatchedAt = dispatchedAt;
    }
}

public enum ShipmentStatus
{
    Ready,
    Dispatched
}

public interface ILogger
{
    void Log(string s);
}

public interface IEventPublisher
{
    void Publish(object shipmentDispatched);
}

public interface IEmailer
{
    void NotifyCustomer(object shipment);
}

public interface DB
{
    void Save(object shipment);
    Shipment GetById(object shipmentId);
}

public interface ICommandHandler<T>
{
}