Exemplo n.º 1
0
        private static Dictionary <Type, EventTypeApplyDelegates> CreateAggregateEventDelegates()
        {
            var delegates = new Dictionary <Type, EventTypeApplyDelegates>();

            var componentTypes = typeExplorer.GetAllTypes()
                                 .Where(x => typeof(IComponent).IsAssignableFrom(x) &&
                                        !x.IsAbstract && !x.IsGenericTypeDefinition);

            foreach (Type aggregateType in componentTypes)
            {
                EventTypeApplyDelegates aggApplyDelegates = new EventTypeApplyDelegates();
                delegates.Add(aggregateType, aggApplyDelegates);
                AddTypeDelegates(aggregateType, aggApplyDelegates);
            }

            return(delegates);
        }
Exemplo n.º 2
0
        private static void AddTypeDelegates(Type componentType, EventTypeApplyDelegates applyDelegates)
        {
            if (componentType.BaseType != null &&
                typeof(IComponent).IsAssignableFrom(componentType.BaseType))
            {
                AddTypeDelegates(componentType.BaseType, applyDelegates);
            }

            var applyMethods = componentType
                               .GetMethods(BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic)
                               .Where(x => x.Name == "Apply" &&
                                      x.GetParameters().Length == 1 &&
                                      typeof(DomainAggregateEvent).IsAssignableFrom(x.GetParameters()[0].ParameterType));

            foreach (MethodInfo applyMethod in applyMethods)
            {
                Type eventType = applyMethod.GetParameters()[0].ParameterType;

                // Create an Action<AggregateRoot, IEvent> that does (agg, evt) => ((ConcreteAggregate)agg).Apply((ConcreteEvent)evt)
                var evtParam = Expression.Parameter(typeof(DomainAggregateEvent), "evt");
                var aggParam = Expression.Parameter(typeof(IComponent), "agg");

                var eventDelegate = Expression.Lambda(
                    Expression.Call(
                        Expression.Convert(
                            aggParam,
                            componentType),
                        applyMethod,
                        Expression.Convert(
                            evtParam,
                            eventType)),
                    aggParam,
                    evtParam).Compile();

                applyDelegates[eventType] = (Action <IComponent, DomainAggregateEvent>)eventDelegate;
            }
        }