// 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 Sample", Version = "v1" }); }); // Repository. services.AddSingleton <IProductRepository, InMemoryProductRepository>(); // Register command handlers. SetupContainerRegistration(services); SetupAttributeRegistration(services); SetupBasicRegistration(services); // Command dispatcher. services.AddSingleton <ICommandAsyncDispatcher>(serviceProvider => { // Wrap ASP NET Core service provider in a resolver. ICommandHandlerResolver containerResolver = new ContainerCommandAsyncHandlerResolver(new AspNetCoreServiceProviderAdapter(serviceProvider)); // CommandHandlerAttributeRegistration implements ICommandHandlerResolver. ICommandHandlerResolver attributeResolver = serviceProvider.GetRequiredService <CommandHandlerAttributeRegistration>(); // CommandHandlerRegistration implements ICommandHandlerResolver. ICommandHandlerResolver basicResolver = serviceProvider.GetRequiredService <CommandHandlerRegistration>(); // Merge all resolvers. var compositeResolver = new CompositeCommandHandlerResolver(new ICommandHandlerResolver[] { // Order is followed when resolving handlers. containerResolver, attributeResolver, basicResolver }, (ex) => true); // Handle any exception if exception is thrown from a resolver, we can return true to allow the dispatcher to proceed to next resolver. return(new CommandDispatcher(compositeResolver)); }); services.AddMvc(); }
public async Task Should_Invoke_Registered_Command_Handler_With_Composite_Resolver() { var commandHandler = new TestCommandHandler(_outputHelper); var container = new Container(); container.Register <ICommandHandler <DoSomethingCommand> >(() => commandHandler, Lifestyle.Singleton); container.Register <ICommandAsyncHandler <DoSomethingWithCancellationCommand> >(() => commandHandler, Lifestyle.Singleton); var containerAdapter = new SimpleInjectorContainerAdapter(container); var containerAsyncHandlerResolver = new ContainerCommandAsyncHandlerResolver(containerAdapter); var containerHandlerResolver = new ContainerCommandHandlerResolver(containerAdapter); Func <Exception, bool> exceptionHandler = (ex) => { var exception = ex as NoCommandHandlerResolvedException; if (exception != null) { _outputHelper.WriteLine($"Ignoring encountered exception while trying to resolve command handler for {exception.CommandType.Name}..."); // Notify as handled if no command handler is resolved from other resolvers. return(true); } return(false); }; var compositeResolver = new CompositeCommandHandlerResolver(new List <ICommandHandlerResolver>() { containerAsyncHandlerResolver, containerHandlerResolver }, exceptionHandler); // Pass in an exception handler. var dispatcher = new CommandDispatcher(compositeResolver); // Composite resolver await dispatcher.DispatchAsync(new DoSomethingCommand()); await dispatcher.DispatchAsync(new DoSomethingWithCancellationCommand()); Assert.Equal(2, commandHandler.HandledCommands.Count); Assert.Contains(commandHandler.HandledCommands, c => c is DoSomethingCommand); Assert.Contains(commandHandler.HandledCommands, c => c is DoSomethingWithCancellationCommand); }