没有为消息指定路由

时间:2014-04-12 03:31:26

标签: c# asp.net-mvc-4 cqrs event-sourcing

我正在跟随Mark Nihof(Fohjin)架构开发基于cqrs的电子商务应用程序。我的开发框架是Asp.net MVC5。报告方工作正常,但当我尝试通过浏览 localhost:63738 / api / Security / Signup 执行命令时,它会显示以下异常 没有为邮件指定路由' RavenProject.Commands.CreateUserCommand'

我的消息路由器类如下:

public class MessageRouter : IRouteMessages
    {
        private readonly IDictionary<Type, ICollection<Action<object>>> _routes;

        public MessageRouter()
        {
            _routes = new Dictionary<Type, ICollection<Action<object>>>();
        }

        public void Register<TMessage>(Action<TMessage> route) where TMessage : class
        {
            var routingKey = typeof(TMessage);
            ICollection<Action<object>> routes;

            if (!_routes.TryGetValue(routingKey, out routes))
                _routes[routingKey] = routes = new LinkedList<Action<object>>();

            routes.Add(message => route(message as TMessage));
        }

        public void Route(object message)
        {
            ICollection<Action<object>> routes;

            if (!_routes.TryGetValue(message.GetType(), out routes))
                throw new RouteNotRegisteredException(message.GetType());

            foreach (var route in routes)
                route(message);
        }
    }

我的路由寄存器类如下:

public class RegisterCommandHandlersInMessageRouter
    {
        private static MethodInfo _createPublishActionWrappedInTransactionMethod;
        private static MethodInfo _registerMethod;

        public static void BootStrap()
        {
            new RegisterCommandHandlersInMessageRouter().RegisterRoutes(ObjectFactory.GetInstance<IRouteMessages>() as MessageRouter);
        }

        public void RegisterRoutes(MessageRouter messageRouter)
        {
            _createPublishActionWrappedInTransactionMethod = GetType().GetMethod("CreatePublishActionWrappedInTransaction");
            _registerMethod = messageRouter.GetType().GetMethod("Register");

            var commands = CommandHandlerFactory.GetCommands();
            var commandHandlers = CommandHandlerFactory.GetCommandHandlers();

            foreach (var command in commands)
            {
                IList<Type> commandHandlerTypes;
                if (!commandHandlers.TryGetValue(command, out commandHandlerTypes))
                    throw new Exception(string.Format("No command handlers found for event '{0}'", command.FullName));

                foreach (var commandHandler in commandHandlerTypes)
                {
                    var injectedCommandHandler = GetCorrectlyInjectedCommandHandler(commandHandler);
                    var action = CreateTheProperAction(command, injectedCommandHandler);
                    RegisterTheCreatedActionWithTheMessageRouter(messageRouter, command, action);
                }
            }
        }

        private static object GetCorrectlyInjectedCommandHandler(Type commandHandler)
        {
            return ObjectFactory.GetInstance(commandHandler);
        }

        private static void RegisterTheCreatedActionWithTheMessageRouter(MessageRouter messageRouter, Type commandType, object action)
        {
            _registerMethod.MakeGenericMethod(commandType).Invoke(messageRouter, new[] { action });
        }

        private object CreateTheProperAction(Type commandType, object commandHandler)
        {
            return _createPublishActionWrappedInTransactionMethod.MakeGenericMethod(commandType, commandHandler.GetType()).Invoke(this, new[] { commandHandler });
        }

        public Action<TCommand> CreatePublishActionWrappedInTransaction<TCommand, TCommandHandler>(TCommandHandler commandHandler)
            where TCommand : class
            where TCommandHandler : ICommandHandler<TCommand>
        {
            //return command => ObjectFactory.GetInstance<TransactionHandler<TCommand, TCommandHandler>>().Execute(command, commandHandler);
            return command => ObjectFactory.GetInstance<ICommandHandler<TCommand>>().Execute(command);
        }
    }

我的错误在哪里,但我没有确定。

注意:我从浏览器调用的方法实际上是HTTP POST方法,但出于检查目的,我使用了HTTP GET。

My Route Register类在引导应用程序期间正确注册所有路由。

还可以通过以下链接查看我的整个作品 https://drive.google.com/file/d/0B1rU7HOTfLweZjFuZlF3M0Z2M28/edit?usp=sharing

1 个答案:

答案 0 :(得分:0)

您仍然需要定义路线。请参阅示例here

_handler = new FirstTestCommandHandler();
var messageRouter = new MessageRouter();
messageRouter.Register<TestCommand>(x => _handler.Execute(x));
DoNotMock.Add(typeof (IRouteMessages), messageRouter);