private static SingleMessageHandlerRegistration RegisterCommandHandlers(IServiceProvider serviceProvider) { // Register command handlers to the message handler registration. // Commands can only have one handler so use SingleMessageHandlerRegistration. var commandHandlerRegistration = new SingleMessageHandlerRegistration(); // ActivateProductCommand commandHandlerRegistration.Register <RegisterProductCommand>((message, cancellationToken) => { // You can also manually instantiate if that's how you roll. var handler = serviceProvider.GetRequiredService <RegisterProductCommandHandler>(); return(handler.HandleRegisterProductCommandAsync(message, cancellationToken)); }); // ActivateProductCommand commandHandlerRegistration.Register <ActivateProductCommand>((message, cancellationToken) => { // You can also manually instantiate if that's how you roll. var handler = serviceProvider.GetRequiredService <ActivateProductCommandHandler>(); return(handler.HandleActivateProductCommandAsync(message, cancellationToken)); }); // DeactivateProductCommand commandHandlerRegistration.Register <DeactivateProductCommand>((message, cancellationToken) => { // You can also manually instantiate if that's how you roll. var handler = serviceProvider.GetRequiredService <DeactivateProductCommandHandler>(); return(handler.HandleDeactivateProductCommandAsync(message, cancellationToken)); }); return(commandHandlerRegistration); }
// 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 ICqrsCommandHandlerSelector ByAttribute(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 classes that has a method marked with [CommandHandler] .AddClasses(classes => classes.Where(type => CommandHandlerAttributeMethod.IsFoundInType(type))) .AsSelf() .WithLifetime(lifetime)); _serviceCollection.AddSingleton <CommandHandlerDelegateResolver>(serviceProvider => { var singleMessageHandlerRegistration = new SingleMessageHandlerRegistration(); singleMessageHandlerRegistration.RegisterCommandHandlersByAttribute(assemblies, serviceProvider.GetRequiredService); return(new CommandHandlerDelegateResolver(singleMessageHandlerRegistration.BuildMessageHandlerResolver())); }); return(this); }
// 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 Mixed Registration Sample", Version = "v1" }); c.IncludeXmlComments(AspNetCoreAppXmlDocPath); }); // Write-side repository. services.AddSingleton <IProductRepository>((serviceProvider) => new PublishingProductRepository(new InMemoryProductRepository(), serviceProvider.GetRequiredService <EventDelegator>()) ); // Read-side repository. services.AddSingleton <IProductReadSideRepository, InMemoryProductReadSideRepository>(); // Register command delegator. services.AddSingleton <CommandDelegator>((serviceProvider) => { // Register command handlers through simple registration. var commandHandlerRegistration = new SingleMessageHandlerRegistration(); commandHandlerRegistration.RegisterCommandHandler(() => new RegisterProductCommandHandler(serviceProvider.GetRequiredService <IProductRepository>())); commandHandlerRegistration.RegisterCommandHandler(() => new ActivateProductCommandHandler(serviceProvider.GetRequiredService <IProductRepository>())); commandHandlerRegistration.RegisterCommandHandler(() => new DeactivateProductCommandHandler(serviceProvider.GetRequiredService <IProductRepository>())); return(new CommandDelegator(commandHandlerRegistration.BuildMessageHandlerResolver())); }); // Register event delegator. services.AddSingleton <EventDelegator>((serviceProvider) => { // Register event handlers through simple registration. 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 handlers to container. services.AddTransient <IQueryAsyncHandler <QueryAllProducts, IReadOnlyCollection <ProductReadModel> >, QueryAllProductsHandler>(); services.AddTransient <IQueryAsyncHandler <QueryProductById, ProductReadModel>, QueryProductByIdHandler>(); // Register query dispatcher. services.AddSingleton <IQueryAsyncDispatcher>(serviceProvider => new QueryDispatcher(new ContainerQueryAsyncHandlerResolver(new AspNetCoreServiceProviderAdapter(serviceProvider))) ); services.AddMvc(); }
public static IMessageHandlerResolver CreateSingleMessageHandlerResolver(Action <SingleMessageHandlerRegistration> registrationAction = null) { var registration = new SingleMessageHandlerRegistration(); if (registrationAction != null) { registrationAction(registration); } return(registration.BuildMessageHandlerResolver()); }
public void ShouldNotAllowNullWhenRegisteringSyncHandler() { // Given Action action = () => { SingleMessageHandlerRegistration registration = CreateSingleHandlerRegistration(); // When registration.Register((Action <TestMessage>)null); }; // Then action.ShouldThrow <ArgumentNullException>("null is not allowed."); }
public ICqrsCommandHandlerSelector ByAttribute(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)); } // Get all types that has methods marked with [CommandHandler] attribute from distinct assemblies. IEnumerable <Type> foundTypes = assemblies.Distinct() .SelectMany(assembly => assembly.GetTypes()) .Where(type => type.IsClass && !type.IsAbstract && CommandHandlerAttributeMethod.IsFoundInType(type)) .ToArray(); if (!foundTypes.Any()) { return(this); } foreach (Type type in foundTypes) { // Register type as self. _container.Register(type, type, lifeStyle); } var singleMessageHandlerRegistration = new SingleMessageHandlerRegistration(); singleMessageHandlerRegistration.RegisterCommandHandlersByAttribute(foundTypes, _container.GetInstance); // Register resolver. _container.Collections.AppendTo( typeof(CommandHandlerDelegateResolver), Lifestyle.Singleton.CreateRegistration(() => new CommandHandlerDelegateResolver(singleMessageHandlerRegistration.BuildMessageHandlerResolver()), _container ) ); return(this); }
/// <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)); }); }
public void ShouldOnlyAllowOneAsyncDelegatePerMessageType() { // Given Action action = () => { SingleMessageHandlerRegistration registration = CreateSingleHandlerRegistration(); // When registration.Register <TestMessage>((message, ct) => Task.CompletedTask); registration.Register <TestMessage>((message, ct) => Task.CompletedTask); }; // Then action.ShouldThrow <InvalidOperationException>("only one message handler delegate per message type should be allowed."); }
public void ShouldThrowWhenNoHandlerIsResolvedFromSingleMessageHandlerResolve() { // Given empty registration SingleMessageHandlerRegistration registration = CreateSingleHandlerRegistration(); RequiredMessageHandlerResolver requiredResolver = CreateRequiredMessageHandlerResolver(registration.BuildMessageHandlerResolver()); Action action = () => { // When MessageHandlerDelegate handler = requiredResolver.ResolveMessageHandler(typeof(TestMessage)); }; // Then action.ShouldThrow <NoMessageHandlerResolvedException>("RequiredMessageHandlerResolver should require a message handler to be found."); }
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)); }
public ICqrsCommandHandlerSelector ByAttribute(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 handlerRegistration = _builder.RegisterAssemblyTypes(distinctAssemblies) .Where(type => type.IsClass && !type.IsAbstract && CommandHandlerAttributeMethod.IsFoundInType(type)) .AsSelf(); // Update registration if lifetime is not PerDependency. switch (lifetime) { case Lifetime.PerLifetimeScope: { handlerRegistration.InstancePerLifetimeScope(); } break; case Lifetime.Singleton: { handlerRegistration.SingleInstance(); } break; } _builder.Register(context => { var c = context.Resolve <IComponentContext>(); var singleMessageHandlerRegistration = new SingleMessageHandlerRegistration(); singleMessageHandlerRegistration.RegisterCommandHandlersByAttribute(distinctAssemblies, c.Resolve); return(new CommandHandlerDelegateResolver(singleMessageHandlerRegistration.BuildMessageHandlerResolver())); }).AsSelf().SingleInstance(); return(this); }
public void ShouldOnlyAllowOneSyncDelegatePerMessageType() { // Given Action action = () => { SingleMessageHandlerRegistration registration = CreateSingleHandlerRegistration(); // Stub Action <TestMessage> doNothingAction = (message) => {}; // When registration.Register <TestMessage>(doNothingAction); registration.Register <TestMessage>(doNothingAction); }; // Then action.ShouldThrow <InvalidOperationException>("only one message handler delegate per message type should be allowed."); }
public void ShouldNotAllowSyncMethodsWithCancellationToken() { Action action = () => { try { var registration = new SingleMessageHandlerRegistration(); registration.RegisterCommandHandlersByAttribute(() => new TestAttributedSyncCommandHandlerWithCancellationToken(_outputHelper)); } catch (Exception ex) { _outputHelper.WriteLine(ex.ToString()); throw; } }; action.Should().Throw <InvalidOperationException>(); }
public void Setup() { // Delegator. var reg = new SingleMessageHandlerRegistration(); reg.Register <TestMessage>(handleMessage); _delegator = new MessageDelegator(reg.BuildMessageHandlerResolver()); // Mediatr. var requestHandler = new TestMediatrRequestHandler(); _mediator = new Mediator((t) => requestHandler, (t) => Enumerable.Empty <object>()); // CQRSLite. Router router = new Router(); router.RegisterHandler <TestCqrsliteCommand>(handleCqrsliteCommand); _commandSender = router; }
public void ShouldRegisterCommandAsyncHandler() { var commandHandler = new TestCommandHandler(_outputHelper); var registration = new SingleMessageHandlerRegistration(); registration.RegisterCommandHandler(() => commandHandler.AsCommandAsyncHandler <TestCommand>()); IMessageHandlerResolver resolver = registration.BuildMessageHandlerResolver(); MessageHandlerDelegate commandHandlerDelegate = resolver.ResolveMessageHandler(typeof(TestCommand)); commandHandlerDelegate.Should().NotBeNull(); // Delegate should invoke the actual command handler - TestCommandHandler. commandHandlerDelegate.Invoke(new TestCommand()); commandHandler.HandledCommands.Should().HaveCount(1); commandHandler.HasHandledCommand <TestCommand>().Should().BeTrue(); }
public async Task ShouldRegisterAllMethodsOfTypeThatIsMarkedWithCommandHandlerAttribute() { var commandHandler = new TestAttributedCommandHandler(_outputHelper); var registration = new SingleMessageHandlerRegistration(); registration.RegisterCommandHandlersByAttribute(() => commandHandler); IMessageHandlerResolver resolver = registration.BuildMessageHandlerResolver(); MessageHandlerDelegate commandHandlerDelegate = resolver.ResolveMessageHandler(typeof(TestCommand)); commandHandlerDelegate.Should().NotBeNull(); // Delegate should invoke the actual command handler - TestAttributedCommandHandler. await commandHandlerDelegate.Invoke(new TestCommand()); commandHandler.HandledCommands.Should().HaveCount(1); commandHandler.HasHandledCommand <TestCommand>().Should().BeTrue(); }
public async Task ShouldRegisterAllCommandHandlerAttributeMethods() { var commandHandler = new TestAttributedCommandHandler(_outputHelper); // Get methods marked with [CommandHandler] attribute. IEnumerable <CommandHandlerAttributeMethod> methods = CommandHandlerAttributeMethod.FromType(() => commandHandler); var registration = new SingleMessageHandlerRegistration(); registration.RegisterCommandHandlersByAttribute(methods); IMessageHandlerResolver resolver = registration.BuildMessageHandlerResolver(); MessageHandlerDelegate commandHandlerDelegate = resolver.ResolveMessageHandler(typeof(TestCommand)); commandHandlerDelegate.Should().NotBeNull(); // Delegate should invoke the actual command handler - TestAttributedCommandHandler. await commandHandlerDelegate.Invoke(new TestCommand()); commandHandler.HandledCommands.Should().HaveCount(1); commandHandler.HasHandledCommand <TestCommand>().Should().BeTrue(); }
public static void Begin(IServiceCollection services) { // Write-side repository. services.AddSingleton <IAggregateRootRepository <Match> >((serviceProvider) => new PublishingAggregateRootRepository <Match>(new InMemoryAggregateRootRepository <Match>(), serviceProvider.GetRequiredService <IDomainEventPublisher>()) ); // Domain event publisher. services.AddSingleton <IDomainEventPublisher, DomainEventPublisher>(); // Register command delegator. services.AddSingleton <CommandDelegator>(serviceProvider => { // Register command handlers. var commandHandlerRegistration = new SingleMessageHandlerRegistration(); commandHandlerRegistration.RegisterCommandHandler(() => new SubmitMovesCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Match> >())); commandHandlerRegistration.RegisterCommandHandler(() => new StartNewGameCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Match> >())); commandHandlerRegistration.RegisterCommandHandler(() => new EndGameCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Match> >())); commandHandlerRegistration.RegisterCommandHandler(() => new ProcessTurnCommandHandler(serviceProvider.GetRequiredService <IAggregateRootRepository <Match> >())); return(new CommandDelegator(commandHandlerRegistration.BuildMessageHandlerResolver())); }); }