Created
November 25, 2012 02:18
-
-
Save AlexeyRaga/4142133 to your computer and use it in GitHub Desktop.
Projection prototype
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
//There is also a set of (extension) methods | |
//such as Add, Update, etc. | |
//all these methods use AddOrUpdate inside. | |
public interface IDocumentWriter<in TKey, TDocument> | |
{ | |
//The idea of AddOrUpdate is borrowed from ConcurrentDictionary: | |
//AddOrUpdate(TKey key, Func<TKey, TView> createNewToAdd, Func<TView, TView> updateExisting); | |
TDocument AddOrUpdate(TKey key, Func<TDocument> addFactory, Func<TDocument, TDocument> updateFactory); | |
bool TryDelete(TKey key); | |
bool Exists(TKey key); | |
} |
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
//The idea of a projection is to accumulate and maintain some persisted state | |
//based on events | |
public sealed class RegistrationStatusProjection | |
{ | |
//just a writer who knows how to persist a projection | |
//The first type parameter is a key, the second is the PVM type. | |
//Look at IDocumentWriter interface in this gist | |
private IDocumentWriter<Guid, RegistrationStatusView> _writer; | |
public RegistrationStatusProjection(IDocumentStore factory) | |
{ | |
//create a writer. | |
//in my case it is a file system writer that will create a file like: | |
//{Guid}-RegistrationStatusView.pvm | |
//where the content is just a RegistrationStatusView serialized into JSON. | |
//Obviously it can be anything: MongoDB persister, SQL 1NF, RavenDB, SOLR, OLAP, etc. | |
_writer = factory.GetWriter<Guid, RegistrationStatusView>(); | |
} | |
//In my case I use a simple "When(IEvent)" convention which allows me to keep | |
//my projections clean and simple. | |
//Another way could be to implement a bunch of IHandle<TEvent> interfaces, | |
//but I really prefer conventions when possible. | |
public void When(RegistrationStarted evt) | |
{ | |
//my writer interface has a set of (extension) methods | |
//such as Add, Update, etc. | |
_writer.Add(evt.RegistrationId, new RegistrationStatusView | |
{ | |
Status = RegistrationProcessStatus.InProgress, | |
Login = evt.Security.Login, | |
DisplayName = evt.Profile.DisplayName, | |
Email = evt.Security.Email, | |
Errors = new List<string>() | |
}); | |
} | |
public void When(RegistrationFailed evt) | |
{ | |
//here I am updating the existing registration projection | |
//AddOrUpdate will load one for me and put it as a "view" parameter | |
//into my anonymous function. | |
//There I just change some properties and the view will be saved back. | |
_writer.AddOrUpdate(evt.RegistrationId, view => | |
{ | |
view.Status = RegistrationProcessStatus.Failed; | |
view.Errors = evt.Errors.ToList(); | |
}); | |
} | |
public void When(RegistrationCompleted evt) | |
{ | |
_writer.AddOrUpdate(evt.RegistrationId, view => | |
{ | |
view.Errors = new List<string>(); | |
view.Status = RegistrationProcessStatus.Successful; | |
}); | |
} |
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
//Damn simple PVM | |
[Serializable] | |
public sealed class RegistrationStatusView | |
{ | |
public string Login { get; set; } | |
public string Email { get; set; } | |
public string DisplayName { get; set; } | |
public List<string> Errors { get; set; } | |
public RegistrationProcessStatus Status { get; set; } | |
} | |
public enum RegistrationProcessStatus | |
{ | |
InProgress = 0, | |
Successful = 1, | |
Failed = 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment