private static StatefulApplyMethods CreateApplyMethods(Type type) { var allMethods = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance); var methodsCalledApply = allMethods.Where(m => m.Name == ApplyMethodsName); var voidMethods = methodsCalledApply.Where(m => m.ReturnType == typeof(void)); var methodsAndParameters = voidMethods.Select(m => new { Method = m, Parameters = m.GetParameters() }); var withOneInputParameter = methodsAndParameters.Where(m => m.Parameters.Length == 1 && !m.Parameters[0].IsOut); var methodAndEventType = withOneInputParameter.Select(m => new { m.Method, Type = m.Parameters[0].ParameterType }); var applyMethods = methodAndEventType.Where(m => m.Type.IsInterface && EventType.IsAssignableFrom(m.Type) && m.Type.Assembly != EventType.Assembly).ToArray(); // Verify no two methods could receive the same event type at the same time var conflicting = (from m1 in applyMethods from m2 in applyMethods where m1 != m2 && (m1.Type.IsAssignableFrom(m2.Type)) select new { OlderVersionType = m1.Type, NewerVersionType = m2.Type }).ToArray(); if (conflicting.Any()) { throw new InvalidOperationException(string.Format("Aggregate {0} contains conflicting apply methods for different versions of the same event: {1}", type.FullName, string.Join(", ", conflicting.Select(c => string.Format("{0} --> {1}", c.NewerVersionType.FullName, c.OlderVersionType.FullName))))); } var actionDictionary = applyMethods .ToDictionary(m => m.Type, m => CreateActionFromMethod(type, m.Type, m.Method)); var result = new StatefulApplyMethods(actionDictionary); return(result); }
protected StatefulAggregate() { _applyMethods = GetApplyMethods(this.GetType()); }