public static void AddCqrsHandlers(this IServiceCollection services, IEnumerable <Assembly> assemblies)
        {
            List <Type> commandHandlerTypes = assemblies.SelectMany(assembly => assembly.GetTypes())
                                              .Where(x => x.GetInterfaces().Any(y => IsCommandHandlerInterface(y)))
                                              .Where(x => x.Name.EndsWith("Handler"))
                                              .ToList();

            foreach (Type commandHandlerType in commandHandlerTypes)
            {
                AddHandlerAsService(services, commandHandlerType);
            }

            services.AddSingleton <ICqrsCommandSubscriptionsManager>(sp => {
                var subManager = new CqrsInMemoryCommandSubscriptionsManager();
                foreach (Type commandHandlerType in commandHandlerTypes)
                {
                    IEnumerable <Type> interfaceTypes = commandHandlerType.GetInterfaces().Where(y => IsHandlerInterface(y));

                    foreach (Type interfaceType in interfaceTypes)
                    {
                        Type commandType = interfaceType.GetGenericArguments()[0];

                        subManager.AddSubscription(commandType, commandHandlerType);
                    }
                }
                return(subManager);
            });

            List <Type> queryHandlerTypes = assemblies.SelectMany(assembly => assembly.GetTypes())
                                            .Where(x => x.GetInterfaces().Any(y => IsQueryHandlerInterface(y)))
                                            .Where(x => x.Name.EndsWith("Handler"))
                                            .ToList();

            foreach (Type queryHandlerType in queryHandlerTypes)
            {
                AddHandlerAsService(services, queryHandlerType);
            }

            services.AddSingleton <ICqrsQuerySubscriptionsManager>(sp => {
                var subManager = new CqrsInMemoryQuerySubscriptionsManager();
                foreach (Type queryHandlerType in queryHandlerTypes)
                {
                    IEnumerable <Type> interfaceTypes = queryHandlerType.GetInterfaces().Where(y => IsHandlerInterface(y));

                    foreach (var interfaceType in interfaceTypes)
                    {
                        Type queryType = interfaceType.GetGenericArguments()[0];

                        subManager.AddSubscription(queryType, queryHandlerType);
                    }
                }
                return(subManager);
            });
        }
        public static void AddCqrsHandlers(this IServiceCollection services, IEnumerable <Assembly> assemblies)
        {
            bool addHandlersAsServices = false;

            //commands
            List <Type> commandHandlerTypes = assemblies.SelectMany(assembly => assembly.GetTypes())
                                              .Where(x => x.GetInterfaces().Any(y => IsCommandHandlerInterface(y)))
                                              .Where(x => x.Name.EndsWith("Handler") && !x.IsAbstract && !x.IsGenericType)
                                              .ToList();

            //Add Handlers as Transient Services to DI
            //ICommandHandler<dynamic,TResponse> are registered against concrete Type.
            //ICommandHandler<TCommand,TResponse> are registered against interface.
            if (addHandlersAsServices)
            {
                foreach (Type commandHandlerType in commandHandlerTypes)
                {
                    AddHandlerAsService(services, commandHandlerType, false);
                }
            }

            //Register non dynamic Command Subscription. Dynamic subscriptions need to be added manually.
            //TCommand --> ICommandHandler<TCommand,TResponse>
            services.AddSingleton <ICqrsCommandSubscriptionsManager>(sp => {
                var subManager = new CqrsInMemoryCommandSubscriptionsManager();
                foreach (Type commandHandlerType in commandHandlerTypes.Where(x => x.GetInterfaces().Any(y => IsCommandHandlerInterface(y))))
                {
                    IEnumerable <Type> interfaceTypes = commandHandlerType.GetInterfaces().Where(y => IsCommandHandlerInterface(y));

                    foreach (Type interfaceType in interfaceTypes)
                    {
                        Type commandType = interfaceType.GetGenericArguments()[0];

                        if (commandType != typeof(Object))
                        {
                            if (addHandlersAsServices)
                            {
                                subManager.AddSubscription(commandType, interfaceType);
                            }
                            else
                            {
                                subManager.AddSubscription(commandType, commandHandlerType);
                            }
                        }
                    }
                }
                return(subManager);
            });

            //queries
            List <Type> queryHandlerTypes = assemblies.SelectMany(assembly => assembly.GetTypes())
                                            .Where(x => x.GetInterfaces().Any(y => IsQueryHandlerInterface(y)))
                                            .Where(x => x.Name.EndsWith("Handler") && !x.IsAbstract && !x.IsGenericType)
                                            .ToList();

            //Add Handlers as Transient Services to DI
            //IQueryHandler<dynamic,TResult> are registered against concrete Type.
            //IQueryHandler<TQuery,TResult> are registered against interface.
            if (addHandlersAsServices)
            {
                foreach (Type queryHandlerType in queryHandlerTypes)
                {
                    AddHandlerAsService(services, queryHandlerType, true);
                }
            }

            //Register non dynamic Query Subscription. Dynamic subscriptions need to be added manually.
            //TQuery --> IQueryHandler<TQuery,TResult>
            services.AddSingleton <ICqrsQuerySubscriptionsManager>(sp => {
                var subManager = new CqrsInMemoryQuerySubscriptionsManager();
                foreach (Type queryHandlerType in queryHandlerTypes.Where(x => x.GetInterfaces().Any(y => IsQueryHandlerInterface(y))))
                {
                    IEnumerable <Type> interfaceTypes = queryHandlerType.GetInterfaces().Where(y => IsQueryHandlerInterface(y));

                    foreach (var interfaceType in interfaceTypes)
                    {
                        Type queryType = interfaceType.GetGenericArguments()[0];

                        if (queryType != typeof(Object))
                        {
                            if (addHandlersAsServices)
                            {
                                subManager.AddSubscription(queryType, interfaceType);
                            }
                            else
                            {
                                subManager.AddSubscription(queryType, queryHandlerType);
                            }
                        }
                    }
                }
                return(subManager);
            });
        }