diff --git a/src/Commands/Merq.Commands.CommandBus/CommandBus.cs b/src/Commands/Merq.Commands.CommandBus/CommandBus.cs
deleted file mode 100644
index ad9182b4..00000000
--- a/src/Commands/Merq.Commands.CommandBus/CommandBus.cs
+++ /dev/null
@@ -1,277 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using Merq.Properties;
-
-namespace Merq
-{
- ///
- /// Default implementation of the .
- ///
- public class CommandBus : ICommandBus
- {
- Dictionary handlerMap;
-
- ///
- /// Initializes the command bus with the given list of handlers.
- ///
- public CommandBus (IEnumerable handlers)
- {
- if (handlers == null) throw new ArgumentNullException (nameof (handlers));
-
-
- AddHandlers (handlers);
- }
-
- ///
- /// Initializes the command bus with the given list of handlers.
- ///
- public CommandBus (params ICommandHandler[] handlers)
- : this ((IEnumerable)handlers)
- {
- }
-
- ///
- /// Determines whether the given command type has a registered handler.
- ///
- /// The type of command to query.
- /// if the command has a registered handler. otherwise.
- public virtual bool CanHandle () where TCommand : IExecutable => handlerMap.ContainsKey (typeof (TCommand));
-
- ///
- /// Determines whether the given command has a registered handler.
- ///
- /// The command to query.
- /// if the command has a registered handler. otherwise.
- public virtual bool CanHandle (IExecutable command)
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- return handlerMap.ContainsKey (command.GetType ());
- }
-
- ///
- /// Determines whether the given command can be executed by a registered
- /// handler with the provided command instance values.
- ///
- /// The command parameters for the query.
- /// if the command can be executed. otherwise.
- public virtual bool CanExecute (TCommand command) where TCommand : IExecutable
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- var handler = GetCommandHandlerFromMap ((IExecutable) command, throwIfMissing: false);
-
- return handler == null ? false :
- ((ICanExecute)handler).CanExecute (command);
- }
-
- ///
- /// Executes the given command synchronously.
- ///
- /// The command parameters for the execution.
- public virtual void Execute (ICommand command)
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- ExecuteImpl (
- "ExecuteCommand",
- new[] { command.GetType () },
- new[] { command });
- }
-
- ///
- /// Executes the given command synchronously.
- ///
- /// The return type of the command execution.
- /// The command parameters for the execution.
- /// The result of executing the command.
- public virtual TResult Execute (ICommand command)
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- return (TResult)ExecuteImpl (
- "ExecuteCommandWithResult",
- new[] { command.GetType (), typeof (TResult) },
- new[] { command });
- }
-
- ///
- /// Executes the given asynchronous command.
- ///
- /// The command parameters for the execution.
- /// Cancellation token to cancel command execution.
- public virtual Task ExecuteAsync (IAsyncCommand command, CancellationToken cancellation)
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- return (Task)ExecuteImpl (
- "ExecuteCommandAsync",
- new[] { command.GetType () },
- new object[] { command, cancellation });
- }
-
- ///
- /// Executes the given command asynchronously.
- ///
- /// The return type of the command execution.
- /// The command parameters for the execution.
- /// Cancellation token to cancel command execution.
- /// The result of executing the command.
- public virtual Task ExecuteAsync (IAsyncCommand command, CancellationToken cancellation)
- {
- if (command == null) throw new ArgumentNullException (nameof (command));
-
- return (Task)ExecuteImpl (
- "ExecuteCommandWithResultAsync",
- new[] { command.GetType (), typeof (TResult) },
- new object[] { command, cancellation });
- }
-
- object ExecuteImpl (string methodName, Type[] typeArguments, params object[] parameters)
- {
- // Important: We need to do this in order to be able to invoke the Execute or ExecuteAsync
- // methods without specifying the generic arguments by the caller explicitly
- // Otherwise it would not be possible to do the following:
- //
- // commandBus.Execute (new MyCommand ()) // void command
- // var result = commandBus.execute (new MyCommandWithResult ()) // command with result
-
- try {
- return typeof (CommandBus)
- .GetTypeInfo ()
- .GetDeclaredMethod (methodName)
- .MakeGenericMethod (typeArguments)
- .Invoke (this, parameters);
- } catch (TargetInvocationException ex) {
- // Rethrow the inner exception preserving stack trace.
- System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
- // Will never get here.
- throw ex.InnerException;
- }
- }
-
- void ExecuteCommand (TCommand command) where TCommand : ICommand
- {
- var handler = GetCommandHandler(command);
-
- handler.Execute (command);
- }
-
- TResult ExecuteCommandWithResult (TCommand command) where TCommand : ICommand
- {
- var handler = GetCommandHandler (command);
-
- return handler.Execute (command);
- }
-
- Task ExecuteCommandAsync (TCommand command, CancellationToken cancellation) where TCommand : IAsyncCommand
- {
- var handler = GetAsyncCommandHandler (command);
-
- return handler.ExecuteAsync (command, cancellation);
- }
-
- Task ExecuteCommandWithResultAsync (TCommand command, CancellationToken cancellation) where TCommand : IAsyncCommand
- {
- var handler = GetAsyncCommandHandler (command);
-
- return handler.ExecuteAsync ((dynamic)command, cancellation);
- }
-
- void AddHandlers (IEnumerable handlers)
- {
- handlerMap = new Dictionary ();
- var nonGenericHandlers = new List();
- var duplicateHandlers = new List>();
-
- ProcessHandlers (handlers, nonGenericHandlers, duplicateHandlers);
- var errors = ProcessErrors (nonGenericHandlers, duplicateHandlers);
-
- if (!string.IsNullOrEmpty (errors))
- throw new ArgumentException (errors);
- }
-
- void ProcessHandlers (IEnumerable handlers, List nonGenericHandlers, List> duplicateHandlers)
- {
- foreach (var handler in handlers.Where (x => x != null)) {
- // Extracts the first T in any of the command handler interfaces (sync, async, with/without result)
- var commandType = GetCommandType (handler.GetType ());
- if (commandType != null) {
- if (!handlerMap.ContainsKey (commandType))
- handlerMap.Add (commandType, handler);
- else
- // Can't have duplicate handlers either. This is one key
- // difference between commands and events.
- duplicateHandlers.Add (Tuple.Create (commandType, handler));
- } else {
- // ICommandHandler without any T is not valid since it can't handle
- // anything.
- nonGenericHandlers.Add (handler);
- }
- }
- }
-
- static string ProcessErrors (List nonGenericHandlers, List> duplicateHandlers)
- {
- return string.Join (Environment.NewLine, nonGenericHandlers
- .Select (handler => Strings.CommandBus.InvalidHandler (handler.GetType ().Name))
- .Concat (duplicateHandlers
- .Select (handler => Strings.CommandBus.DuplicateHandler (handler.Item2.GetType ().Name, handler.Item1.Name))));
- }
-
- ICommandHandler GetCommandHandlerFromMap (IExecutable command, bool throwIfMissing)
- {
- ICommandHandler handler;
- if (!handlerMap.TryGetValue (command.GetType (), out handler) && throwIfMissing) {
- throw new NotSupportedException (Strings.CommandBus.NoHandler (command.GetType ()));
- }
-
- return handler;
- }
-
- ICommandHandler GetCommandHandler (TCommand command) where TCommand : ICommand
- {
- return (ICommandHandler)GetCommandHandlerFromMap ((IExecutable)command, true);
- }
-
- ICommandHandler GetCommandHandler (IExecutable command) where TCommand : ICommand
- {
- return (ICommandHandler)GetCommandHandlerFromMap (command, true);
- }
-
- IAsyncCommandHandler GetAsyncCommandHandler (TCommand command) where TCommand : IAsyncCommand
- {
- return (IAsyncCommandHandler)GetCommandHandlerFromMap ((IExecutable)command, true);
- }
-
- IAsyncCommandHandler GetAsyncCommandHandler (IExecutable command) where TCommand : IAsyncCommand
- {
- return (IAsyncCommandHandler)GetCommandHandlerFromMap (command, true);
- }
-
- static Type GetCommandType (Type type)
- {
- return type.GetTypeInfo ().ImplementedInterfaces
- .Where (x => IsHandlerInterface (x))
- .Select (x => x.GenericTypeArguments.First ())
- .FirstOrDefault ();
- }
-
- static bool IsHandlerInterface (Type type)
- {
- if (!type.IsConstructedGenericType)
- return false;
-
- var genericType = type.GetGenericTypeDefinition();
-
- return genericType == typeof (ICommandHandler<>) ||
- genericType == typeof (ICommandHandler<,>) ||
- genericType == typeof (IAsyncCommandHandler<>) ||
- genericType == typeof (IAsyncCommandHandler<,>);
- }
- }
-}