예제 #1
0
            public void ShouldCheckForCorrectQueryType()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomethingWithDelay, string>)queryHandler);

                QueryHandlerDelegate <string> queryHandlerDelegate = registration.ResolveQueryHandler <QuerySomethingWithDelay, string>();

                queryHandlerDelegate.Should().NotBeNull();

                const string data = nameof(ShouldCheckForCorrectQueryType);

                Func <Task> action = async() =>
                {
                    try
                    {
                        await queryHandlerDelegate.Invoke(new QuerySomething(data));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                };

                action.Should().Throw <ArgumentException>();
            }
            public Task Should_Check_For_Correct_Query_Type()
            {
                return(Assert.ThrowsAnyAsync <ArgumentException>(async() =>
                {
                    var queryHandler = new TestQueryHandler(_testOutputHelper);
                    var registration = new QueryHandlerRegistration();
                    registration.Register(() => (IQueryHandler <QuerySomethingWithDelay, string>)queryHandler);

                    QueryHandlerDelegate <string> queryHandlerDelegate = registration.ResolveQueryHandler <QuerySomethingWithDelay, string>();

                    Assert.NotNull(queryHandlerDelegate);

                    const string data = nameof(Should_Check_For_Correct_Query_Type);

                    try
                    {
                        await queryHandlerDelegate.Invoke(new QuerySomething(data));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                }));
            }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Swagger.
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = "AspNetCore Basic Registration Sample", Version = "v1"
                });
                c.IncludeXmlComments(AspNetCoreAppXmlDocPath);
            });

            // Write-side repository.
            services.AddSingleton <IAggregateRootRepository <Product> >((serviceProvider) =>
                                                                        new PublishingAggregateRootRepository <Product>(new InMemoryAggregateRootRepository <Product>(),
                                                                                                                        serviceProvider.GetRequiredService <IDomainEventPublisher>())
                                                                        );

            // Domain event publisher.
            services.AddSingleton <IDomainEventPublisher, DomainEventPublisher>();

            // Read-side repository.
            services.AddSingleton <IProductReadSideRepository, InMemoryProductReadSideRepository>();

            // Register command delegator.
            services.AddSingleton <CommandDelegator>(serviceProvider =>
            {
                // Register command handlers.
                var commandHandlerRegistration = new SingleMessageHandlerRegistration();
                commandHandlerRegistration.RegisterCommandHandler(() => new RegisterProductCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Product> >()));
                commandHandlerRegistration.RegisterCommandHandler(() => new ActivateProductCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Product> >()));
                commandHandlerRegistration.RegisterCommandHandler(() => new DeactivateProductCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Product> >()));

                return(new CommandDelegator(commandHandlerRegistration.BuildMessageHandlerResolver()));
            });

            // Register event delegator.
            services.AddSingleton <EventDelegator>((serviceProvider) =>
            {
                // Register event handlers.
                var eventHandlerRegistration = new MultiMessageHandlerRegistration();
                eventHandlerRegistration.RegisterEventHandler <ProductRegisteredEvent>(() => new ProductDomainEventsHandler(serviceProvider.GetRequiredService <IProductReadSideRepository>()));
                eventHandlerRegistration.RegisterEventHandler <ProductActivatedEvent>(() => new ProductDomainEventsHandler(serviceProvider.GetRequiredService <IProductReadSideRepository>()));
                eventHandlerRegistration.RegisterEventHandler <ProductDeactivatedEvent>(() => new ProductDomainEventsHandler(serviceProvider.GetRequiredService <IProductReadSideRepository>()));

                return(new EventDelegator(eventHandlerRegistration.BuildMessageHandlerResolver()));
            });

            // Register query dispatcher.
            services.AddSingleton <IQueryAsyncDispatcher>(serviceProvider =>
            {
                // Register query handlers.
                var registration = new QueryHandlerRegistration();
                registration.Register(() => new QueryAllProductsHandler(serviceProvider.GetRequiredService <IProductReadSideRepository>()));
                registration.Register(() => new QueryProductByIdHandler(serviceProvider.GetRequiredService <IProductReadSideRepository>()));

                return(new QueryDispatcher(registration));
            });

            services.AddMvc();
        }
예제 #4
0
            public Task Should_Throw_When_Cancelled()
            {
                return(Assert.ThrowsAnyAsync <OperationCanceledException>(async() =>
                {
                    var queryHandler = new TestQueryHandler(_testOutputHelper);
                    var registration = new QueryHandlerRegistration();
                    registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithDelay, string>)queryHandler);

                    var cts = new CancellationTokenSource();

                    var dispatcher = new QueryDispatcher(registration);
                    Task task = dispatcher.DispatchAsync <QuerySomethingWithDelay, string>(new QuerySomethingWithDelay("This will be cancelled", 3000), cts.Token);

                    cts.Cancel();

                    try
                    {
                        await task;
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                }));
            }
            public void ShouldThrowWhenNoRegisteredQueryHandlerIsFound()
            {
                var          registration = new QueryHandlerRegistration();
                var          dispatcher   = new LoggingQueryDispatcher(new QueryDispatcher(registration), _outputHelper);
                const string data         = nameof(ShouldThrowWhenNoRegisteredQueryHandlerIsFound);

                Action action = () => dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data));

                action.Should().Throw <NoQueryHandlerResolvedException>();
            }
            public void ShouldPropagateExceptionFromQueryHandler()
            {
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomethingWithException, string>) new TestQueryHandler(_outputHelper));
                var dispatcher = new LoggingQueryDispatcher(new QueryDispatcher(registration), _outputHelper);

                Action action = () => dispatcher.Dispatch <QuerySomethingWithException, string>(
                    new QuerySomethingWithException("This will cause an exception."));

                action.Should().Throw <TestQueryHandlerException>();
            }
예제 #7
0
            public async Task Should_Allow_Registered_Query_Handlers_With_Non_Reference_Type_Query_Results()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomethingWithNonReferenceTypeResult, int>)queryHandler);

                var dispatcher = new QueryDispatcher(registration);
                var result     = await dispatcher.DispatchAsync <QuerySomethingWithNonReferenceTypeResult, int>(new QuerySomethingWithNonReferenceTypeResult(1973));

                Assert.Equal(1973, result);
            }
            public async Task ShouldAllowRegisteredQueryHandlersWithNonReferenceTypeQueryResults()
            {
                var queryHandler = new TestQueryHandler(_outputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomethingWithNonReferenceTypeResult, int>)queryHandler);

                var dispatcher = new QueryDispatcher(registration);
                var result     = await dispatcher.DispatchAsync <QuerySomethingWithNonReferenceTypeResult, int>(new QuerySomethingWithNonReferenceTypeResult(1973));

                result.Should().Be(1973);
            }
            public async Task ShouldInvokeRegisteredQueryHandler()
            {
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomething, string>) new TestQueryHandler(_outputHelper));

                const string data = nameof(ShouldInvokeRegisteredQueryHandler);

                var dispatcher = new QueryDispatcher(registration);
                var result     = await dispatcher.DispatchAsync <QuerySomething, string>(new QuerySomething(data));

                result.Should().Be(data);
            }
예제 #10
0
            public async Task Should_Invoke_Registered_Query_Handler()
            {
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomething, string>) new TestQueryHandler(_testOutputHelper));

                const string data = nameof(Should_Invoke_Registered_Query_Handler);

                var dispatcher = new QueryDispatcher(registration);
                var result     = await dispatcher.DispatchAsync <QuerySomething, string>(new QuerySomething(data));

                Assert.Equal(result, data);
            }
예제 #11
0
        public static void Begin(IServiceCollection services)
        {
            // Read-side repository.
            services.AddSingleton <IMatchReadStackRepository, MatchReadStackRepository>();

            // Register query dispatcher.
            services.AddSingleton <IQueryAsyncDispatcher>(serviceProvider =>
            {
                // Register query handlers.
                var registration = new QueryHandlerRegistration();
                registration.Register(() => new QueryAllMatchesHandler(serviceProvider.GetRequiredService <IMatchReadStackRepository>()));
                registration.Register(() => new QueryActiveMatchHandler(serviceProvider.GetRequiredService <IMatchReadStackRepository>()));

                return(new QueryDispatcher(registration));
            });
        }
예제 #12
0
            public async Task Should_Invoke_Registered_Query_Handler_With_Cancellation_Token()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithDelay, string>)queryHandler);

                var cts = new CancellationTokenSource();

                var dispatcher = new QueryDispatcher(registration);

                const string data = nameof(Should_Invoke_Registered_Query_Handler_With_Cancellation_Token);

                var result = await dispatcher.DispatchAsync <QuerySomethingWithDelay, string>(new QuerySomethingWithDelay(data, 500), cts.Token);

                Assert.Equal(data, result);
            }
            public async Task ShouldInvokeRegisteredQueryHandlerWithCancellationToken()
            {
                var queryHandler = new TestQueryHandler(_outputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithDelay, string>)queryHandler);

                var cts = new CancellationTokenSource();

                var dispatcher = new QueryDispatcher(registration);

                const string data = nameof(ShouldInvokeRegisteredQueryHandlerWithCancellationToken);

                var result = await dispatcher.DispatchAsync <QuerySomethingWithDelay, string>(new QuerySomethingWithDelay(data, 500), cts.Token);

                result.Should().Be(data);
            }
예제 #14
0
            public async Task ShouldRegisterAllQueryHandlers()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomething, string>)queryHandler);

                QueryHandlerDelegate <string> queryHandlerDelegate = registration.ResolveQueryHandler <QuerySomething, string>();

                var query = new QuerySomething(nameof(ShouldRegisterAllQueryHandlers));

                var result1 = await queryHandler.HandleAsync(query);

                var result2 = await queryHandlerDelegate.Invoke(query);

                result1.Should().Be(result2);
            }
예제 #15
0
            public async Task ShouldInvokeTheActualRegisteredQueryHandler()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);

                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomething, string>)queryHandler);

                QueryHandlerDelegate <string> queryHandlerDelegate = registration.ResolveQueryHandler <QuerySomething, string>();

                queryHandlerDelegate.Should().NotBeNull();

                const string data = nameof(ShouldInvokeTheActualRegisteredQueryHandler);

                // Invoke.
                await queryHandlerDelegate.Invoke(new QuerySomething(data));

                queryHandler.HandledQueries.Should().HaveCount(1);
                queryHandler.HasHandledQuery <QuerySomething>().Should().BeTrue();
            }
예제 #16
0
            public void Should_Propagate_Exception_From_Query_Handler()
            {
                Assert.Throws <TestQueryHandlerException>(() =>
                {
                    var registration = new QueryHandlerRegistration();
                    registration.Register(() => (IQueryHandler <QuerySomethingWithException, string>) new TestQueryHandler(_testOutputHelper));

                    var dispatcher = new QueryDispatcher(registration);

                    try
                    {
                        dispatcher.Dispatch <QuerySomethingWithException, string>(new QuerySomethingWithException("This will cause an exception."));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                });
            }
예제 #17
0
            public void Should_Throw_When_No_Registered_Query_Handler_Is_Found()
            {
                Assert.Throws <NoQueryHandlerResolvedException>(() =>
                {
                    var registration = new QueryHandlerRegistration();
                    var dispatcher   = new QueryDispatcher(registration);

                    const string data = nameof(Should_Throw_When_No_Registered_Query_Handler_Is_Found);

                    try
                    {
                        var result = dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                });
            }
예제 #18
0
            public Task Should_Throw_When_No_Registered_Query_Handler_Is_Found()
            {
                return(Assert.ThrowsAsync <NoQueryHandlerResolvedException>(async() =>
                {
                    var registration = new QueryHandlerRegistration();
                    var dispatcher = new QueryDispatcher(registration);

                    const string data = nameof(Should_Throw_When_No_Registered_Query_Handler_Is_Found);

                    try
                    {
                        var result = await dispatcher.DispatchAsync <QuerySomething, string>(new QuerySomething((string)data));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                }));
            }
            public void ShouldInvokeRegisteredQueryHandlerWhenDispatchedMultipleTimes()
            {
                var queryHandler = new TestQueryHandler(_outputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomething, string>)queryHandler);
                registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithNonReferenceTypeResult, int>) new TestQueryHandler(_outputHelper));

                const string data1 = "Test message 1.";
                const string data2 = "Test message 2.";
                const int    data3 = 1;

                var dispatcher = new QueryDispatcher(registration);
                var result1    = dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data1));
                var result2    = dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data2));
                var result3    = dispatcher.Dispatch <QuerySomethingWithNonReferenceTypeResult, int>(new QuerySomethingWithNonReferenceTypeResult(data3));

                result1.Should().Be(data1);
                result2.Should().Be(data2);
                result3.Should().Be(data3);
            }
            public void ShouldThrowWhenCancelled()
            {
                var queryHandler = new TestQueryHandler(_outputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithDelay, string>)queryHandler);
                var dispatcher = new QueryDispatcher(registration);

                using (var cts = new CancellationTokenSource())
                {
                    Task task = dispatcher.DispatchAsync <QuerySomethingWithDelay, string>(
                        new QuerySomethingWithDelay("This will be cancelled", 3000), cts.Token);

                    // Cancel.
                    cts.Cancel();

                    Func <Task> cancelledTask = () => task;

                    cancelledTask.Should().Throw <OperationCanceledException>();
                }
            }
예제 #21
0
            public Task Should_Propagate_Exception_From_Query_Handler()
            {
                return(Assert.ThrowsAnyAsync <TestQueryHandlerException>(async() =>
                {
                    var queryHandler = new TestQueryHandler(_testOutputHelper);
                    var registration = new QueryHandlerRegistration();
                    registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithException, string>)queryHandler);

                    var dispatcher = new QueryDispatcher(registration);

                    try
                    {
                        await dispatcher.DispatchAsync <QuerySomethingWithException, string>(new QuerySomethingWithException("This will cause an exception."));
                    }
                    catch (Exception ex)
                    {
                        _testOutputHelper.WriteLine(ex.ToString());
                        throw;
                    }
                }));
            }
예제 #22
0
            public void Should_Invoke_Registered_Query_Handler_When_Dispatched_Multiple_Times()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);
                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryAsyncHandler <QuerySomething, string>)queryHandler);
                registration.Register(() => (IQueryAsyncHandler <QuerySomethingWithNonReferenceTypeResult, int>) new TestQueryHandler(_testOutputHelper));

                const string data1 = "Test message 1.";
                const string data2 = "Test message 2.";
                const int    data3 = 1;

                var dispatcher = new QueryDispatcher(registration);
                var result1    = dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data1));
                var result2    = dispatcher.Dispatch <QuerySomething, string>(new QuerySomething(data2));
                var result3    = dispatcher.Dispatch <QuerySomethingWithNonReferenceTypeResult, int>(new QuerySomethingWithNonReferenceTypeResult(data3));

                Assert.Equal(data1, result1);
                Assert.Equal(data2, result2);
                Assert.Equal(data3, result3);
            }
            public async Task Should_Invoke_The_Actual_Registered_Query_Handler()
            {
                var queryHandler = new TestQueryHandler(_testOutputHelper);

                var registration = new QueryHandlerRegistration();

                registration.Register(() => (IQueryHandler <QuerySomething, string>)queryHandler);

                QueryHandlerDelegate <string> queryHandlerDelegate = registration.ResolveQueryHandler <QuerySomething, string>();

                Assert.NotNull(queryHandlerDelegate);

                const string data = nameof(Should_Invoke_The_Actual_Registered_Query_Handler);

                // Invoke.
                await queryHandlerDelegate.Invoke(new QuerySomething(data));

                // Check if actual command handler instance was invoked.
                Assert.Equal(1, queryHandler.HandledQueries.Count);
                Assert.Contains(queryHandler.HandledQueries, c => c is QuerySomething);
            }