PageRenderTime 30ms CodeModel.GetById 20ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/Source/Bifrost/Commands/CommandHandlerInvoker.cs

#
C# | 107 lines | 60 code | 10 blank | 37 comment | 3 complexity | a2cc9f4e6d41cb1a4991a8ad27cae42f MD5 | raw file
  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
 22using System;
 23using System.Linq;
 24using System.Collections.Generic;
 25using Bifrost.Execution;
 26using Microsoft.Practices.ServiceLocation;
 27using System.Reflection;
 28
 29namespace Bifrost.Commands
 30{
 31	/// <summary>
 32	/// Represents a <see cref="ICommandHandlerInvoker">ICommandHandlerInvoker</see> for handling
 33	/// command handlers that have methods called Handle() and takes specific <see cref="ICommand">commands</see>
 34	/// in as parameters
 35	/// </summary>
 36	[Singleton]
 37	public class CommandHandlerInvoker : ICommandHandlerInvoker
 38	{
 39        const string HandleMethodName = "Handle";
 40
 41		readonly ITypeDiscoverer _discoverer;
 42	    readonly IServiceLocator _serviceLocator;
 43        readonly Dictionary<Type, MethodInfo> _commandHandlers = new Dictionary<Type, MethodInfo>();
 44	    bool _initialized;
 45
 46	    /// <summary>
 47	    /// Initializes a new instance of <see cref="CommandHandlerInvoker">CommandHandlerInvoker</see>
 48	    /// </summary>
 49	    /// <param name="discoverer">A <see cref="ITypeDiscoverer"/> to use for discovering <see cref="ICommandHandler">command handlers</see></param>
 50	    /// <param name="serviceLocator">A <see cref="IServiceLocator"/> to use for getting instances of objects</param>
 51	    public CommandHandlerInvoker(ITypeDiscoverer discoverer, IServiceLocator serviceLocator)
 52		{
 53			_discoverer = discoverer;
 54		    _serviceLocator = serviceLocator;
 55	        _initialized = false;
 56		}
 57
 58		private void Initialize()
 59		{
 60		    var handlers = _discoverer.FindMultiple<ICommandHandler>();
 61			Array.ForEach(handlers, Register);
 62		    _initialized = true;
 63		}
 64
 65		/// <summary>
 66		/// Register a command handler explicitly 
 67		/// </summary>
 68		/// <param name="handlerType"></param>
 69		/// <remarks>
 70		/// The registration process will look into the handler and find methods that 
 71		/// are called Handle() and takes a command as parameter
 72		/// </remarks>
 73		public void Register(Type handlerType)
 74		{
 75            var allMethods = handlerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
 76
 77            var query = from m in allMethods
 78                        where m.Name.Equals(HandleMethodName) &&
 79                              m.GetParameters().Length == 1 &&
 80                              typeof(ICommand).IsAssignableFrom(m.GetParameters()[0].ParameterType)
 81                        select m;
 82
 83            foreach (var method in query)
 84                _commandHandlers[method.GetParameters()[0].ParameterType] = method;
 85		}
 86
 87#pragma warning disable 1591 // Xml Comments
 88		public bool TryHandle(ICommand command)
 89		{
 90            if( !_initialized)
 91                Initialize();
 92
 93            var commandType = command.GetType();
 94            if (_commandHandlers.ContainsKey(commandType))
 95            {
 96                var commandHandlerType = _commandHandlers[commandType].DeclaringType;
 97                var commandHandler = _serviceLocator.GetInstance(commandHandlerType);
 98                var method = _commandHandlers[commandType];
 99                method.Invoke(commandHandler, new[] { command });
100                return true;
101            }
102
103		    return false;
104		}
105#pragma warning restore 1591 // Xml Comments
106	}
107}