| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | 
							- #if XFORMS
 
- namespace Caliburn.Micro.Core.Xamarin.Forms
 
- #else
 
- namespace Caliburn.Micro
 
- #endif
 
- {
 
-     using System;
 
-     using System.Globalization;
 
-     using System.Linq;
 
-     using System.Reflection;
 
-     using System.Collections.Generic;
 
- #if !SILVERLIGHT
 
-     using System.ComponentModel;
 
- #endif
 
-     /// <summary>
 
-     /// A service that is capable of properly binding values to a method's parameters and creating instances of <see cref="IResult"/>.
 
-     /// </summary>
 
-     public static class MessageBinder {
 
-         /// <summary>
 
-         /// The special parameter values recognized by the message binder along with their resolvers.
 
-         /// Parameter names are case insensitive so the specified names are unique and can be used with different case variations
 
-         /// </summary>
 
-         public static readonly Dictionary<string, Func<ActionExecutionContext, object>> SpecialValues =
 
-             new Dictionary<string, Func<ActionExecutionContext, object>>(StringComparer.OrdinalIgnoreCase)
 
-             {
 
-                 {"$eventargs", c => c.EventArgs},
 
- #if XFORMS
 
-                 {"$datacontext", c => c.Source.BindingContext},
 
-                 {"$bindingcontext", c => c.Source.BindingContext},
 
- #else
 
-                 {"$datacontext", c => c.Source.DataContext},
 
- #endif
 
-                 {"$source", c => c.Source},
 
-                 {"$executioncontext", c => c},
 
-                 {"$view", c => c.View}
 
-             };
 
-         /// <summary>
 
-         /// Custom converters used by the framework registered by destination type for which they will be selected.
 
-         /// The converter is passed the existing value to convert and a "context" object.
 
-         /// </summary>
 
-         public static readonly Dictionary<Type, Func<object, object, object>> CustomConverters =
 
-             new Dictionary<Type, Func<object, object, object>>
 
-             {
 
-                 {
 
-                     typeof (DateTime), (value, context) => {
 
-                         DateTime result;
 
-                         DateTime.TryParse(value.ToString(), out result);
 
-                         return result;
 
-                     }
 
-                 }
 
-             };
 
-         /// <summary>
 
-         /// Determines the parameters that a method should be invoked with.
 
-         /// </summary>
 
-         /// <param name="context">The action execution context.</param>
 
-         /// <param name="requiredParameters">The parameters required to complete the invocation.</param>
 
-         /// <returns>The actual parameter values.</returns>
 
-         public static object[] DetermineParameters(ActionExecutionContext context, ParameterInfo[] requiredParameters) {
 
-             var providedValues = context.Message.Parameters.OfType<Parameter>().Select(x => x.Value).ToArray();
 
-             var finalValues = new object[requiredParameters.Length];
 
-             for (int i = 0; i < requiredParameters.Length; i++) {
 
-                 var parameterType = requiredParameters[i].ParameterType;
 
-                 var parameterValue = providedValues[i];
 
-                 var parameterAsString = parameterValue as string;
 
-                 if (parameterAsString != null)
 
-                     finalValues[i] = CoerceValue(parameterType,
 
-                         EvaluateParameter(parameterAsString, parameterType, context), context);
 
-                 else finalValues[i] = CoerceValue(parameterType, parameterValue, context);
 
-             }
 
-             return finalValues;
 
-         }
 
-         /// <summary>
 
-         /// Transforms the textual parameter into the actual parameter.
 
-         /// </summary>
 
-         public static Func<string, Type, ActionExecutionContext, object> EvaluateParameter =
 
-             (text, parameterType, context) => {
 
-                 Func<ActionExecutionContext, object> resolver;
 
-                 return SpecialValues.TryGetValue(text, out resolver) ? resolver(context) : text;
 
-             };
 
-         /// <summary>
 
-         /// Coerces the provided value to the destination type.
 
-         /// </summary>
 
-         /// <param name="destinationType">The destination type.</param>
 
-         /// <param name="providedValue">The provided value.</param>
 
-         /// <param name="context">An optional context value which can be used during conversion.</param>
 
-         /// <returns>The coerced value.</returns>
 
-         public static object CoerceValue(Type destinationType, object providedValue, object context) {
 
-             if (providedValue == null) {
 
-                 return GetDefaultValue(destinationType);
 
-             }
 
-             var providedType = providedValue.GetType();
 
-             if (destinationType.IsAssignableFrom(providedType)) {
 
-                 return providedValue;
 
-             }
 
-             if (CustomConverters.ContainsKey(destinationType)) {
 
-                 return CustomConverters[destinationType](providedValue, context);
 
-             }
 
-             try {
 
- #if !WinRT && !XFORMS
 
-                 var converter = TypeDescriptor.GetConverter(destinationType);
 
-                 if (converter.CanConvertFrom(providedType)) {
 
-                     return converter.ConvertFrom(providedValue);
 
-                 }
 
-                 converter = TypeDescriptor.GetConverter(providedType);
 
-                 if (converter.CanConvertTo(destinationType)) {
 
-                     return converter.ConvertTo(providedValue, destinationType);
 
-                 }
 
- #endif
 
- #if WinRT || XFORMS
 
-                 if (destinationType.GetTypeInfo().IsEnum) {
 
- #else
 
-                 if (destinationType.IsEnum) {
 
- #endif
 
-                     var stringValue = providedValue as string;
 
-                     if (stringValue != null) {
 
-                         return Enum.Parse(destinationType, stringValue, true);
 
-                     }
 
-                     return Enum.ToObject(destinationType, providedValue);
 
-                 }
 
-                 if (typeof (Guid).IsAssignableFrom(destinationType)) {
 
-                     var stringValue = providedValue as string;
 
-                     if (stringValue != null) {
 
-                         return new Guid(stringValue);
 
-                     }
 
-                 }
 
-             }
 
-             catch {
 
-                 return GetDefaultValue(destinationType);
 
-             }
 
-             try {
 
-                 return Convert.ChangeType(providedValue, destinationType, CultureInfo.CurrentCulture);
 
-             }
 
-             catch {
 
-                 return GetDefaultValue(destinationType);
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// Gets the default value for a type.
 
-         /// </summary>
 
-         /// <param name="type">The type.</param>
 
-         /// <returns>The default value.</returns>
 
-         public static object GetDefaultValue(Type type) {
 
- #if WinRT || XFORMS
 
-             var typeInfo = type.GetTypeInfo();
 
-             return typeInfo.IsClass || typeInfo.IsInterface ? null : System.Activator.CreateInstance(type);
 
- #else
 
-             return type.IsClass || type.IsInterface ? null : Activator.CreateInstance(type);
 
- #endif
 
-         }
 
-     }
 
- }
 
 
  |