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 settings = new CommandHandlingSettings(
                resolver,
                new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter()));
            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();
            }
        }
예제 #3
0
        /// <summary>
        ///     Creats a command handling middlware.
        /// </summary>
        /// <param name="settings">Settings to configure the middleware.</param>
        /// <returns>An owin middleware function (MidFunc) that represents </returns>
        public static MidFunc HandleCommands(CommandHandlingSettings settings)
        {
            Condition.Requires(settings, "settings").IsNotNull();

            return(next =>
            {
                var webApiConfig = ConfigureWebApi(settings);
                var appBuilder = new AppBuilder();
                appBuilder
                .UseWebApi(webApiConfig)
                .Run(ctx => next(ctx.Environment));
                return appBuilder.Build();
            });
        }
        /// <summary>
        ///     Creats a command handling middlware.
        /// </summary>
        /// <param name="settings">Settings to configure the middleware.</param>
        /// <returns>An owin middleware function (MidFunc) that represents </returns>
        public static MidFunc HandleCommands(CommandHandlingSettings settings)
        {
            Ensure.That(settings, "settings").IsNotNull();

            return next =>
            {
                var webApiConfig = ConfigureWebApi(settings);
                var appBuilder = new AppBuilder();
                appBuilder
                    .UseWebApi(webApiConfig)
                    .Run(ctx => next(ctx.Environment));
                return appBuilder.Build();
            };
        }
        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);
        }
예제 #6
0
        public CommandHandlerController(CommandHandlingSettings settings)
        {
            _settings = settings;

            var temp = _settings.OnPredispatch ?? ((_, __) => { });

            _predispatch = (metadata, headers) =>
            {
                metadata[CommandMessageExtensions.UserKey] = (User as ClaimsPrincipal) ?? new ClaimsPrincipal(new ClaimsIdentity());
                try
                {
                    temp(metadata, headers);
                }
                catch (Exception ex)
                {
                    Logger.ErrorException("Exception occured invoking the Predispatch hook", ex);
                }
            };
        }
        public async Task Can_invoke_command_over_http()
        {
            // 1. Setup the middlware
            var resolver = new CommandHandlerResolver(new CommandModule());
            var commandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                { typeof(Command).FullName.ToLower(), typeof(Command) }
            };
            var settings = new CommandHandlingSettings(resolver, commandMediaTypeMap);
            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(), commandMediaTypeMap);
            }
        }
        private static HttpConfiguration ConfigureWebApi(CommandHandlingSettings settings)
        {
            var container = new TinyIoCContainer();
            container.Register(settings);
            container.Register(new RecyclableMemoryStreamManager());

            var config = new HttpConfiguration
            {
                DependencyResolver = new TinyIoCDependencyResolver(container)
            };
            config.Services.Replace(typeof(IHttpControllerTypeResolver), new CommandHandlingHttpControllerTypeResolver());
            config.Filters.Add(new HttpProblemDetailsExceptionFilterAttribute(settings.MapProblemDetailsFromException));
            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
            config.MapHttpAttributeRoutes();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/problem+json"));
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
                new CamelCasePropertyNamesContractResolver();
            config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.None;

            return config;
        }
        public CommandHandlerController(
            CommandHandlingSettings settings,
            RecyclableMemoryStreamManager recyclableMemoryStreamManager)
        {
            _settings = settings;
            _recyclableMemoryStreamManager = recyclableMemoryStreamManager;

            var temp = _settings.OnPredispatch ?? ((_, __) => { });
            _predispatch = (metadata, headers) =>
            {
                metadata[CommandMessageExtensions.UserKey] = (User as ClaimsPrincipal) ?? new ClaimsPrincipal(new ClaimsIdentity());
                try
                {
                    temp(metadata, headers);
                }
                catch(Exception ex)
                {
                    s_logger.ErrorException("Exception occured invoking the Predispatch hook", ex);
                }
            };
        }
예제 #10
0
        private static HttpConfiguration ConfigureWebApi(CommandHandlingSettings settings)
        {
            var container = new TinyIoCContainer();

            container.Register(settings);

            var config = new HttpConfiguration
            {
                DependencyResolver = new TinyIoCDependencyResolver(container)
            };

            config.Services.Replace(typeof(IHttpControllerTypeResolver), new CommandHandlingHttpControllerTypeResolver());
            config.Filters.Add(new HttpProblemDetailsExceptionFilterAttribute(settings.MapProblemDetailsFromException));
            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
            config.MapHttpAttributeRoutes();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/problem+json"));
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
                new CamelCasePropertyNamesContractResolver();
            config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.None;

            return(config);
        }
        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 commandMediaTypeMap = new CommandMediaTypeMap(new CommandMediaTypeWithQualifierVersionFormatter())
            {
                { typeof(Command).Name.ToLower(), typeof(Command) }
            };
            var settings = new CommandHandlingSettings(new CommandHandlerResolver(module), commandMediaTypeMap)
            {
                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(), commandMediaTypeMap, customizeRequest: request =>
                {
                    request.Headers.Add(correlationIdKey, "cor-1");
                });

                correlationId.Should().Be("cor-1");
            }
        }
        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);
            }
        }
        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.Should().Be(expected);
        }