public QueryInfo(Type queryType, ICqrsOptions options) { QueryType = queryType; IsAsync = queryType.IsAssignableToGenericType(typeof(IAsyncQuery <>)); ResultType = DetermineResultTypes(queryType, IsAsync).Single(); HttpMethods = queryType .GetCustomAttributes(true) .OfType <HttpMethodAttribute>() .SelectMany(x => x.HttpMethods) .Distinct() .ToArray(); if (!HttpMethods.Any()) { HttpMethods = options.DefaultQueryHttpMethods; } if (IsAsync) { QueryHandlerType = typeof(IAsyncQueryHandler <,>).MakeGenericType(QueryType, ResultType); } else { QueryHandlerType = typeof(IQueryHandler <,>).MakeGenericType(QueryType, ResultType); } }
private async Task HandleCommand(HttpContext context, ICqrsOptions options) { var path = options.GetCommandPath(context.Request.Path.Value); if (!_commandTypes.Value.ContainsKey(path)) { throw new CommandNotFoundException($"Command '{path}' not found"); } dynamic result = null; var info = _commandTypes.Value[path]; var exposeAttribute = info.CommandType.GetCustomAttribute <ExposeAttribute>(); var formatter = _registry.GetFormatter(exposeAttribute.Formatter); var deserializeMethod = _deserializeMethods.GetOrAdd(info.CommandType, (t) => { var mi = CreateDeserializeLambdaMethodInfo.MakeGenericMethod(t); return(mi.Invoke(null, null)); }); dynamic command = await deserializeMethod(formatter, context.Request); dynamic handler = _container.GetInstance(info.CommandHandlerType); context.Items[ContextKey] = new CqrsContext(context.Request.Path.Value, path, CqrsType.Command, info.CommandHandlerType); if (info.IsGeneric) { if (info.IsAsync) { result = await handler.HandleAsync(command, context.RequestAborted); } else { result = handler.Handle(command); } } else { if (info.IsAsync) { await handler.HandleAsync(command, context.RequestAborted); } else { handler.Handle(command); } } CloseSession(); var json = result is string?result : await formatter.SerializeAsync(result, context.Request); context.Response.ContentType = formatter.ContentType; context.Response.StatusCode = (int)HttpStatusCode.OK; await HttpResponseWritingExtensions.WriteAsync(context.Response, json, context.RequestAborted); }
private async Task HandleQuery(HttpContext context, ICqrsOptions options) { var path = context.Request.Path.Value; var method = context.Request.Method; if (!_queryTypes.Value.ContainsKey($"{method} {path}")) { throw new QueryNotFoundException($"Query '{method} {path}' not found"); } var info = _queryTypes.Value[$"{method} {path}"]; var exposeAttribute = info.QueryType.GetCustomAttribute <ExposeAttribute>(); var formatter = _registry.GetFormatter(exposeAttribute.Formatter); var deserializeMethod = _deserializeMethods.GetOrAdd(info.QueryType, (t) => { var mi = CreateDeserializeLambdaMethodInfo.MakeGenericMethod(t); return(mi.Invoke(null, null)); }); var query = await deserializeMethod(formatter, context.Request); dynamic handler = options.GetInstance(info.QueryHandlerType); context.Items[IOwinContextExtensions.ContextKey] = new CqrsContext(context.Request.Path.Value, path, CqrsType.Command, info.QueryHandlerType); dynamic result; if (info.IsAsync) { result = await handler.HandleAsync(query, context.RequestAborted); } else { result = handler.Handle(query); } string json = null; if (result != null) { json = result is string?result : await formatter.SerializeAsync(result, context.Request); } context.Response.ContentType = formatter.ContentType; if (json != null) { context.Response.StatusCode = (int)HttpStatusCode.OK; await context.Response.WriteAsync(json, context.RequestAborted); } else { context.Response.StatusCode = (int)HttpStatusCode.NoContent; } }
public QueryHandlerMiddleware(CqrsFormatterRegistry registry, ICqrsOptions options) { _registry = registry; _options = options; _queryTypes = new Lazy <Dictionary <string, QueryInfo> >(() => options.GetQueryTypes() .SelectMany(x => x.HttpMethods, (ci, method) => new { QueryInfo = ci, HttpMethod = method }) .ToDictionary( keySelector: (x) => $"{x.HttpMethod} {options.GetQueryPath(x.QueryInfo)}", elementSelector: x => x.QueryInfo, comparer: StringComparer.OrdinalIgnoreCase)); }
private async Task HandleCommand(HttpContext context, ICqrsOptions options) { var path = options.GetCommandPath(context.Request.Path.Value); if (!_commandTypes.ContainsKey(path)) { throw new CommandNotFoundException($"Command '{path}' not found"); } dynamic result = null; var info = _commandTypes[path]; var commandData = await new StreamReader(context.Request.Body).ReadToEndAsync(); dynamic command = DeserializeCommand(commandData, info.CommandType); dynamic handler = _container.GetInstance(info.CommandHandlerType); context.Items[ContextKey] = new CqrsContext(context.Request.Path.Value, path, CqrsType.Command, info.CommandHandlerType); if (info.IsGeneric) { if (info.IsAsync) { result = await handler.HandleAsync(command, context.RequestAborted); } else { result = handler.Handle(command); } } else { if (info.IsAsync) { await handler.HandleAsync(command, context.RequestAborted); } else { handler.Handle(command); } } CloseSession(); var json = result is string?result : JsonConvert.SerializeObject(result, _jsonSerializerSettings); context.Response.ContentType = ContentType; context.Response.StatusCode = (int)HttpStatusCode.OK; await HttpResponseWritingExtensions.WriteAsync(context.Response, json, context.RequestAborted); }
public CommandInfo(Type commandType, ICqrsOptions options) { CommandType = commandType; IsAsync = typeof(IAsyncCommand).IsAssignableFrom(commandType) || commandType.GetTypeInfo().IsAssignableToGenericType(typeof(IAsyncCommand <>)); IsGeneric = commandType.GetTypeInfo().IsAssignableToGenericType(typeof(ICommand <>)) || commandType.GetTypeInfo().IsAssignableToGenericType(typeof(IAsyncCommand <>)); GenericTypes = new[] { CommandType }; HttpMethods = commandType .GetCustomAttributes(true) .OfType <HttpMethodAttribute>() .SelectMany(x => x.HttpMethods) .Distinct() .ToArray(); if (!HttpMethods.Any()) { HttpMethods = options.DefaultCommandHttpMethods; } if (IsGeneric) { ResultType = DetermineResultTypes(commandType, IsAsync).Single(); GenericTypes = GenericTypes.Union(new[] { ResultType }).ToArray(); } if (IsAsync) { if (IsGeneric) { CommandHandlerType = typeof(IAsyncCommandHandler <,>).MakeGenericType(GenericTypes); } else { CommandHandlerType = typeof(IAsyncCommandHandler <>).MakeGenericType(GenericTypes); } } else { if (IsGeneric) { CommandHandlerType = typeof(ICommandHandler <,>).MakeGenericType(GenericTypes); } else { CommandHandlerType = typeof(ICommandHandler <>).MakeGenericType(GenericTypes); } } }
public CqrsMiddleware(Container container, ICqrsOptions options) { _container = container; _options = options; _jsonSerializerSettings = options.GetJsonSerializerSettings(); _commandTypes = options.GetCommandTypes().ToDictionary( keySelector: options.GetCommandKey, elementSelector: type => type, comparer: StringComparer.OrdinalIgnoreCase); _queryTypes = options.GetQueryTypes().ToDictionary( keySelector: options.GetQueryKey, elementSelector: info => info, comparer: StringComparer.OrdinalIgnoreCase); }
public CqrsMiddleware(Container container, CqrsFormatterRegistry registry, ICqrsOptions options) { _container = container; _registry = registry; _options = options; _commandTypes = new Lazy <Dictionary <string, CommandInfo> >(() => options.GetCommandTypes().ToDictionary( keySelector: options.GetCommandKey, elementSelector: type => type, comparer: StringComparer.OrdinalIgnoreCase)); _queryTypes = new Lazy <Dictionary <string, QueryInfo> >(() => options.GetQueryTypes().ToDictionary( keySelector: options.GetQueryKey, elementSelector: info => info, comparer: StringComparer.OrdinalIgnoreCase)); }
private async Task HandleQuery(HttpContext context, ICqrsOptions options) { var path = options.GetQueryPath(context.Request.Path.Value); if (!_queryTypes.ContainsKey(path)) { throw new QueryNotFoundException($"Query '{path}' not found"); } // GET operations get their data through the query string, while POST operations expect a JSON // object being put in the body. var queryData = context.Request.Method == HttpMethod.Get.Method ? SerializationHelpers.ConvertQueryStringToJson(context.Request.QueryString.Value) : await new StreamReader(context.Request.Body).ReadToEndAsync(); var info = _queryTypes[path]; var query = DeserializeQuery(queryData, info.QueryType); dynamic handler = _container.GetInstance(info.QueryHandlerType); context.Items[ContextKey] = new CqrsContext(context.Request.Path.Value, path, CqrsType.Command, info.QueryHandlerType); dynamic result; if (info.IsAsync) { result = await handler.HandleAsync(query, context.RequestAborted); } else { result = handler.Handle(query); } var json = result is string?result : JsonConvert.SerializeObject(result, _jsonSerializerSettings); context.Response.ContentType = ContentType; context.Response.StatusCode = (int)HttpStatusCode.OK; await HttpResponseWritingExtensions.WriteAsync(context.Response, json, context.RequestAborted); }