private string GetUniqueId(CommandHandlerContext filterContext) { Contract.Requires(filterContext != null); Contract.Requires(filterContext.Descriptor != null); StringBuilder uniqueIdBuilder = new StringBuilder(); // Unique ID of the handler description AppendPartToUniqueIdBuilder(uniqueIdBuilder, filterContext.Descriptor.HandlerType); if (this.VaryByUser && filterContext.User != null) { AppendPartToUniqueIdBuilder(uniqueIdBuilder, filterContext.User.Identity.Name); } // Unique ID from the VaryByParams settings, if any uniqueIdBuilder.Append(this.GetUniqueIdFromCommand(filterContext)); // The key is typically too long to be useful, so we use a cryptographic hash // as the actual key (better randomization and key distribution, so small vary // values will generate dramtically different keys). using (SHA256 sha = SHA256.Create()) { return(Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(uniqueIdBuilder.ToString())))); } }
public IEnumerable <dynamic> Handle(CommandHandlerContext context) { dynamic closed = new ExpandoObject(); closed.id = context.State.id; yield return(closed); }
public ActionInvoker(CommandHandlerContext context, CancellationToken cancellationToken, ServicesContainer services) { Contract.Requires(services != null); this.context = context; this.cancellationToken = cancellationToken; this.services = services; }
public IEnumerable <dynamic> Handle(CommandHandlerContext context) { dynamic deposited = new ExpandoObject(); deposited.id = context.State.id; deposited.amount = context.Command.amount; yield return(deposited); }
public IEnumerable <dynamic> Handle(CommandHandlerContext context) { dynamic withdrawn = new ExpandoObject(); withdrawn.id = context.State.id; withdrawn.amount = context.Command.amount; yield return(withdrawn); }
/// <summary> /// Invokes a <see cref="ICommandHandler"/>. /// </summary> /// <param name="context">The context of invocation.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task"/> of HandlerResponse.</returns> public virtual Task <HandlerResponse> InvokeHandlerAsync(CommandHandlerContext context, CancellationToken cancellationToken) { if (context == null) { throw Error.ArgumentNull("context"); } return(InvokeActionAsyncCore(context, cancellationToken)); }
public IEnumerable <dynamic> Handle(CommandHandlerContext context) { dynamic created = new ExpandoObject(); created.id = context.State.id; created.owner = context.Command.owner; yield return(created); }
public void WhenExecutedFilterVaryByUserThenCacheIsUpdated() { // Arrange CacheAttribute filter = this.CreateAttribute(new MemoryCache("test")); filter.Duration = 10; filter.VaryByUser = true; filter.VaryByParams = CacheAttribute.VaryByParamsNone; CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1); CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor); context1.User = new GenericPrincipal(new GenericIdentity("user1"), null); CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null); executedContext1.Response = new HandlerResponse(request1, "result1"); SimpleCommand command2 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2); CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor); context2.User = new GenericPrincipal(new GenericIdentity("user2"), null); CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null); executedContext2.Response = new HandlerResponse(request2, "result2"); SimpleCommand command3 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3); CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor); context3.User = new GenericPrincipal(new GenericIdentity("user1"), null); CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null); executedContext3.Response = new HandlerResponse(request3, "result3"); // Act filter.OnCommandExecuting(context1); filter.OnCommandExecuted(executedContext1); filter.OnCommandExecuting(context2); filter.OnCommandExecuted(executedContext2); filter.OnCommandExecuting(context3); filter.OnCommandExecuted(executedContext3); // Assert Assert.Equal("result1", executedContext1.Response.Value); Assert.Equal("result2", executedContext2.Response.Value); Assert.Equal("result1", executedContext3.Response.Value); }
private static async Task <HandlerResponse> InvokeActionAsyncCore(CommandHandlerContext context, CancellationToken cancellationToken) { Contract.Requires(context != null); Contract.Requires(context.Descriptor != null); CommandHandlerDescriptor handlerDescriptor = context.Descriptor; try { object result = await handlerDescriptor.ExecuteAsync(context, cancellationToken); // This is cached in a local for performance reasons. ReturnType is a virtual property on CommandHandlerDescriptor, // or else we'd want to cache this as part of that class. bool isDeclaredTypeHandlerResult = typeof(ICommandHandlerResult).IsAssignableFrom(handlerDescriptor.ReturnType); if (result == null && isDeclaredTypeHandlerResult) { // If the return type of the action descriptor is IHandlerResult, it's not valid to return null throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_NullHandlerResult); } if (isDeclaredTypeHandlerResult || handlerDescriptor.ReturnType == typeof(object)) { ICommandHandlerResult actionResult = result as ICommandHandlerResult; if (actionResult == null && isDeclaredTypeHandlerResult) { // If the return type of the action descriptor is IHandlerResult, it's not valid to return an // object that doesn't implement IHandlerResult throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_InvalidHandlerResult, result.GetType()); } if (actionResult != null) { HandlerResponse response = await actionResult.ExecuteAsync(cancellationToken); if (response == null) { throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_NullHandlerResponse); } HandlerResponse.EnsureResponseHasRequest(response, context.Request); return(response); } } // This is a non-IHandlerResult, so run the converter return(handlerDescriptor.ResultConverter.Convert(context, result)); } catch (HandlerResponseException handlerResponseException) { HandlerResponse response = handlerResponseException.Response; HandlerResponse.EnsureResponseHasRequest(response, context.Request); return(response); } }
public HandlerResponse Convert(CommandHandlerContext context, object handlerResult) { if (context == null) { throw Error.ArgumentNull("context"); } Contract.Assert(handlerResult == null); return(context.Request.CreateResponse()); }
public CommandHandlerFilterResult(CommandHandlerContext context, ServicesContainer services, ICommandHandlerFilter[] filters) { Contract.Requires(context != null); Contract.Requires(services != null); Contract.Requires(filters != null); this.context = context; this.services = services; this.filters = filters; }
private async Task <HandlerResponse> ExecuteHandlerFilterAsyncCore(CommandHandlerContext handlerContext, CancellationToken cancellationToken, Func <Task <HandlerResponse> > continuation) { await this.OnCommandExecutingAsync(handlerContext, cancellationToken); if (handlerContext.Response != null) { return(handlerContext.Response); } return(await this.CallOnHandlerExecutedAsync(handlerContext, cancellationToken, continuation)); }
Task <HandlerResponse> ICommandHandlerFilter.ExecuteHandlerFilterAsync(CommandHandlerContext handlerContext, CancellationToken cancellationToken, Func <Task <HandlerResponse> > continuation) { return(this.TraceWriter.TraceBeginEndAsync( handlerContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info, this.InnerActionFilter.GetType().Name, ExecuteActionFilterAsyncMethodName, beginTrace: null, execute: () => this.InnerActionFilter.ExecuteHandlerFilterAsync(handlerContext, cancellationToken, continuation), endTrace: null, errorTrace: null)); }
public virtual Task OnCommandExecutingAsync(CommandHandlerContext handlerContext, CancellationToken cancellationToken) { try { this.OnCommandExecuting(handlerContext); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } return(TaskHelpers.Completed()); }
/// <summary> /// Executes the filter handler asynchronously. /// </summary> /// <param name="handlerContext">The handler context.</param> /// <param name="cancellationToken">The cancellation token assigned for this task.</param> /// <param name="continuation">The delegate function to continue after the handler method is invoked.</param> /// <returns>The newly created task for this operation.</returns> public Task <HandlerResponse> ExecuteHandlerFilterAsync(CommandHandlerContext handlerContext, CancellationToken cancellationToken, Func <Task <HandlerResponse> > continuation) { if (handlerContext == null) { throw Error.ArgumentNull("handlerContext"); } if (continuation == null) { throw Error.ArgumentNull("continuation"); } return(this.ExecuteHandlerFilterAsyncCore(handlerContext, cancellationToken, continuation)); }
public ExceptionFilterResult(CommandHandlerContext context, IExceptionFilter[] filters, IExceptionLogger exceptionLogger, IExceptionHandler exceptionHandler, ICommandHandlerResult innerResult) { Contract.Requires(context != null); Contract.Requires(filters != null); Contract.Requires(exceptionLogger != null); Contract.Requires(exceptionHandler != null); Contract.Requires(innerResult != null); this.context = context; this.filters = filters; this.exceptionLogger = exceptionLogger; this.exceptionHandler = exceptionHandler; this.innerResult = innerResult; }
public void WhenExecutedFilterVaryByParamsSetIncorrectlyThenCacheIsAlwaysUsed() { // Arrange CacheAttribute filter = this.CreateAttribute(new MemoryCache("test")); filter.Duration = 10; filter.VaryByParams = "XXXX"; CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1); CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor); CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null); executedContext1.SetResponse("result1"); SimpleCommand command2 = new SimpleCommand { Property1 = 2, Property2 = "test2" }; CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2); CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor); CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null); executedContext2.SetResponse("result2"); SimpleCommand command3 = new SimpleCommand { Property1 = 2, Property2 = "test3" }; CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3); CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor); CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null); executedContext3.SetResponse("result3"); // Act filter.OnCommandExecuting(context1); filter.OnCommandExecuted(executedContext1); filter.OnCommandExecuting(context2); filter.OnCommandExecuted(executedContext2); filter.OnCommandExecuting(context3); filter.OnCommandExecuted(executedContext3); // Assert Assert.Equal("result1", executedContext1.Response.Value); Assert.Equal("result1", executedContext2.Response.Value); Assert.Equal("result1", executedContext3.Response.Value); }
public void WhenCreatingInstanceThenPropertiesAreDefined() { // Arrange CommandHandlerContext preContext = new CommandHandlerContext(); Exception exception = new Exception(); ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception); // Act CommandHandlerExecutedContext context = new CommandHandlerExecutedContext(preContext, exceptionInfo); // Assert Assert.Null(context.Response); Assert.NotNull(context.ExceptionInfo.SourceException); Assert.Same(context.ExceptionInfo.SourceException, exception); }
public void WhenSettingResultThenResultIsDefined() { // Arrange CommandHandlerContext preContext = new CommandHandlerContext(); Exception exception = new Exception(); ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception); CommandHandlerExecutedContext context = new CommandHandlerExecutedContext(preContext, exceptionInfo); var value = "test"; // Act context.Response = context.Request.CreateResponse("test"); // Assert Assert.Equal(context.Response.Value, value); }
public void Add_Success() { //Arrange _commandHandlerActivatorMock.Setup(_createExpression). Returns(new object()); var activator = _commandHandlerActivatorMock.Object; var registry = new CommandHandlerRegistry(activator); var context = new CommandHandlerContext(); //Act registry.Add(context); //Assert _commandHandlerActivatorMock.Verify(_createExpression); }
public void WhenCreatingInstanceWithDefaultCtorThenPropertiesAreDefined() { // Arrange // Act CommandHandlerContext context = new CommandHandlerContext(); // Assert Assert.Null(context.Configuration); Assert.Null(context.Request); Assert.Null(context.Command); Assert.Null(context.Descriptor); Assert.Null(context.Request); Assert.NotNull(context.Items); Assert.Equal(0, context.Items.Count); }
// Generate a unique ID of normalized key names + key values private string GetUniqueIdFromCommand(CommandHandlerContext filterContext) { Contract.Requires(filterContext != null); Contract.Requires(filterContext.Configuration != null); Contract.Requires(filterContext.Command != null); IModelFlattener flattener = filterContext.Configuration.Services.GetModelFlattener(); ModelMetadataProvider metadataProvider = filterContext.Configuration.Services.GetModelMetadataProvider(); ModelDictionary parameters = flattener.Flatten(filterContext.Command, filterContext.Command.GetType(), metadataProvider, string.Empty); IEnumerable <string> keys = SplitVaryByParam(this.VaryByParams); keys = (keys ?? parameters.Keys).OrderBy(key => key, StringComparer.Ordinal); return(CreateUniqueId(keys.Concat(keys.Select(key => parameters.ContainsKey(key) ? parameters[key] : null)))); }
private dynamic ExecuteCore(ICommand command, CommandHandlerContext context) { try { return(((dynamic)this.Inner).Handle(command, context)); } finally { IDisposable disposable = this.Inner as IDisposable; if (disposable != null) { this.request.UnregisterForDispose(disposable, true); } } }
/// <summary> /// Converts the result of an handler to an instance of <see cref="HandlerResponse"/>. /// </summary> /// <param name="context">The conversion context.</param> /// <param name="handlerResult">The result to convert.</param> /// <returns>A <see cref="HandlerResponse"/>.</returns> /// <exception cref="InvalidOperationException"></exception> public HandlerResponse Convert(CommandHandlerContext context, object handlerResult) { if (context == null) { throw Error.ArgumentNull("context"); } HandlerResponse response = (HandlerResponse)handlerResult; if (response == null) { throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_NullHandlerResponse); } HandlerResponse.EnsureResponseHasRequest(response, context.Request); return(response); }
public void WhenInvokingFilterWithExceptionThenTransactionRollbacks() { // Arrange TransactionFilterAttribute filter = new TransactionFilterAttribute(); CommandHandlerContext executingContext = new CommandHandlerContext(); Exception exception = new Exception(); ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception); CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(executingContext, exceptionInfo); // Act filter.OnCommandExecuting(executingContext); Transaction transaction = Transaction.Current.Clone(); filter.OnCommandExecuted(executedContext); // Assert Assert.Equal(TransactionStatus.Aborted, transaction.TransactionInformation.Status); }
public void WhenExecutingFilterThenCacheIsChecked() { // Arrange CacheAttribute filter = this.CreateAttribute(); SimpleCommand command = new SimpleCommand { Property1 = 12, Property2 = "test" }; CommandHandlerRequest request = new CommandHandlerRequest(this.config, command); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); CommandHandlerContext context = new CommandHandlerContext(request, descriptor); // Act filter.OnCommandExecuting(context); // Assert this.cache.Verify(c => c.Get(It.IsAny <string>(), It.IsAny <string>()), Times.Once()); Assert.Null(context.Response); }
public void WhenCreatingInstanceWithParameterCtorThenPropertiesAreDefined() { // Arrange CommandHandlerRequest request = new CommandHandlerRequest(this.config, this.command.Object); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); // Act CommandHandlerContext context = new CommandHandlerContext(request, descriptor); // Assert Assert.Same(this.config, context.Configuration); Assert.Same(request, context.Request); Assert.Same(request.Command, context.Command); Assert.Same(descriptor, context.Descriptor); Assert.NotNull(context.Request); Assert.NotNull(context.Items); Assert.Equal(0, context.Items.Count); }
public void WhenExecuteExceptionFilterAsyncThenReturnsCompletedTask() { // Arrange Mock <MessageProcessorTests.ISpy> spy = new Mock <MessageProcessorTests.ISpy>(); IExceptionFilter filter = new CustomExceptionFilterAttribute(spy.Object); CommandHandlerContext handlerContext = new CommandHandlerContext(); Exception exception = new Exception(); ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception); CommandHandlerExecutedContext handlerExecutedContext = new CommandHandlerExecutedContext(handlerContext, exceptionInfo); CancellationToken cancellationToken = new CancellationToken(); // Act var task = filter.ExecuteExceptionFilterAsync(handlerExecutedContext, cancellationToken); // Assert Assert.NotNull(task); Assert.True(task.IsCompleted); spy.Verify(s => s.Spy("OnException"), Times.Once()); }
public void WhenExecutedFilterWithoutKeyThenCacheIsNotUpdated() { // Arrange CacheAttribute filter = this.CreateAttribute(); SimpleCommand command = new SimpleCommand { Property1 = 12, Property2 = "test" }; CommandHandlerRequest request = new CommandHandlerRequest(this.config, command); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); CommandHandlerContext context = new CommandHandlerContext(request, descriptor); CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(context, null); // Act filter.OnCommandExecuted(executedContext); // Assert this.cache.Verify(c => c.Add(It.IsAny <string>(), It.IsAny <object>(), It.IsAny <DateTimeOffset>(), It.IsAny <string>()), Times.Never()); }
/// <summary> /// Execute the request via the worker. /// </summary> /// <param name="request">The <see cref="HandlerRequest"/> to execute.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to cancel the execution.</param> /// <returns>The result of the command, if any.</returns> public Task <HandlerResponse> ExecuteAsync(CommandHandlerRequest request, CancellationToken cancellationToken) { if (request == null) { throw Error.ArgumentNull("request"); } cancellationToken.ThrowIfCancellationRequested(); ServicesContainer servicesContainer = request.Configuration.Services; ICommandHandlerSelector handlerSelector = servicesContainer.GetHandlerSelector(); CommandHandlerDescriptor descriptor = handlerSelector.SelectHandler(request); ICommandHandler commandHandler = descriptor.CreateHandler(request); if (commandHandler == null) { throw CreateHandlerNotFoundException(descriptor); } request.RegisterForDispose(commandHandler, true); CommandHandlerContext context = new CommandHandlerContext(request, descriptor); context.Handler = commandHandler; commandHandler.CommandContext = context; CommandFilterGrouping commandFilterGrouping = descriptor.GetFilterGrouping(); ICommandHandlerResult result = new CommandHandlerFilterResult(context, servicesContainer, commandFilterGrouping.CommandHandlerFilters); if (descriptor.RetryPolicy != RetryPolicy.NoRetry) { result = new RetryHandlerResult(descriptor.RetryPolicy, result); } if (commandFilterGrouping.ExceptionFilters.Length > 0) { IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(servicesContainer); IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(servicesContainer); result = new ExceptionFilterResult(context, commandFilterGrouping.ExceptionFilters, exceptionLogger, exceptionHandler, result); } return(result.ExecuteAsync(cancellationToken)); }