Skip to content

Instantly share code, notes, and snippets.

@jarroda
Last active June 24, 2016 19:06
Show Gist options
  • Select an option

  • Save jarroda/822358918af62d3f61dd04f6769ad84d to your computer and use it in GitHub Desktop.

Select an option

Save jarroda/822358918af62d3f61dd04f6769ad84d to your computer and use it in GitHub Desktop.
Example of a projection based on aggregate relation
public class MartenProjectionEx<T> : IProjection where T : class, new()
{
private readonly IAggregationFinder<T> _finder;
private readonly IAggregator<T> _aggregator;
private readonly Dictionary<Type, Func<object, Guid>> _relatedEvents = new Dictionary<Type, Func<object, Guid>>();
private readonly ProjectionOptions _options;
public MartenProjectionEx(IAggregationFinder<T> finder, IAggregator<T> aggregator, ProjectionOptions options)
{
_finder = finder;
_aggregator = aggregator;
_options = options;
}
public void Apply(IDocumentSession session, EventStream[] streams)
{
foreach(var stream in streams.Where(_aggregator.AppliesTo))
{
var related = stream.Events
.Select(e => e.Data)
.FirstOrDefault(e => _options._relatedEvents.ContainsKey(e.GetType()));
T state;
if (related != null)
{
var id = _options._relatedEvents[related.GetType()](related);
state = session.Load<T>(id);
}
else
{
state = _finder.Find(stream, session);
}
update(state, stream);
session.Store(state);
};
}
public Task ApplyAsync(IDocumentSession session, EventStream[] streams, CancellationToken token)
{
throw new NotImplementedException();
}
private void update(T state, EventStream stream)
{
foreach (var e in stream.Events)
{
e.Apply(state, _aggregator);
}
}
}
/// <summary>
/// ProjectionOptions supplies the configuration necessary
/// for building a projection
/// </summary>
public class ProjectionOptions
{
internal readonly Dictionary<Type, Func<object, Guid>> _relatedEvents = new Dictionary<Type, Func<object, Guid>>();
public void ConfigureRelation<TEvent>(Expression<Func<TEvent, Guid>> expression)
{
var eventParam = Expression.Parameter(typeof(object), "evnt");
var idParam = Expression.Parameter(typeof(Guid), "id");
var convert = Expression.Convert(eventParam, typeof(TEvent));
var invoke = Expression.Invoke(expression, convert);
var func = Expression.Lambda<Func<object, Guid>>(invoke, eventParam).Compile();
_relatedEvents[typeof(TEvent)] = func;
}
public void ConfigureRelation<TEvent, TAggregate>(Expression<Func<TAggregate, Guid>> expression)
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment