Exemple #1
0
        /// <summary>
        /// Discover all event handlers associated with any locatable class marked with <see cref="EventHandlerAttribute"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known classes marked with <see cref="EventHandlerAttribute"/>.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        private static Dictionary <Type, EventHandler[]> DiscoverEventHandlers(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy <IPublishCommands> commandPublisher)
        {
            var knownEvents   = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Event)));
            var knownHandlers = DiscoverHandleMethods(typeLocator, serviceProvider, sagaStore, commandPublisher);
            var result        = new Dictionary <Type, EventHandler[]>();
            var logMessage    = new StringBuilder();

            logMessage.AppendLine("Discovered event handlers:");
            foreach (var eventType in knownEvents.OrderBy(type => type.FullName))
            {
                var eventHandlers = eventType.GetTypeHierarchy().Reverse()
                                    .Where(knownHandlers.ContainsKey)
                                    .SelectMany(type => knownHandlers[type])
                                    .OrderBy(handler => handler is SagaEventHandler)
                                    .ThenBy(handler => handler.HandlerType.AssemblyQualifiedName)
                                    .ToArray();

                logMessage.Append("    ");
                logMessage.Append(eventType);
                logMessage.AppendLine();

                foreach (var eventHandler in eventHandlers)
                {
                    logMessage.Append("        ");
                    logMessage.Append(eventHandler.HandlerType);
                    logMessage.AppendLine();
                }

                result.Add(eventType, eventHandlers);
            }

            Log.Debug(logMessage.ToString);

            return(result);
        }
        /// <summary>
        /// Initializes a new instance of <see cref="CommandHandlerRegistry"/> with the specified <paramref name="typeLocator"/> and <paramref name="serviceProvider"/>.
        /// </summary>
        /// <param name="aggregateStore">The <see cref="Aggregate"/> store.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        public CommandHandlerRegistry(IStoreAggregates aggregateStore, ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serviceProvider, nameof(serviceProvider));

            knownCommandHandlers = DiscoverCommandHandlers(aggregateStore, typeLocator, serviceProvider);
        }
        /// <summary>
        /// Discover all command handlers associated with any locatable <see cref="Aggregate"/> type.
        /// </summary>
        /// <param name="aggregateStore">The <see cref="Aggregate"/> store.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        private static Dictionary<Type, CommandHandler> DiscoverCommandHandlers(IStoreAggregates aggregateStore, ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            var knownHandleMethods = DiscoverHandleMethods(typeLocator, serviceProvider);
            var result = new Dictionary<Type, CommandHandler>();
            var logMessage = new StringBuilder();

            logMessage.AppendLine("Discovered command handlers:");
            foreach (var aggregateMapping in knownHandleMethods.OrderBy(kvp => kvp.Key.FullName))
            {
                logMessage.Append("    ");
                logMessage.Append(aggregateMapping.Key);
                logMessage.AppendLine();

                foreach (var handleMethodMapping in aggregateMapping.Value.OrderBy(kvp => kvp.Key.FullName))
                {
                    logMessage.Append("        ");
                    logMessage.Append(handleMethodMapping.Key);
                    logMessage.AppendLine();

                    if (result.ContainsKey(handleMethodMapping.Key))
                        throw new MappingException(Exceptions.HandleMethodMustBeAssociatedWithSingleAggregate.FormatWith(aggregateMapping.Key, handleMethodMapping.Key));

                    result.Add(handleMethodMapping.Key, new CommandHandler(aggregateMapping.Key, handleMethodMapping.Key, aggregateStore, handleMethodMapping.Value));
                }
            }

            Log.Debug(logMessage.ToString);

            return result;
        }
Exemple #4
0
        /// <summary>
        /// Initializes a new instance of <see cref="CommandHandlerRegistry"/> with the specified <paramref name="typeLocator"/> and <paramref name="serviceProvider"/>.
        /// </summary>
        /// <param name="aggregateStore">The <see cref="Aggregate"/> store.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        public CommandHandlerRegistry(IStoreAggregates aggregateStore, ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serviceProvider, nameof(serviceProvider));

            knownCommandHandlers = DiscoverCommandHandlers(aggregateStore, typeLocator, serviceProvider);
        }
Exemple #5
0
        /// <summary>
        /// Discover all event handlers methods associated with any locatable class marked with with <see cref="EventHandlerAttribute"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known classes marked with <see cref="EventHandlerAttribute"/>.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        private static Dictionary <Type, List <EventHandler> > DiscoverHandleMethods(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy <IPublishCommands> commandPublisher)
        {
            var handlerTypes       = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.GetCustomAttribute <EventHandlerAttribute>() != null);
            var knownEventHandlers = new Dictionary <Type, List <EventHandler> >();

            foreach (var handlerType in handlerTypes)
            {
                var handleMethods = GetHandleMethods(handlerType, serviceProvider);
                var sagaMetadata  = typeof(Saga).IsAssignableFrom(handlerType) ? GetSagaMetadata(handlerType, handleMethods) : null;

                foreach (var handleMethod in handleMethods)
                {
                    List <EventHandler> eventHandlers;
                    Type eventType = handleMethod.Key;
                    if (!knownEventHandlers.TryGetValue(eventType, out eventHandlers))
                    {
                        knownEventHandlers.Add(eventType, eventHandlers = new List <EventHandler>());
                    }

                    var eventHandler = new EventHandler(handlerType, eventType, handleMethod.Value, GetHandlerFactory(handlerType, serviceProvider));
                    if (sagaMetadata != null)
                    {
                        eventHandler = eventType == typeof(Timeout) ? new SagaTimeoutHandler(eventHandler, sagaMetadata, sagaStore, commandPublisher) : new SagaEventHandler(eventHandler, sagaMetadata, sagaStore, commandPublisher);
                    }

                    eventHandlers.Add(eventHandler);
                }
            }

            return(knownEventHandlers);
        }
 public IStream CatchUp(string streamName, ILocateTypes typeLocator)
 {
     return new CatchUpStream(
         _logger,
         _eventStore,
         typeLocator,
         streamName
     );
 }
        /// <summary>
        /// Discover all known <see cref="Aggregate"/> implementations known to the specified <paramref name="typeLocator"/>.
        /// </summary>
        /// <param name="typeLocator">The type locator used to retrieve all <see cref="Aggregate"/> type information.</param>
        private static IDictionary<Type, ApplyMethodCollection> DiscoverAggregates(ILocateTypes typeLocator)
        {
            var aggregateTypes = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Aggregate)));
            var result = new Dictionary<Type, ApplyMethodCollection>();

            foreach (var aggregateType in aggregateTypes)
                result.Add(aggregateType, DiscoverApplyMethods(aggregateType));

            return result;
        }
 public IStream Persistent(string streamName, string groupName, ILocateTypes typeLocator)
 {
     return new PersistentStream(
         _logger,
         _eventStore,
         _credentials,
         typeLocator,
         streamName,
         groupName
     );
 }
 public CatchUpStream(
     ILogger<IEventStore> logger,
     IEventStoreConnection eventStore,
     ILocateTypes typeLocator,
     string streamName)
 {
     _logger = logger;
     _eventStore = eventStore;
     _typeLocator = typeLocator;
     _streamName = streamName;
 }
        /// <summary>
        /// Discover all known <see cref="Aggregate"/> implementations known to the specified <paramref name="typeLocator"/>.
        /// </summary>
        /// <param name="typeLocator">The type locator used to retrieve all <see cref="Aggregate"/> type information.</param>
        private static IDictionary <Type, ApplyMethodCollection> DiscoverAggregates(ILocateTypes typeLocator)
        {
            var aggregateTypes = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Aggregate)));
            var result         = new Dictionary <Type, ApplyMethodCollection>();

            foreach (var aggregateType in aggregateTypes)
            {
                result.Add(aggregateType, DiscoverApplyMethods(aggregateType));
            }

            return(result);
        }
        /// <summary>
        /// Initializes a new instance of <see cref="SqlSagaStore"/>.
        /// </summary>
        /// <param name="dialect">The database dialect associated with this <see cref="SqlSagaStore"/>.</param>
        /// <param name="serializer">The <see cref="ISerializeObjects"/> used to store binary data.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Saga"/> types.</param>
        public SqlSagaStore(ISagaStoreDialect dialect, ISerializeObjects serializer, ILocateTypes typeLocator)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serializer, nameof(serializer));
            Verify.NotNull(dialect, nameof(dialect));

            this.dialect = dialect;
            this.serializer = serializer;
            this.typeToGuidMap = GetKnownSagas(typeLocator);
            this.guidToTypeMap = typeToGuidMap.ToDictionary(item => item.Value, item => item.Key);

            Initialize();
        }
Exemple #12
0
        /// <summary>
        /// Initializes a new instance of <see cref="SqlSagaStore"/>.
        /// </summary>
        /// <param name="dialect">The database dialect associated with this <see cref="SqlSagaStore"/>.</param>
        /// <param name="serializer">The <see cref="ISerializeObjects"/> used to store binary data.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Saga"/> types.</param>
        public SqlSagaStore(ISagaStoreDialect dialect, ISerializeObjects serializer, ILocateTypes typeLocator)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serializer, nameof(serializer));
            Verify.NotNull(dialect, nameof(dialect));

            this.dialect       = dialect;
            this.serializer    = serializer;
            this.typeToGuidMap = GetKnownSagas(typeLocator);
            this.guidToTypeMap = typeToGuidMap.ToDictionary(item => item.Value, item => item.Key);

            Initialize();
        }
        /// <summary>
        /// Initializes a new instance of <see cref="EventHandlerRegistry"/> with the specified <paramref name="typeLocator"/> and <paramref name="serviceProvider"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator used to retrieve all known <see cref="Event"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        public EventHandlerRegistry(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy<IPublishCommands> commandPublisher)
        {
            Verify.NotNull(sagaStore, nameof(sagaStore));
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serviceProvider, nameof(serviceProvider));
            Verify.NotNull(commandPublisher, nameof(commandPublisher));

            knownEventHandlers = DiscoverEventHandlers(typeLocator, serviceProvider, sagaStore, commandPublisher);
            knownSagaTimeoutHandlers = knownEventHandlers.Where(item => typeof(Timeout).IsAssignableFrom(item.Key))
                                                         .SelectMany(item => item.Value)
                                                         .OfType<SagaEventHandler>()
                                                         .Distinct(item => item.HandlerType)
                                                         .ToDictionary(item => item.HandlerType, item => new EventHandler[] { item });
        }
Exemple #14
0
        /// <summary>
        /// Initializes a new instance of <see cref="EventHandlerRegistry"/> with the specified <paramref name="typeLocator"/> and <paramref name="serviceProvider"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator used to retrieve all known <see cref="Event"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        public EventHandlerRegistry(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy <IPublishCommands> commandPublisher)
        {
            Verify.NotNull(sagaStore, nameof(sagaStore));
            Verify.NotNull(typeLocator, nameof(typeLocator));
            Verify.NotNull(serviceProvider, nameof(serviceProvider));
            Verify.NotNull(commandPublisher, nameof(commandPublisher));

            knownEventHandlers       = DiscoverEventHandlers(typeLocator, serviceProvider, sagaStore, commandPublisher);
            knownSagaTimeoutHandlers = knownEventHandlers.Where(item => typeof(Timeout).IsAssignableFrom(item.Key))
                                       .SelectMany(item => item.Value)
                                       .OfType <SagaEventHandler>()
                                       .Distinct(item => item.HandlerType)
                                       .ToDictionary(item => item.HandlerType, item => new EventHandler[] { item });
        }
 public PersistentStream(
     ILogger<IEventStore> logger,
     IEventStoreConnection eventStore,
     UserCredentials credentials,
     ILocateTypes typeLocator,
     string streamName,
     string groupName)
 {
     _logger = logger;
     _eventStore = eventStore;
     _credentials = credentials;
     _typeLocator = typeLocator;
     _streamName = streamName;
     _groupName = groupName;
 }
Exemple #16
0
        /// <summary>
        /// Generate unique saga type identifiers for all locatable <see cref="Saga"/> types.
        /// </summary>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Saga"/> types.</param>
        private static Dictionary <Type, Guid> GetKnownSagas(ILocateTypes typeLocator)
        {
            var knownSagas = typeLocator.GetTypes(type => type.IsClass && !type.IsAbstract && type.DerivesFrom(typeof(Saga))).ToDictionary(type => type, HashType);
            var logMessage = new StringBuilder();

            logMessage.AppendLine("Discovered sagas:");
            foreach (var saga in knownSagas)
            {
                logMessage.Append("    ");
                logMessage.AppendFormat("{0} - {1}", saga.Key, saga.Value);
                logMessage.AppendLine();
            }

            Log.Debug(logMessage.ToString);

            return(knownSagas);
        }
Exemple #17
0
        /// <summary>
        /// Discover all command handlers methods associated with any locatable <see cref="Aggregate"/> type.
        /// </summary>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        private static Dictionary <Type, HandleMethodCollection> DiscoverHandleMethods(ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            var aggregateTypes       = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Aggregate)));
            var knownCommandHandlers = new Dictionary <Type, HandleMethodCollection>();

            foreach (var aggregateType in aggregateTypes)
            {
                var handleMethods = GetHandleMethods(aggregateType, serviceProvider);

                knownCommandHandlers.Add(aggregateType, handleMethods);
            }

            return(knownCommandHandlers);
        }
Exemple #18
0
        /// <summary>
        /// Discover all command handlers associated with any locatable <see cref="Aggregate"/> type.
        /// </summary>
        /// <param name="aggregateStore">The <see cref="Aggregate"/> store.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        private static Dictionary <Type, CommandHandler> DiscoverCommandHandlers(IStoreAggregates aggregateStore, ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            var knownHandleMethods = DiscoverHandleMethods(typeLocator, serviceProvider);
            var result             = new Dictionary <Type, CommandHandler>();
            var logMessage         = new StringBuilder();

            logMessage.AppendLine("Discovered command handlers:");
            foreach (var aggregateMapping in knownHandleMethods.OrderBy(kvp => kvp.Key.FullName))
            {
                logMessage.Append("    ");
                logMessage.Append(aggregateMapping.Key);
                logMessage.AppendLine();

                foreach (var handleMethodMapping in aggregateMapping.Value.OrderBy(kvp => kvp.Key.FullName))
                {
                    logMessage.Append("        ");
                    logMessage.Append(handleMethodMapping.Key);
                    logMessage.AppendLine();

                    if (result.ContainsKey(handleMethodMapping.Key))
                    {
                        throw new MappingException(Exceptions.HandleMethodMustBeAssociatedWithSingleAggregate.FormatWith(aggregateMapping.Key, handleMethodMapping.Key));
                    }

                    result.Add(handleMethodMapping.Key, new CommandHandler(aggregateMapping.Key, handleMethodMapping.Key, aggregateStore, handleMethodMapping.Value));
                }
            }

            Log.Debug(logMessage.ToString);

            return(result);
        }
        /// <summary>
        /// Discover all event handlers associated with any locatable class marked with <see cref="EventHandlerAttribute"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known classes marked with <see cref="EventHandlerAttribute"/>.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        private static Dictionary<Type, EventHandler[]> DiscoverEventHandlers(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy<IPublishCommands> commandPublisher)
        {
            var knownEvents = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Event)));
            var knownHandlers = DiscoverHandleMethods(typeLocator, serviceProvider, sagaStore, commandPublisher);
            var result = new Dictionary<Type, EventHandler[]>();
            var logMessage = new StringBuilder();

            logMessage.AppendLine("Discovered event handlers:");
            foreach (var eventType in knownEvents.OrderBy(type => type.FullName))
            {
                var eventHandlers = eventType.GetTypeHierarchy().Reverse()
                                             .Where(knownHandlers.ContainsKey)
                                             .SelectMany(type => knownHandlers[type])
                                             .OrderBy(handler => handler is SagaEventHandler)
                                             .ThenBy(handler => handler.HandlerType.AssemblyQualifiedName)
                                             .ToArray();

                logMessage.Append("    ");
                logMessage.Append(eventType);
                logMessage.AppendLine();

                foreach (var eventHandler in eventHandlers)
                {
                    logMessage.Append("        ");
                    logMessage.Append(eventHandler.HandlerType);
                    logMessage.AppendLine();
                }

                result.Add(eventType, eventHandlers);
            }

            Log.Debug(logMessage.ToString);

            return result;
        }
        /// <summary>
        /// Discover all event handlers methods associated with any locatable class marked with with <see cref="EventHandlerAttribute"/>.
        /// </summary>
        /// <param name="sagaStore">The saga store to pass on to any <see cref="SagaEventHandler"/> instances.</param>
        /// <param name="typeLocator">The type locator use to retrieve all known classes marked with <see cref="EventHandlerAttribute"/>.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton event handler dependencies.</param>
        /// <param name="commandPublisher">The command publisher used to publish saga commands.</param>
        private static Dictionary<Type, List<EventHandler>> DiscoverHandleMethods(ILocateTypes typeLocator, IServiceProvider serviceProvider, IStoreSagas sagaStore, Lazy<IPublishCommands> commandPublisher)
        {
            var handlerTypes = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.GetCustomAttribute<EventHandlerAttribute>() != null);
            var knownEventHandlers = new Dictionary<Type, List<EventHandler>>();

            foreach (var handlerType in handlerTypes)
            {
                var handleMethods = GetHandleMethods(handlerType, serviceProvider);
                var sagaMetadata = typeof(Saga).IsAssignableFrom(handlerType) ? GetSagaMetadata(handlerType, handleMethods) : null;

                foreach (var handleMethod in handleMethods)
                {
                    List<EventHandler> eventHandlers;
                    Type eventType = handleMethod.Key;
                    if (!knownEventHandlers.TryGetValue(eventType, out eventHandlers))
                        knownEventHandlers.Add(eventType, eventHandlers = new List<EventHandler>());

                    var eventHandler = new EventHandler(handlerType, eventType, handleMethod.Value, GetHandlerFactory(handlerType, serviceProvider));
                    if (sagaMetadata != null)
                        eventHandler = eventType == typeof(Timeout) ? new SagaTimeoutHandler(eventHandler, sagaMetadata, sagaStore, commandPublisher) : new SagaEventHandler(eventHandler, sagaMetadata, sagaStore, commandPublisher);

                    eventHandlers.Add(eventHandler);
                }
            }

            return knownEventHandlers;
        }
 public IStream Persistent(string reference, string category, ILocateTypes typeLocator)
 {
     return new MemoryStream(_eventStore);
 }
 public IStream CatchUp(string reference, ILocateTypes typeLocator)
 {
     return new MemoryStream(_eventStore);
 }
        /// <summary>
        /// Initializes a new instance of <see cref="AggregateUpdater"/>.
        /// </summary>
        /// <param name="typeLocator"></param>
        public AggregateUpdater(ILocateTypes typeLocator)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));

            knownApplyMethods = new ReadOnlyDictionary<Type, ApplyMethodCollection>(DiscoverAggregates(typeLocator));
        }
        /// <summary>
        /// Generate unique saga type identifiers for all locatable <see cref="Saga"/> types.
        /// </summary>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Saga"/> types.</param>
        private static Dictionary<Type, Guid> GetKnownSagas(ILocateTypes typeLocator)
        {
            var knownSagas = typeLocator.GetTypes(type => type.IsClass && !type.IsAbstract && type.DerivesFrom(typeof(Saga))).ToDictionary(type => type, HashType);
            var logMessage = new StringBuilder();

            logMessage.AppendLine("Discovered sagas:");
            foreach (var saga in knownSagas)
            {
                logMessage.Append("    ");
                logMessage.AppendFormat("{0} - {1}", saga.Key, saga.Value);
                logMessage.AppendLine();
            }

            Log.Debug(logMessage.ToString);

            return knownSagas;
        }
        /// <summary>
        /// Discover all command handlers methods associated with any locatable <see cref="Aggregate"/> type.
        /// </summary>
        /// <param name="typeLocator">The type locator use to retrieve all known <see cref="Aggregate"/> types.</param>
        /// <param name="serviceProvider">The service locator used to retrieve singleton command handler dependencies.</param>
        private static Dictionary<Type, HandleMethodCollection> DiscoverHandleMethods(ILocateTypes typeLocator, IServiceProvider serviceProvider)
        {
            var aggregateTypes = typeLocator.GetTypes(type => !type.IsAbstract && type.IsClass && type.DerivesFrom(typeof(Aggregate)));
            var knownCommandHandlers = new Dictionary<Type, HandleMethodCollection>();

            foreach (var aggregateType in aggregateTypes)
            {
                var handleMethods = GetHandleMethods(aggregateType, serviceProvider);

                knownCommandHandlers.Add(aggregateType, handleMethods);
            }

            return knownCommandHandlers;
        }
 public IStream CatchUp(string streamName, ILocateTypes typeLocator)
 {
     return _stream;
 }
 public IStream Persistent(string streamName, string groupName, ILocateTypes typeLocator)
 {
     return _stream;
 }
        /// <summary>
        /// Initializes a new instance of <see cref="AggregateUpdater"/>.
        /// </summary>
        /// <param name="typeLocator"></param>
        public AggregateUpdater(ILocateTypes typeLocator)
        {
            Verify.NotNull(typeLocator, nameof(typeLocator));

            knownApplyMethods = new ReadOnlyDictionary <Type, ApplyMethodCollection>(DiscoverAggregates(typeLocator));
        }