public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { TSuccessResult result; try { var executingPipeline = _commandsBuilder.ExecutingPipelines.Reverse() // TODO: always reversing? .Aggregate((ExecutingPipeline) new FinalExecutingPipeline(this), (current, executingPipelineType) => (ExecutingPipeline)_dependencyService.Resolve(executingPipelineType, typeof(ExecutingPipeline), current)); result = await executingPipeline.ExecutingAsync(command).ConfigureAwait(false); } catch (Exception exception) { var exceptionPipeline = _commandsBuilder.ExceptionPipelines.Reverse() .Aggregate((ExceptionPipeline) new FinalExceptionPipeline(), (current, exceptionPipelineType) => (ExceptionPipeline)_dependencyService.Resolve(exceptionPipelineType, typeof(ExceptionPipeline), current)); var newResult = await exceptionPipeline.ExceptionAsync(command, exception).ConfigureAwait(false); if (newResult is Exception newException) { ExceptionDispatchInfo.Capture(newException).Throw(); } return((TSuccessResult)newResult); // TODO: I don't think this should go back into the outgoing... } var executedPipeline = _commandsBuilder.ExecutedPipelines.Reverse() .Aggregate((ExecutedPipeline) new FinalExecutedPipeline(), (current, executedPipelineType) => (ExecutedPipeline)_dependencyService.Resolve(executedPipelineType, typeof(ExecutedPipeline), current)); return(await executedPipeline.ExecutedAsync(command, result).ConfigureAwait(false)); }
public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { using (var internalCommandProcessor = new InternalCommandProcessor(_commandsBuilder, _lifetimeScopeService, command)) { return(await internalCommandProcessor.ProcessAsync(command).ConfigureAwait(false)); } }
public void WhenNotFromAdoReturnsEmptyList() { ISuccessResult <WorkItemLink[]> result = (ISuccessResult <WorkItemLink[]>)CreateWorkItemLinkMapper().Map(new OctopusBuildInformation { BuildEnvironment = "Something", BuildUrl = "http://redstoneblock/DefaultCollection/Deployable/_build/results?buildId=24" }); Assert.IsEmpty(result.Value); }
public ResultRegisterProcessor(ISuccessResult <TCommand, TSuccessResult> command, IReadOnlyDictionary <Type, Func <object, TReturn> > defaultResultParsers, ICommandProcessor commandProcessor) { Contract.Requires(command != null); Contract.Requires(defaultResultParsers != null); Contract.Requires(commandProcessor != null); _command = command; _defaultResultParsers = defaultResultParsers; _commandProcessor = commandProcessor; }
public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { var resultTaskCompletionSource = new TaskCompletionSource <TSuccessResult>(); // TODO: timeout var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(15)); cancellationTokenSource.Token.Register(() => resultTaskCompletionSource.TrySetException(new Exception("30b1ddaa-21d9-452d-8c32-faf070dc7c8c"))); var commandTransport = new CommandContainer { Id = Guid.NewGuid().ToString(), // TODO: could i do a string ID which i pass in and then stop duplicates. For example the ID of the object to be created in the db Command = command }; await _commandTransportClient.ListenAsync <TSuccessResult>(commandTransport.Id, resultTransport => { if (resultTransport.Success) { resultTaskCompletionSource.SetResult(resultTransport.Result); } else if (!resultTransport.Success) { resultTaskCompletionSource.SetException(resultTransport.Exception); } else { throw new NotImplementedException(); } return(Task.CompletedTask); }).ConfigureAwait(false); await _commandTransportClient.SendAsync(commandTransport).ConfigureAwait(false); return(await resultTaskCompletionSource.Task.ConfigureAwait(false)); }
public async Task <CommandProcessorSuccessResult <TSuccessResult> > ProcessResultAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { try { return(new CommandProcessorSuccessResult <TSuccessResult>(await ProcessAsync(command).ConfigureAwait(false))); } catch (Exception exception) { return(new CommandProcessorSuccessResult <TSuccessResult>(exception)); } }
public override Task <TSuccessResult> ExecutedAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, TSuccessResult result) { Console.WriteLine("ExecutedAsync"); return(base.ExecutedAsync(command, result)); }
public override Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception) { return(Task.FromResult((object)exception)); }
public virtual Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception) where TCommand : IAsyncCommand { return(_nextExceptionPipeline.ExceptionAsync(command, exception)); }
// can i make one which only returns the success public ResultRegisterProcessor <TCommand, TSuccessResult, TReturn> For <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { return(new ResultRegisterProcessor <TCommand, TSuccessResult, TReturn> (command, _resultParsers, _commandProcessor)); }
public override Task <TSuccessResult> ExecutingAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) { return(_commandProcessor.ExecuteAsync(command)); }
public virtual Task <TSuccessResult> ExecutingAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { return(_nextExecutingPipeline.ExecutingAsync(command)); }
public override Task <TSuccessResult> ExecutedAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, TSuccessResult result) { return(Task.FromResult(result)); }
public static TResult Success <TCommand, TResult>(this ISuccessResult <TCommand, TResult> result) where TCommand : IAsyncCommand { return(default);
public Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { throw new NotImplementedException(); }
internal async Task <TSuccessResult> ExecuteAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand { var isInitialCommand = command == _initialCommand; var allClassTypes = GetAllConcreteClassTypes(typeof(TCommand)); // TODO: only create with IAsyncCommand, if none then throw a handler not found exception.. an analyzer could check this var firstRegisteredClassType = allClassTypes.First(t => _dependencyService.IsRegistered(typeof(IAsyncCommandHandler <,>).MakeGenericType(t, typeof(TSuccessResult)))); var handlerType = typeof(IAsyncCommandHandler <,>).MakeGenericType(firstRegisteredClassType, typeof(TSuccessResult)); var handler = _dependencyService.Resolve(handlerType); var pipelines = _commandsBuilder.Pipelines.Select(p => (Pipeline)_dependencyService.Resolve(p)).ToList(); // run executing pipeline and notification foreach (var pipeline in pipelines) { if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand) { await pipeline.ExecutingAsync(command).ConfigureAwait(false); } } if (_commandsBuilder.ExecutingNotifications.TryGetValue(typeof(TCommand), out var executingNotifications)) { foreach (var executingNotification in executingNotifications) { // TODO: can this be done a better way? await((Task)typeof(IExecutingNotification <>).MakeGenericType(typeof(TCommand)) .GetTypeInfo().GetMethod("OnExecutingAsync", new[] { command.GetType() }) .Invoke(_dependencyService.Resolve(executingNotification), new object[] { command })).ConfigureAwait(false); } } Task <TSuccessResult> task = null; try { task = (Task <TSuccessResult>)handlerType.GetTypeInfo().GetMethod("ExecuteAsync", new[] { command.GetType() }).Invoke(handler, new object[] { command }); var result = await task.ConfigureAwait(false); if (_commandsBuilder.ExecutedNotifications.TryGetValue(typeof(TCommand), out var executedNotifications)) { foreach (var executedNotification in executedNotifications) { await((Task)typeof(IExecutedNotification <,>).MakeGenericType(typeof(TCommand), typeof(TSuccessResult)) .GetTypeInfo().GetMethod("OnExecutedAsync", new[] { command.GetType(), typeof(TSuccessResult) }) .Invoke(_dependencyService.Resolve(executedNotification), new object[] { command, result })).ConfigureAwait(false); } } pipelines.Reverse(); foreach (var pipeline in pipelines) { if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand) { await pipeline.ExecutedAsync(command, result).ConfigureAwait(false); } } } catch (Exception exception) { // if the command was not async, we will need to get the inner exception if (exception is TargetInvocationException targetInvocationException) { exception = targetInvocationException.InnerException; } // run exception notification and pipeline if (_commandsBuilder.ExceptionNotifications.TryGetValue(typeof(TCommand), out var exceptionNotifications)) { foreach (var exceptionNotification in exceptionNotifications) { await((Task)typeof(IExceptionNotification <>).MakeGenericType(typeof(TCommand)) .GetTypeInfo().GetMethod("OnExceptionAsync", new[] { command.GetType(), typeof(Exception) }) .Invoke(_dependencyService.Resolve(exceptionNotification), new object[] { command, exception })).ConfigureAwait(false); } } pipelines.Reverse(); foreach (var pipeline in pipelines) { if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand) { await pipeline.ExceptionAsync(command, exception).ConfigureAwait(false); } } ExceptionDispatchInfo.Capture(exception).Throw(); } return(await task.ConfigureAwait(false)); }
public override Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception) { Console.WriteLine("ExceptionAsync"); return(base.ExceptionAsync(command, exception)); }