// 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(); }
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)); }); }
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; } })); }
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 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 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 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 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>(); }
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 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); }
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); }
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); }
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 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); }
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; } }); }
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(); }
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); }
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>(); } }
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; } })); }