Last active
August 29, 2015 14:00
-
-
Save jkonecki/20be888e1d77555dcf0e to your computer and use it in GitHub Desktop.
Orleans event sourced state
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
// Events | |
public class PersonRegistered | |
{ | |
public string FirstName { get; set; } | |
public string LastName { get; set; } | |
public GenderType Gender { get; set; } | |
} | |
public class PersonMarried | |
{ | |
public string LastName { get; set; } | |
} | |
// Event sourced state | |
public interface IAggregateState : IGrainState | |
{ | |
List<object> Events { get; set; } | |
} | |
// Event sourced grain base class | |
public abstract class AggregateGrainBase<S> : GrainBase<S> | |
where S : class, IAggregateState | |
{ | |
public override Task ActivateAsync() | |
{ | |
dynamic self = this; | |
foreach (dynamic @event in this.State.Events) | |
self.Apply(@event); | |
this.State.Events.Clear(); | |
return base.ActivateAsync(); | |
} | |
protected void RaiseEvent(object @event) | |
{ | |
this.State.Events.Add(@event); | |
dynamic self = this; | |
dynamic ev = @event; | |
self.Apply(ev); | |
} | |
} | |
// Implementation | |
public interface IPersonState : IAggregateState | |
{ | |
string FirstName { get; set; } | |
string LastName { get; set; } | |
GenderType Gender { get; set; } | |
} | |
[StorageProvider(ProviderName = "TestStore")] | |
public class Person : AggregateGrainBase<IPersonState>, Test.Interfaces.IPerson | |
{ | |
Task IPerson.Register(PersonalAttributes props) | |
{ | |
this.RaiseEvent(new PersonRegistered | |
{ | |
FirstName = props.FirstName, | |
LastName = props.LastName, | |
Gender = props.Gender | |
}); | |
return State.WriteStateAsync(); | |
} | |
Task IPerson.Marry(string newLastName) | |
{ | |
this.RaiseEvent(new PersonMarried | |
{ | |
LastName = newLastName | |
}); | |
return State.WriteStateAsync(); | |
} | |
Task<string> IPerson.FirstName | |
{ | |
get { return Task.FromResult(State.FirstName); } | |
} | |
Task<string> IPerson.LastName | |
{ | |
get { return Task.FromResult(State.LastName); } | |
} | |
Task<GenderType> IPerson.Gender | |
{ | |
get { return Task.FromResult(State.Gender); } | |
} | |
public void Apply(PersonRegistered @event) | |
{ | |
this.State.FirstName = @event.FirstName; | |
this.State.LastName = @event.LastName; | |
} | |
public void Apply(PersonMarried @event) | |
{ | |
this.State.LastName = @event.LastName; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment