public ICqrsBuilder RegisterEventHandlers(Action <ICqrsEventHandlerSelector> selector)
        {
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            // Select event handlers to register.
            selector(_eventHandlerSelector);

            _builder.Register(context =>
            {
                IMessageHandlerResolver[] handlers = context.Resolve <IEnumerable <EventHandlerDelegateResolver> >().ToArray();

                if (handlers.Any())
                {
                    return(handlers.Length > 1
                        ? new EventDelegator(CompositeMessageHandlerResolver.Compose(handlers))
                        : new EventDelegator(handlers[0]));
                }

                return(new EventDelegator(NullMessageHandlerDelegateResolver.Instance));
            }).As <EventDelegator>().SingleInstance();

            return(this);
        }
            public void ShouldResolveTheFirstAvaibleMessageHandlerFromListOfResolvers()
            {
                // Given
                int expectedNumberOfHandlers = 3;
                int actualNumberOfHandlers   = 0;

                IMessageHandlerResolver multiResolver = CreateMultiMessageHandlerResolver(multiRegistration =>
                {
                    // These should be invoked.
                    multiRegistration.Register <TestMessage>((message, ct) => { actualNumberOfHandlers++; return(Task.CompletedTask); });
                    multiRegistration.Register <TestMessage>((message, ct) => { actualNumberOfHandlers++; return(Task.CompletedTask); });
                    multiRegistration.Register <TestMessage>((message, ct) => { actualNumberOfHandlers++; return(Task.CompletedTask); });
                });

                // This should not be invoked.
                IMessageHandlerResolver singleResolver = CreateSingleMessageHandlerResolver(singleRegistration =>
                {
                    singleRegistration.Register <TestMessage>((message, ct) => { actualNumberOfHandlers++; return(Task.CompletedTask); });
                });

                CompositeMessageHandlerResolver compositeResolver = CreateCompositeMessageHandlerResolver(multiResolver, singleResolver);

                // When
                MessageHandlerDelegate handler = compositeResolver.ResolveMessageHandler(typeof(TestMessage));

                handler.Invoke(new TestMessage()); // Should invode the handlers registered in multi registration

                // Then
                actualNumberOfHandlers.ShouldBeEquivalentTo(expectedNumberOfHandlers);
            }
        public ICqrsBuilder RegisterEventHandlers(Action <ICqrsEventHandlerSelector> selector)
        {
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            selector(_eventHandlerSelector);

            _container.RegisterSingleton <EventDelegator>(() =>
            {
                if (TryGetInstance(out IEnumerable <EventHandlerDelegateResolver> eventHandlerResolvers))
                {
                    EventHandlerDelegateResolver[] resolverArray = eventHandlerResolvers.ToArray();

                    if (resolverArray.Length == 1)
                    {
                        return(new EventDelegator(resolverArray[0]));
                    }

                    return(new EventDelegator(CompositeMessageHandlerResolver.Compose(resolverArray)));
                }

                return(new EventDelegator(NullMessageHandlerDelegateResolver.Instance));
            });

            return(this);
        }
        public ICqrsCommandHandlerSelector ByInterface(ServiceLifetime lifetime, params Assembly[] assemblies)
        {
            if (assemblies == null)
            {
                throw new ArgumentNullException(nameof(assemblies));
            }

            if (assemblies.Length == 0)
            {
                throw new ArgumentException("No command handler assemblies were provided.", nameof(assemblies));
            }

            _serviceCollection.Scan(scan => scan
                                    // Scan distinct assemblies.
                                    .FromAssemblies(assemblies.Distinct())
                                    // Register async and sync command handlers
                                    .AddClasses(classes => classes.AssignableToAny(typeof(ICommandAsyncHandler <>), typeof(ICommandHandler <>)))
                                    .AsImplementedInterfaces()
                                    .WithLifetime(lifetime));

            _serviceCollection.AddSingleton <CommandHandlerDelegateResolver>(serviceProvider =>
            {
                return(new CommandHandlerDelegateResolver(
                           CompositeMessageHandlerResolver.Compose(
                               new ContainerCommandAsyncHandlerResolver(new ServiceProviderAdapter(serviceProvider)),
                               new ContainerCommandHandlerResolver(new ServiceProviderAdapter(serviceProvider)))));
            });

            return(this);
        }
        public ICqrsBuilder AddEventHandlers(Action <ICqrsEventHandlerSelector> selector)
        {
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            selector(_eventHandlerSelector);

            _serviceCollection.AddSingleton <EventDelegator>(serviceProvider =>
            {
                EventHandlerDelegateResolver[] messageHandlerResolvers = serviceProvider.GetServices <EventHandlerDelegateResolver>().ToArray();

                if (messageHandlerResolvers.Length == 1)
                {
                    return(new EventDelegator(messageHandlerResolvers[0]));
                }
                else if (messageHandlerResolvers.Length > 1)
                {
                    return(new EventDelegator(CompositeMessageHandlerResolver.Compose(messageHandlerResolvers)));
                }

                // Empty delegator.
                return(new EventDelegator(NullMessageHandlerDelegateResolver.Instance));
            });

            return(this);
        }
        public ICqrsCommandHandlerSelector ByInterface(Lifetime lifetime, params Assembly[] assemblies)
        {
            if (assemblies == null)
            {
                throw new ArgumentNullException(nameof(assemblies));
            }

            if (assemblies.Length == 0)
            {
                throw new ArgumentException("No command handler assemblies were provided.", nameof(assemblies));
            }

            Assembly[] distinctAssemblies = assemblies.Distinct().ToArray();

            var asyncHandlerRegistration = _builder.RegisterAssemblyTypes(distinctAssemblies)
                                           .AsClosedTypesOf(typeof(ICommandAsyncHandler <>))
                                           .AsImplementedInterfaces();

            var syncHandlerRegistration = _builder.RegisterAssemblyTypes(distinctAssemblies)
                                          .AsClosedTypesOf(typeof(ICommandHandler <>))
                                          .AsImplementedInterfaces();

            // Update registration if lifetime is not PerDependency.
            switch (lifetime)
            {
            case Lifetime.PerLifetimeScope:
            {
                asyncHandlerRegistration.InstancePerLifetimeScope();
                syncHandlerRegistration.InstancePerLifetimeScope();
            }
            break;

            case Lifetime.Singleton:
            {
                asyncHandlerRegistration.SingleInstance();
                syncHandlerRegistration.SingleInstance();
            }
            break;
            }

            _builder.Register(context =>
            {
                var c       = context.Resolve <IComponentContext>();
                var adapter = new ComponentContextAdapter(c);
                return(new CommandHandlerDelegateResolver(
                           CompositeMessageHandlerResolver.Compose(
                               new ContainerCommandAsyncHandlerResolver(adapter),
                               new ContainerCommandHandlerResolver(adapter))));
            }).AsSelf().SingleInstance();

            return(this);
        }
            public void ShouldReturnNullMessageHandlerIfNoMessageHandlerIsFound()
            {
                // Given empty registration
                IMessageHandlerResolver         multiRegistration  = CreateMultiMessageHandlerResolver();
                IMessageHandlerResolver         singleRegistration = CreateSingleMessageHandlerResolver();
                CompositeMessageHandlerResolver compositeResolver  = CreateCompositeMessageHandlerResolver(multiRegistration, singleRegistration);

                // When
                MessageHandlerDelegate handler = compositeResolver.ResolveMessageHandler(typeof(TestMessage));

                // Then
                handler.ShouldBeEquivalentTo(NullMessageHandlerDelegate.Instance);
            }
Esempio n. 8
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">Service collection.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            // Swagger.
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = "AspNetCore Sample", Version = "v1"
                });
                c.IncludeXmlComments(AspNetCoreAppXmlDocPath);
            });

            // Write side repository.
            services.AddSingleton <IProductRepository>((serviceProvider) =>
                                                       // Use in-memory repository, decorated by a PublishingProductRepository which publishes domain events from the Product aggregate root.
                                                       new PublishingProductRepository(new InMemoryProductRepository(), serviceProvider.GetRequiredService <IMessageDelegator>())
                                                       );

            // Register read side services.
            // In this sample, we will just have a read side repository
            // which serves as a thin layer between the app layer and the data layer.
            services.AddSingleton <IProductReadSideRepository, InMemoryProductReadSideRepository>();

            // Register command handlers and event handlers to the container.
            services.AddTransient <RegisterProductCommandHandler>();
            services.AddTransient <ActivateProductCommandHandler>();
            services.AddTransient <DeactivateProductCommandHandler>();
            services.AddTransient <ProductDomainEventsHandler>();

            // Register message delegator to the container.
            services.AddSingleton <IMessageDelegator>((serviceProvider) =>
            {
                // Register command handlers to the message handler registration.
                // Commands can only have one handler so use SingleMessageHandlerRegistration.
                SingleMessageHandlerRegistration commandHandlerRegistration = RegisterCommandHandlers(serviceProvider);

                // Register event handlers to the message handler registration.
                // Events can have multiple handlers so use MultiMessageHandlerRegistration.
                MultiMessageHandlerRegistration eventHandlerRegistration = RegisterEventHandlers(serviceProvider);

                // Combine command handlers and event handlers.
                var resolver = CompositeMessageHandlerResolver.Compose(
                    commandHandlerRegistration.BuildMessageHandlerResolver(),
                    eventHandlerRegistration.BuildMessageHandlerResolver()
                    );

                return(new MessageDelegator(resolver));
            });
        }
Esempio n. 9
0
        private static App Setup(string[] args)
        {
            // Simple injector.
            Container container = new Container();

            // Write side repository.
            container.RegisterSingleton <IProductRepository>(() =>
                                                             // Use in-memory repository, decorated by a PublishingProductRepository which publishes domain events from the Product.
                                                             new PublishingProductRepository(new InMemoryProductRepository(), container.GetInstance <IMessageDelegator>())
                                                             );

            // Register read side services.
            // In this sample, we will just have a read side repository
            // which serves as a thin layer between the app layer and the data layer.
            container.RegisterSingleton <IProductReadSideRepository, InMemoryProductReadSideRepository>();

            // Register command handlers and event handlers to the container.
            container.Register <RegisterProductCommandHandler>();
            container.Register <ActivateProductCommandHandler>();
            container.Register <DeactivateProductCommandHandler>();
            container.Register <ProductDomainEventsHandler>();

            // Register console app use cases.
            container.RegisterCollection(typeof(IUseCase), typeof(IUseCase).Assembly);

            // Message delegator.
            container.RegisterSingleton <IMessageDelegator>(() =>
            {
                // Register command handlers to the message handler registration.
                // Commands can only have one handler so use SingleMessageHandlerRegistration.
                SingleMessageHandlerRegistration commandHandlerRegistration = RegisterCommandHandlers(container);

                // Register event handlers to the message handler registration.
                // Events can have multiple handlers so use MultiMessageHandlerRegistration.
                MultiMessageHandlerRegistration eventHandlerRegistration = RegisterEventHandlers(container);

                // Combine command handlers and event handlers.
                var resolver = CompositeMessageHandlerResolver.Compose(
                    commandHandlerRegistration.BuildMessageHandlerResolver(),
                    eventHandlerRegistration.BuildMessageHandlerResolver()
                    );

                return(new MessageDelegator(resolver));
            });

            return(new App(container));
        }
Esempio n. 10
0
            public void ShouldThrowWhenNoHandlerIsResolvedFromCompositeMessageHandlerResolver()
            {
                // Given empty registration
                IMessageHandlerResolver         multiResolver     = CreateMultiMessageHandlerResolver();
                IMessageHandlerResolver         singleResolver    = CreateSingleMessageHandlerResolver();
                CompositeMessageHandlerResolver compositeResolver = CreateCompositeMessageHandlerResolver(singleResolver, multiResolver);
                RequiredMessageHandlerResolver  requiredResolver  = CreateRequiredMessageHandlerResolver(compositeResolver);

                Action action = () =>
                {
                    // When
                    MessageHandlerDelegate handler = requiredResolver.ResolveMessageHandler(typeof(TestMessage));
                };

                // Then
                action.ShouldThrow <NoMessageHandlerResolvedException>("RequiredMessageHandlerResolver should require a message handler to be found.");
            }
Esempio n. 11
0
            public void ShouldResolveCommandHandlerFromCompositeResolver()
            {
                var commandHandler = new TestCommandHandler(_outputHelper);
                var container      = new Container();

                container.RegisterSingleton <ICommandHandler <TestCommand> >(commandHandler);
                container.RegisterSingleton <ICommandAsyncHandler <CancellableTestCommand> >(commandHandler);

                // Exception handler will log and ignore exception.
                Func <Exception, bool> exceptionHandler = (ex) =>
                {
                    if (ex != null)
                    {
                        _outputHelper.WriteLine($"Ignoring encountered exception while trying to resolve command handler: {ex.Message}");

                        // Notify as handled if no command handler is resolved from other resolvers.
                        return(true);
                    }

                    return(false);
                };

                var containerAdapter = new SimpleInjectorContainerAdapter(container);
                var containerAsyncHandlerResolver = new ContainerCommandAsyncHandlerResolver(containerAdapter, exceptionHandler);
                var containerHandlerResolver      = new ContainerCommandHandlerResolver(containerAdapter, exceptionHandler);

                CompositeMessageHandlerResolver compositeResolver = CompositeMessageHandlerResolver.Compose(
                    containerAsyncHandlerResolver,
                    containerHandlerResolver);

                MessageHandlerDelegate testCommandHandlerDelegate            = compositeResolver.ResolveMessageHandler(typeof(TestCommand));
                MessageHandlerDelegate cancellableTestCommandHandlerDelegate = compositeResolver.ResolveMessageHandler(typeof(CancellableTestCommand));

                testCommandHandlerDelegate?.Invoke(new TestCommand());
                cancellableTestCommandHandlerDelegate?.Invoke(new CancellableTestCommand());

                commandHandler.HandledCommands.Should().HaveCount(2);
                commandHandler.HasHandledCommand <TestCommand>().Should().BeTrue();
                commandHandler.HasHandledCommand <CancellableTestCommand>().Should().BeTrue();
            }
Esempio n. 12
0
        public ICqrsCommandHandlerSelector ByInterface(Lifestyle lifeStyle, params Assembly[] assemblies)
        {
            if (lifeStyle == null)
            {
                throw new ArgumentNullException(nameof(lifeStyle));
            }

            if (assemblies == null)
            {
                throw new ArgumentNullException(nameof(assemblies));
            }

            if (assemblies.Length == 0)
            {
                throw new ArgumentException("No command handler assemblies were provided.", nameof(assemblies));
            }

            IEnumerable <Assembly> distinctAssemblies = assemblies.Distinct();

            _container.Register(typeof(ICommandAsyncHandler <>), distinctAssemblies, lifeStyle);
            _container.Register(typeof(ICommandHandler <>), distinctAssemblies, lifeStyle);

            // Register resolver.
            _container.Collections.AppendTo(
                typeof(CommandHandlerDelegateResolver),
                Lifestyle.Singleton.CreateRegistration(() =>
                                                       new CommandHandlerDelegateResolver(
                                                           // Combine container async and sync command handler resolver.
                                                           CompositeMessageHandlerResolver.Compose(
                                                               new ContainerCommandAsyncHandlerResolver(new SimpleInjectorContainerAdapter(_container)),
                                                               new ContainerCommandHandlerResolver(new SimpleInjectorContainerAdapter(_container)))),
                                                       _container
                                                       )
                );

            return(this);
        }