コード例 #1
0
        static void Main()
        {
            Func <IFoo> getFoo              = () => new DummyFoo();
            var         module              = new CommandModule(getFoo);
            var         resolver            = new CommandHandlerResolver(module);
            var         commandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                // Use a string to decouple command name from the command clr type. This will ensure
                // refactoring, i.e. moving CommandThatHasASyncHandler or renaming it, won't change your http API.
                { "CommandThatHasASyncHandler", typeof(CommandThatHasASyncHandler) },

                // Can use typeof().Name if you are not concerned with backwards compat or versioning.
                { typeof(CommandThatHasAnAsyncHandler).Name, typeof(CommandThatHasAnAsyncHandler) },
            };
            var settings = new CommandHandlingSettings(resolver, commandMediaTypeMap);
            var commandHandlingMiddleware = CommandHandlingMiddleware.HandleCommands(settings);

            // 5. Add the middleware to your owin pipeline
            using (WebApp.Start("http://localhost:8080",
                                app =>
            {
                app.Use(commandHandlingMiddleware);
            }))
            {
                Console.WriteLine("Press any key");
            }
        }
コード例 #2
0
        private static void Main()
        {
            var resolver = new CommandHandlerResolver(new CommandModule());

            var commandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                { typeof(CommandThatIsAccepted).Name, typeof(CommandThatIsAccepted) },
                { typeof(CommandThatThrowsProblemDetailsException).Name, typeof(CommandThatThrowsProblemDetailsException) }
            };

            var settings = new CommandHandlingSettings(resolver, commandMediaTypeMap);

            var commandHandlingMiddleware = CommandHandlingMiddleware.HandleCommands(settings);

            using (WebApp.Start("http://*****:*****@"..\..\wwwroot")
                });
                app.UseStaticFiles(new StaticFileOptions
                {
                    RequestPath = new PathString("/cedarjs"),
                    FileSystem = new PhysicalFileSystem(@"..\..\..\Cedar.CommandHandling.Http.Js")
                });
                app.Map("/test/commands", commandsApp => commandsApp.Use(commandHandlingMiddleware));
            }))
            {
                Process.Start("http://localhost:8080/index.html");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey();
            }
        }
コード例 #3
0
        public async Task Should_invoke_predispatch_hook()
        {
            var          module           = new CommandHandlerModule();
            string       correlationId    = null;
            const string correlationIdKey = "CorrelationId";

            module.For <Command>().Handle((commandMessage, __) =>
            {
                correlationId = commandMessage.Metadata.Get <string>(correlationIdKey);
                return(Task.FromResult(0));
            });
            var settings = new CommandHandlingSettings(new CommandHandlerResolver(module))
            {
                OnPredispatch = (metadata, headers) =>
                {
                    var correlationIdHeader = headers.SingleOrDefault(kvp => kvp.Key == correlationIdKey);
                    if (correlationIdHeader.Value != null)
                    {
                        metadata[correlationIdKey] = correlationIdHeader.Value.SingleOrDefault();
                    }
                }
            };

            var midFunc = CommandHandlingMiddleware.HandleCommands(settings);

            using (var client = midFunc.CreateEmbeddedClient())
            {
                await client.PutCommand(new Command(), Guid.NewGuid(), customizeRequest : request =>
                {
                    request.Headers.Add(correlationIdKey, "cor-1");
                });

                correlationId.Should().Be("cor-1");
            }
        }
コード例 #4
0
        private static void Main()
        {
            var resolver = new CommandHandlerResolver(new CommandModule());
            var settings = new CommandHandlingSettings(resolver);
            var commandHandlingMiddleware = CommandHandlingMiddleware.HandleCommands(settings);

            using (WebApp.Start("http://*****:*****@"..\..\wwwroot")
                });
                app.UseStaticFiles(new StaticFileOptions
                {
                    RequestPath = new PathString("/cedarjs"),
                    FileSystem = new PhysicalFileSystem(@"..\..\..\Cedar.HttpCommandHandling.Js")
                });
                app.Map("/test/commands", commandsApp => commandsApp.Use(commandHandlingMiddleware));
            }))
            {
                Process.Start("http://localhost:8080/index.html");
                Console.WriteLine("Press any key to exit");
                Console.ReadKey();
            }
        }
コード例 #5
0
        public void Can_set_ParseMediaType()
        {
            var sut            = new CommandHandlingSettings(A.Fake <ICommandHandlerResolver>(), A.Fake <ResolveCommandType>());
            var parseMediaType = A.Fake <ParseMediaType>();

            sut.ParseMediaType = parseMediaType;

            sut.ParseMediaType.Should().Be(parseMediaType);
        }
コード例 #6
0
        public async Task Example_exception_handling()
        {
            var resolver = new CommandHandlerResolver(new CommandModule());
            var settings = new CommandHandlingSettings(resolver)
            {
                // 10. Specify the exception -> HttpProblemDetails mapper here
                MapProblemDetailsFromException = MapExceptionToProblemDetails
            };
            var middleware = CommandHandlingMiddleware.HandleCommands(settings);

            using (HttpClient client = middleware.CreateEmbeddedClient())
            {
                // 11. Handling standard exceptions.
                try
                {
                    await client.PutCommand(new CommandThatThrowsStandardException(), Guid.NewGuid());
                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine(ex.Message);
                }

                // 12. Handling explicit HttpProblemDetailsExceptions
                try
                {
                    await client.PutCommand(new CommandThatThrowsProblemDetailsException(), Guid.NewGuid());
                }
                catch (HttpProblemDetailsException <HttpProblemDetails> ex)
                {
                    Console.WriteLine(ex.ProblemDetails.Detail);
                    Console.WriteLine(ex.ProblemDetails.Status);
                }

                // 13. Handling mapped exceptions, same as #6
                try
                {
                    await client.PutCommand(new CommandThatThrowsMappedException(), Guid.NewGuid());
                }
                catch (HttpProblemDetailsException <HttpProblemDetails> ex)
                {
                    Console.WriteLine(ex.ProblemDetails.Detail);
                    Console.WriteLine(ex.ProblemDetails.Status);
                }

                // 14. Handling custom HttpProblemDetailExceptions
                try
                {
                    await client.PutCommand(new CommandThatThrowsCustomProblemDetailsException(), Guid.NewGuid());
                }
                catch (CustomHttpProblemDetailsException ex)
                {
                    Console.WriteLine(ex.ProblemDetails.Detail);
                    Console.WriteLine(ex.ProblemDetails.Status);
                    Console.WriteLine(ex.ProblemDetails.Name);
                }
            }
        }
コード例 #7
0
        public CommandHandlingFixture()
        {
            var module                  = CreateCommandHandlerModule();
            var handlerResolver         = new CommandHandlerResolver(module);
            var commandHandlingSettings = new CommandHandlingSettings(handlerResolver)
            {
                MapProblemDetailsFromException = CreateProblemDetails
            };

            _midFunc = CommandHandlingMiddleware.HandleCommands(commandHandlingSettings);
        }
コード例 #8
0
        public void Configuration(IAppBuilder app)
        {
            app.Map("/api/commands", builder =>
            {
                var moviesCommandModule    = TinyIoCContainer.Current.Resolve <MoviesCommandModule>();
                var directorsCommandModule = TinyIoCContainer.Current.Resolve <DirectorsCommandModule>();
                var resolver = new CommandHandlerResolver(moviesCommandModule, directorsCommandModule);
                var settings = new CommandHandlingSettings(resolver);

                var commandHandlingMiddleware = CommandHandlingMiddleware.HandleCommands(settings);
                builder.Use(commandHandlingMiddleware);
            });
        }
コード例 #9
0
        public void When_deserializer_throws_then_should_throw_HttpProblemDetailsException()
        {
            var sut = new CommandHandlingSettings(A.Fake <ICommandHandlerResolver>(), A.Fake <ResolveCommandType>());

            Action act = () =>
            {
                using (var reader = new StringReader("xyx"))
                {
                    sut.DeserializeCommand(reader, typeof(CommandHandlingSettingsTests));
                }
            };

            act.ShouldThrowExactly <HttpProblemDetailsException <HttpProblemDetails> >()
            .And.ProblemDetails.Status.Should().Be(400);
        }
コード例 #10
0
        public void When_custom_deserializer_throws_then_should_throw_HttpProblemDetailsException()
        {
            var sut = new CommandHandlingSettings(A.Fake <ICommandHandlerResolver>(), A.Fake <ResolveCommandType>())
            {
                DeserializeCommand = (_, __) => { throw new Exception(); }
            };

            Action act = () =>
            {
                using (var reader = new StringReader("xyx"))
                {
                    sut.DeserializeCommand(reader, typeof(CommandHandlingSettingsTests));
                }
            };

            act.ShouldThrow <HttpProblemDetailsException <HttpProblemDetails> >();
        }
コード例 #11
0
        public async Task Can_invoke_command_over_http()
        {
            // 1. Setup the middlware
            var resolver   = new CommandHandlerResolver(new CommandModule());
            var settings   = new CommandHandlingSettings(resolver);
            var middleware = CommandHandlingMiddleware.HandleCommands(settings);

            // 2. Create an embedded HttpClient. This allows invoking of the
            //    HttpPipeline in-memory without a server / listener.
            using (HttpClient client = middleware.CreateEmbeddedClient())
            {
                // 3. This is as close as you can get to simulating a real client call
                //    without needing real server.
                //    Can use this to do acceptance testing also.
                await client.PutCommand(new Command(), Guid.NewGuid());
            }
        }
コード例 #12
0
        static void Main()
        {
            Func <IFoo> getFoo   = () => new DummyFoo();
            var         resolver = new CommandHandlerResolver(new CommandModule(getFoo));
            var         settings = new CommandHandlingSettings(resolver);
            var         commandHandlingMiddleware = CommandHandlingMiddleware.HandleCommands(settings);

            // 5. Add the middleware to your owin pipeline
            using (WebApp.Start("http://localhost:8080",
                                app =>
            {
                app.Use(commandHandlingMiddleware);
            }))
            {
                Console.WriteLine("Press any key");
            }
        }
コード例 #13
0
        public CommandHandlingFixture()
        {
            var module          = CreateCommandHandlerModule();
            var handlerResolver = new CommandHandlerResolver(module);

            CommandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                { typeof(Command).Name.ToLowerInvariant(), typeof(Command) },
                { typeof(CommandThatThrowsStandardException).Name.ToLowerInvariant(), typeof(CommandThatThrowsStandardException) },
                { typeof(CommandThatThrowsProblemDetailsException).Name.ToLowerInvariant(), typeof(CommandThatThrowsProblemDetailsException) },
                { typeof(CommandThatThrowsMappedException).Name.ToLowerInvariant(), typeof(CommandThatThrowsMappedException) },
                { typeof(CommandThatThrowsCustomProblemDetailsException).Name.ToLowerInvariant(), typeof(CommandThatThrowsCustomProblemDetailsException) }
            };
            var commandHandlingSettings = new CommandHandlingSettings(handlerResolver, CommandMediaTypeMap)
            {
                MapProblemDetailsFromException = CreateProblemDetails
            };

            _midFunc = CommandHandlingMiddleware.HandleCommands(commandHandlingSettings);
        }
コード例 #14
0
        public async Task Can_invoke_command_over_http()
        {
            var resolver            = new CommandHandlerResolver(new CommandModule());
            var commandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                { typeof(Command).FullName.ToLower(), typeof(Command) }
            };

            // 1. Create the serializer
            var jsonSerializer = new JsonSerializer();
            var settings       = new CommandHandlingSettings(resolver, commandMediaTypeMap)
            {
                // 2. Customize the deserialization
                DeserializeCommand = (commandReader, type) =>
                {
                    using (var reader = new JsonTextReader(commandReader))
                    {
                        return(jsonSerializer.Deserialize(reader, type));
                    }
                }
            };
            var middleware = CommandHandlingMiddleware.HandleCommands(settings);

            // 3. Customize the serialization
            SerializeCommand serializeCommand = (writer, command) =>
            {
                jsonSerializer.Serialize(writer, command);
            };

            // 3. Create an embedded HttpClient. This allows invoking of the
            //    HttpPipeline in-memory without a server / listener.
            using (HttpClient client = middleware.CreateEmbeddedClient())
            {
                // 3. This is as close as you can get to simulating a real client call
                //    without needing real server.
                //    Can use this to do acceptance testing also.
                await client.PutCommand(new Command(), Guid.NewGuid(), commandMediaTypeMap, serializeCommand : serializeCommand);
            }
        }
コード例 #15
0
        public void When_custom_deserializer_throws_HttpProblemDetailsException_then_it_should_propagate()
        {
            var expected = new HttpProblemDetailsException <HttpProblemDetails>(new HttpProblemDetails());
            var sut      = new CommandHandlingSettings(A.Fake <ICommandHandlerResolver>(), A.Fake <ResolveCommandType>())
            {
                DeserializeCommand = (_, __) => { throw expected; }
            };

            Exception thrown = null;

            try
            {
                using (var reader = new StringReader("xyx"))
                {
                    sut.DeserializeCommand(reader, typeof(CommandHandlingSettingsTests));
                }
            }
            catch (Exception ex)
            {
                thrown = ex;
            }

            thrown.ShouldBe(expected);
        }
コード例 #16
0
        static void Main()
        {
            var resolver = new CommandHandlerResolver(new CommandModule());

            // 1. Create a map to resolve types from a key.
            // This could of course be done with reflection + conventions.
            // For the sake of example, we're going to be explict.
            var commandMap = new[]
            {
                typeof(CommandVersioning.V1.Command),
                typeof(CommandVersioning.V2.Command),
            }.ToDictionary(t => t.Name.ToLowerInvariant(), t => t);

            var resolveCommandType = new ResolveCommandType((typeName, version) =>
            {
                // 2. In this example, we're not handling unversioned commands. You
                // may of course handle them.
                if (version == null)
                {
                    return(null); // 3. Return null if the command type can't be resolved.
                }

                // 4. Here we're just converting the typeName to a key that matches our
                // convetion.
                var typeNameSegments = typeName.Split('.').ToList();                // my.type.name -> { my, type, name }
                typeNameSegments.Insert(typeNameSegments.Count - 1, "v" + version); // { my, type, name } -> { my, type, vX, name }
                typeName = string.Join(".", typeNameSegments);                      // { my, type, vX, name } -> my.type.vX.name

                Type commandType;
                commandMap.TryGetValue(typeName, out commandType);
                return(commandType);
            });

            // 5. CommandHandlingSettings has a contructor overload to pass in the command type resolver.
            var settings = new CommandHandlingSettings(resolver, resolveCommandType);
        }