LCOV - code coverage report
Current view: top level - Cqrs/Bus - RouteManager.cs Hit Total Coverage
Test: doc-coverage.info Lines: 2 11 18.2 %
Date: 2017-07-26

          Line data    Source code
       1             : #region Copyright
       2             : // // -----------------------------------------------------------------------
       3             : // // <copyright company="cdmdotnet Limited">
       4             : // //   Copyright cdmdotnet Limited. All rights reserved.
       5             : // // </copyright>
       6             : // // -----------------------------------------------------------------------
       7             : #endregion
       8             : 
       9             : using System;
      10             : using System.Collections.Generic;
      11             : using System.Linq;
      12             : using Cqrs.Commands;
      13             : using Cqrs.Events;
      14             : using Cqrs.Infrastructure;
      15             : using Cqrs.Messages;
      16             : 
      17             : namespace Cqrs.Bus
      18             : {
      19             :         public class RouteManager
      20             :                 : IHandlerRegistrar
      21           0 :         {
      22             :                 protected IDictionary<Type, Route> Routes { get; private set; }
      23             : 
      24             :                 private static Type CommandType { get; set; }
      25             : 
      26             :                 private static Type EventType { get; set; }
      27             : 
      28           0 :                 public RouteManager()
      29             :                 {
      30             :                         Routes = new Dictionary<Type, Route>();
      31             :                 }
      32             : 
      33             :                 static RouteManager()
      34             :                 {
      35             :                         CommandType = typeof (ICommand<>);
      36             :                         EventType = typeof (IEvent<>);
      37             :                 }
      38             : 
      39             :                 #region Implementation of IHandlerRegistrar
      40             : 
      41             :                 /// <summary>
      42             :                 /// Register an event or command handler that will listen and respond to events or commands.
      43             :                 /// </summary>
      44           1 :                 public virtual void RegisterHandler<TMessage>(Action<TMessage> handler, Type targetedType, bool holdMessageLock = true)
      45             :                         where TMessage : IMessage
      46             :                 {
      47             :                         Route route;
      48             :                         if (!Routes.TryGetValue(typeof(TMessage), out route))
      49             :                         {
      50             :                                 route = new Route
      51             :                                 {
      52             :                                         Handlers = new List<RouteHandlerDelegate>()
      53             :                                 };
      54             :                                 Routes.Add(typeof(TMessage), route);
      55             :                         }
      56             :                         route.Handlers.Add
      57             :                         (
      58             :                                 new RouteHandlerDelegate
      59             :                                 {
      60             :                                         Delegate = DelegateAdjuster.CastArgument<IMessage, TMessage>(x => handler(x)),
      61             :                                         TargetedType = targetedType
      62             :                                 }
      63             :                         );
      64             :                 }
      65             : 
      66             :                 /// <summary>
      67             :                 /// Register an event or command handler that will listen and respond to events or commands.
      68             :                 /// </summary>
      69           1 :                 public void RegisterHandler<TMessage>(Action<TMessage> handler, bool holdMessageLock = true)
      70             :                         where TMessage : IMessage
      71             :                 {
      72             :                         RegisterHandler(handler, null, holdMessageLock);
      73             :                 }
      74             : 
      75             :                 #endregion
      76             : 
      77           0 :                 public RouteHandlerDelegate GetSingleHandler<TMessage>(bool throwExceptionOnNoRouteHandlers = true)
      78             :                         where TMessage : IMessage
      79             :                 {
      80             :                         Route route;
      81             :                         Type messageType = typeof(TMessage);
      82             :                         bool isACommand = IsACommand(messageType);
      83             : 
      84             :                         if (Routes.TryGetValue(typeof(TMessage), out route))
      85             :                         {
      86             :                                 if (route.Handlers == null || route.Handlers.Count != 1)
      87             :                                 {
      88             :                                         if (isACommand)
      89             :                                                 throw new MultipleCommandHandlersRegisteredException(messageType);
      90             :                                         throw new InvalidOperationException("Cannot send to more than one handler.");
      91             :                                 }
      92             :                                 return route.Handlers.Single();
      93             :                         }
      94             : 
      95             :                         if (throwExceptionOnNoRouteHandlers)
      96             :                         {
      97             :                                 if (isACommand)
      98             :                                         throw new NoCommandHandlerRegisteredException(messageType);
      99             :                                 throw new InvalidOperationException("No handler registered.");
     100             :                         }
     101             : 
     102             :                         return null;
     103             :                 }
     104             : 
     105           0 :                 public RouteHandlerDelegate GetSingleHandler<TMessage>(TMessage message, bool throwExceptionOnNoRouteHandlers = true)
     106             :                         where TMessage : IMessage
     107             :                 {
     108             :                         Route route;
     109             :                         Type messageType = message.GetType();
     110             :                         bool isACommand = IsACommand(messageType);
     111             : 
     112             :                         if (Routes.TryGetValue(messageType, out route))
     113             :                         {
     114             :                                 if (route.Handlers != null)
     115             :                                 {
     116             :                                         if (route.Handlers.Count > 1)
     117             :                                         {
     118             :                                                 if (isACommand)
     119             :                                                         throw new MultipleCommandHandlersRegisteredException(messageType);
     120             :                                                 throw new InvalidOperationException("Cannot send to more than one handler.");
     121             :                                         }
     122             :                                         if (route.Handlers.Count == 1)
     123             :                                                 return route.Handlers.Single();
     124             :                                 }
     125             :                         }
     126             : 
     127             :                         if (throwExceptionOnNoRouteHandlers)
     128             :                         {
     129             :                                 if (isACommand)
     130             :                                         throw new NoCommandHandlerRegisteredException(messageType);
     131             :                                 throw new InvalidOperationException("No handler registered.");
     132             :                         }
     133             : 
     134             :                         return null;
     135             :                 }
     136             : 
     137           0 :                 public IEnumerable<RouteHandlerDelegate> GetHandlers<TMessage>(TMessage message, bool throwExceptionOnNoRouteHandlers = true)
     138             :                         where TMessage : IMessage
     139             :                 {
     140             :                         Route route;
     141             :                         Type messageType = message.GetType();
     142             :                         if (Routes.TryGetValue(messageType, out route))
     143             :                                 return route.Handlers;
     144             : 
     145             :                         if (throwExceptionOnNoRouteHandlers)
     146             :                         {
     147             :                                 bool isACommand = IsACommand(messageType);
     148             :                                 bool isAnEvent = IsAnEvent(messageType);
     149             : 
     150             :                                 if (isACommand)
     151             :                                         throw new NoCommandHandlerRegisteredException(messageType);
     152             :                                 if (isAnEvent)
     153             :                                         throw new NoEventHandlerRegisteredException(messageType);
     154             :                                 throw new NoHandlerRegisteredException(messageType);
     155             :                         }
     156             : 
     157             :                         return Enumerable.Empty<RouteHandlerDelegate>();
     158             :                 }
     159             : 
     160           0 :                 protected virtual bool IsACommand<TMessage>(TMessage message)
     161             :                 {
     162             :                         Type messageType = message.GetType();
     163             :                         return IsACommand(messageType);
     164             :                 }
     165             : 
     166           0 :                 protected virtual bool IsACommand(Type messageType)
     167             :                 {
     168             :                         bool isACommand = false;
     169             :                         Type messageCommandInterface = messageType.GetInterfaces().FirstOrDefault(type => type.FullName.StartsWith(CommandType.FullName));
     170             :                         if (messageCommandInterface != null)
     171             :                         {
     172             :                                 Type[] genericArguments = messageCommandInterface.GetGenericArguments();
     173             :                                 if (genericArguments.Length == 1)
     174             :                                         isACommand = CommandType.MakeGenericType(genericArguments.Single()).IsAssignableFrom(messageType);
     175             :                         }
     176             : 
     177             :                         return isACommand;
     178             :                 }
     179             : 
     180           0 :                 protected virtual bool IsAnEvent<TMessage>(TMessage message)
     181             :                 {
     182             :                         Type messageType = message.GetType();
     183             :                         return IsACommand(messageType);
     184             :                 }
     185             : 
     186           0 :                 protected virtual bool IsAnEvent(Type messageType)
     187             :                 {
     188             :                         bool isAnEvent = false;
     189             :                         Type messageCommandInterface = messageType.GetInterfaces().FirstOrDefault(type => type.FullName.StartsWith(EventType.FullName));
     190             :                         if (messageCommandInterface != null)
     191             :                         {
     192             :                                 Type[] genericArguments = messageCommandInterface.GetGenericArguments();
     193             :                                 if (genericArguments.Length == 1)
     194             :                                         isAnEvent = EventType.MakeGenericType(genericArguments.Single()).IsAssignableFrom(messageType);
     195             :                         }
     196             : 
     197             :                         return isAnEvent;
     198             :                 }
     199             :         }
     200             : }

Generated by: LCOV version 1.10