PageRenderTime 52ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/Bifrost/Commands/CommandHandlerInvoker.cs

#
C# | 107 lines | 60 code | 10 blank | 37 comment | 3 complexity | a2cc9f4e6d41cb1a4991a8ad27cae42f MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. #region License
  2. //
  3. // Copyright (c) 2008-2012, DoLittle Studios and Komplett ASA
  4. //
  5. // Licensed under the Microsoft Permissive License (Ms-PL), Version 1.1 (the "License")
  6. // With one exception :
  7. // Commercial libraries that is based partly or fully on Bifrost and is sold commercially,
  8. // must obtain a commercial license.
  9. //
  10. // You may not use this file except in compliance with the License.
  11. // You may obtain a copy of the license at
  12. //
  13. // http://bifrost.codeplex.com/license
  14. //
  15. // Unless required by applicable law or agreed to in writing, software
  16. // distributed under the License is distributed on an "AS IS" BASIS,
  17. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. // See the License for the specific language governing permissions and
  19. // limitations under the License.
  20. //
  21. #endregion
  22. using System;
  23. using System.Linq;
  24. using System.Collections.Generic;
  25. using Bifrost.Execution;
  26. using Microsoft.Practices.ServiceLocation;
  27. using System.Reflection;
  28. namespace Bifrost.Commands
  29. {
  30. /// <summary>
  31. /// Represents a <see cref="ICommandHandlerInvoker">ICommandHandlerInvoker</see> for handling
  32. /// command handlers that have methods called Handle() and takes specific <see cref="ICommand">commands</see>
  33. /// in as parameters
  34. /// </summary>
  35. [Singleton]
  36. public class CommandHandlerInvoker : ICommandHandlerInvoker
  37. {
  38. const string HandleMethodName = "Handle";
  39. readonly ITypeDiscoverer _discoverer;
  40. readonly IServiceLocator _serviceLocator;
  41. readonly Dictionary<Type, MethodInfo> _commandHandlers = new Dictionary<Type, MethodInfo>();
  42. bool _initialized;
  43. /// <summary>
  44. /// Initializes a new instance of <see cref="CommandHandlerInvoker">CommandHandlerInvoker</see>
  45. /// </summary>
  46. /// <param name="discoverer">A <see cref="ITypeDiscoverer"/> to use for discovering <see cref="ICommandHandler">command handlers</see></param>
  47. /// <param name="serviceLocator">A <see cref="IServiceLocator"/> to use for getting instances of objects</param>
  48. public CommandHandlerInvoker(ITypeDiscoverer discoverer, IServiceLocator serviceLocator)
  49. {
  50. _discoverer = discoverer;
  51. _serviceLocator = serviceLocator;
  52. _initialized = false;
  53. }
  54. private void Initialize()
  55. {
  56. var handlers = _discoverer.FindMultiple<ICommandHandler>();
  57. Array.ForEach(handlers, Register);
  58. _initialized = true;
  59. }
  60. /// <summary>
  61. /// Register a command handler explicitly
  62. /// </summary>
  63. /// <param name="handlerType"></param>
  64. /// <remarks>
  65. /// The registration process will look into the handler and find methods that
  66. /// are called Handle() and takes a command as parameter
  67. /// </remarks>
  68. public void Register(Type handlerType)
  69. {
  70. var allMethods = handlerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
  71. var query = from m in allMethods
  72. where m.Name.Equals(HandleMethodName) &&
  73. m.GetParameters().Length == 1 &&
  74. typeof(ICommand).IsAssignableFrom(m.GetParameters()[0].ParameterType)
  75. select m;
  76. foreach (var method in query)
  77. _commandHandlers[method.GetParameters()[0].ParameterType] = method;
  78. }
  79. #pragma warning disable 1591 // Xml Comments
  80. public bool TryHandle(ICommand command)
  81. {
  82. if( !_initialized)
  83. Initialize();
  84. var commandType = command.GetType();
  85. if (_commandHandlers.ContainsKey(commandType))
  86. {
  87. var commandHandlerType = _commandHandlers[commandType].DeclaringType;
  88. var commandHandler = _serviceLocator.GetInstance(commandHandlerType);
  89. var method = _commandHandlers[commandType];
  90. method.Invoke(commandHandler, new[] { command });
  91. return true;
  92. }
  93. return false;
  94. }
  95. #pragma warning restore 1591 // Xml Comments
  96. }
  97. }