public static void Invoke(Object obj, DomainEvent domainEvent)
        {
            if (!invokerCache.ContainsKey(obj.GetType()))
            {
                var typeCache = new Dictionary<Type, MethodInvoker>();

                var applyMethods = obj.GetType().GetMethods(
                    BindingFlags.NonPublic |
                    BindingFlags.Instance);

                foreach (var item in applyMethods
                    .Where(am => am.Name.Equals("apply", StringComparison.OrdinalIgnoreCase))
                    .Select(am => new { parameters = am.GetParameters(), minfo = am })
                    .Where(p => p.parameters.Length == 1 &&
                        typeof(DomainEvent).IsAssignableFrom(p.parameters[0].ParameterType)))
                {
                    var localItem = item;
                    typeCache[localItem.parameters[0].ParameterType] = item.minfo.DelegateForCallMethod();
                }
                invokerCache[obj.GetType()] = typeCache;

            }
            var thisTypeCache = invokerCache[obj.GetType()];
            MethodInvoker invoker;
            if (thisTypeCache.TryGetValue(domainEvent.GetType(), out invoker))
            {
                invoker.Invoke(obj, domainEvent);
            }
        }