Created
June 28, 2021 19:51
-
-
Save nordfjord/e4bb4ceb325f1459ee44e13b1348da58 to your computer and use it in GitHub Desktop.
Processor in c#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace ProcessorDemo | |
{ | |
public interface IProcessor<Event, Command, State> | |
{ | |
public State InitialState { get; } | |
public State Evolve(State state, Event @event); | |
public IEnumerable<Command> React(State state, Event @event); | |
} | |
public enum PaymentStatus | |
{ | |
None, InProgress, Succeeded, Failed | |
} | |
public interface PaymentEvent | |
{ | |
} | |
public class PaymentRequested: PaymentEvent { | |
public string Id { get; set; } | |
} | |
public class PaymentFailed: PaymentEvent { | |
public string Id { get; set; } | |
} | |
public class PaymentSucceeded: PaymentEvent { | |
public string Id { get; set; } | |
} | |
public interface PaymentCommand | |
{ | |
} | |
public class Pay : PaymentCommand | |
{ | |
public string Id { get; set; } | |
} | |
public class ProcessPayment : PaymentCommand | |
{ | |
public string Id { get; set; } | |
} | |
public class PaymentProcessor : IProcessor<PaymentEvent, PaymentCommand, PaymentStatus> | |
{ | |
public PaymentStatus InitialState { get; } = PaymentStatus.None; | |
public PaymentStatus Evolve(PaymentStatus state, PaymentEvent @event) | |
{ | |
return @event switch | |
{ | |
PaymentRequested => PaymentStatus.InProgress, | |
PaymentSucceeded => PaymentStatus.Succeeded, | |
PaymentFailed => PaymentStatus.Failed, | |
_ => state | |
}; | |
} | |
public IEnumerable<PaymentCommand> React(PaymentStatus state, PaymentEvent @event) | |
{ | |
if (state != PaymentStatus.None) return Enumerable.Empty<PaymentCommand>(); | |
return @event switch | |
{ | |
PaymentRequested e => new[] {new ProcessPayment {Id = e.Id}}, | |
_ => Enumerable.Empty<PaymentCommand>() | |
}; | |
} | |
} | |
public class ListProcessor<Event, Command, State> : IProcessor<Event, Command, Dictionary<string, State>> | |
{ | |
private readonly IProcessor<Event, Command, State> _processor; | |
private readonly Func<Event, string> _getId; | |
public ListProcessor(IProcessor<Event, Command, State> processor, Func<Event, string> getId) | |
{ | |
_processor = processor; | |
_getId = getId; | |
} | |
public Dictionary<string, State> InitialState { get; } = new(); | |
public Dictionary<string, State> Evolve(Dictionary<string, State> state, Event @event) | |
{ | |
var id = _getId(@event); | |
var innerState = state[id] ?? _processor.InitialState; | |
var newState = _processor.Evolve(innerState, @event); | |
state[id] = newState; | |
return state; | |
} | |
public IEnumerable<Command> React(Dictionary<string, State> state, Event @event) | |
{ | |
return _processor.React(state[_getId(@event)] ?? _processor.InitialState, @event); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ProcessorDemo { | |
public class Program { | |
public static void Main(string[] args) | |
{ | |
var processor = new ListProcessor<PaymentEvent, PaymentCommand, PaymentStatus>(new PaymentProcessor(), @event => @event switch | |
{ | |
PaymentRequested e => e.Id, | |
PaymentSucceeded e => e.Id, | |
PaymentFailed e => e.Id, | |
_ => throw new ArgumentOutOfRangeException(nameof(@event), @event, null) | |
}); | |
processor.React(processor.InitialState, new PaymentRequested {Id = "1"}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment