CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
Utilities.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="Utilities.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Contains utility methods used by the</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Reflection;
10using Csla.Reflection;
11using System.ComponentModel;
12using Csla.Properties;
13
14namespace Csla
15{
20 public static class Utilities
21 {
22 #region Replacements for VB runtime functionality
23
28 public static bool IsNumeric(object value)
29 {
30 double dbl;
31 return double.TryParse(value.ToString(), System.Globalization.NumberStyles.Any,
32 System.Globalization.NumberFormatInfo.InvariantInfo, out dbl);
33 }
34
44 public static object CallByName(
45 object target, string methodName, CallType callType,
46 params object[] args)
47 {
48 switch (callType)
49 {
50 case CallType.Get:
51 {
52 return MethodCaller.CallPropertyGetter(target, methodName);
53 }
54 case CallType.Let:
55 case CallType.Set:
56 {
57 MethodCaller.CallPropertySetter(target, methodName, args[0]);
58 return null;
59 }
60 case CallType.Method:
61 {
62 return MethodCaller.CallMethod(target, methodName, args);
63 }
64 }
65 return null;
66 }
67
68 #endregion
69
76 public static Type GetPropertyType(Type propertyType)
77 {
78 Type type = propertyType;
79 if (type.IsGenericType &&
80 (type.GetGenericTypeDefinition() == typeof(Nullable<>)))
81 return Nullable.GetUnderlyingType(type);
82 return type;
83 }
84
90 public static Type GetChildItemType(Type listType)
91 {
92 Type result = null;
93 if (listType.IsArray)
94 result = listType.GetElementType();
95 else
96 {
97 var indexer =
98 (DefaultMemberAttribute)Attribute.GetCustomAttribute(
99 listType, typeof(DefaultMemberAttribute));
100 if (indexer != null)
101 {
102 foreach (PropertyInfo prop in listType.GetProperties(
103 BindingFlags.Public |
104 BindingFlags.Instance |
105 BindingFlags.FlattenHierarchy))
106 {
107 if (prop.Name == indexer.MemberName)
108 result = Utilities.GetPropertyType(prop.PropertyType);
109 }
110 }
111 if (result == null)
112 {
113 result = listType.GetMethod("get_Item")?.ReturnType;
114 }
115 }
116 return result;
117 }
118
119 #region CoerceValue
120
153 public static object CoerceValue(Type desiredType, Type valueType, object oldValue, object value)
154 {
155 if (desiredType.IsAssignableFrom(valueType))
156 {
157 // types match, just return value
158 return value;
159 }
160 else
161 {
162 if (desiredType.IsGenericType)
163 {
164 if (desiredType.GetGenericTypeDefinition() == typeof(Nullable<>))
165 if (value == null)
166 return null;
167 else if (valueType.Equals(typeof(string)) && System.Convert.ToString(value) == string.Empty)
168 return null;
169 }
170 desiredType = Utilities.GetPropertyType(desiredType);
171 }
172
173 if (desiredType.IsEnum)
174 {
175 if (value is byte? && ((byte?) value).HasValue)
176 return System.Enum.Parse(desiredType, ((byte?) value).Value.ToString());
177 if (value is short? && ((short?) value).HasValue)
178 return System.Enum.Parse(desiredType, ((short?) value).Value.ToString());
179 if (value is int? && ((int?) value).HasValue)
180 return System.Enum.Parse(desiredType, ((int?) value).Value.ToString());
181 if (value is long? && ((long?) value).HasValue)
182 return System.Enum.Parse(desiredType, ((long?) value).Value.ToString());
183 }
184
185 if (desiredType.IsEnum &&
186 (valueType.Equals(typeof(string)) || Enum.GetUnderlyingType(desiredType).Equals(valueType)))
187 return System.Enum.Parse(desiredType, value.ToString());
188
189 if (desiredType.Equals(typeof(SmartDate)) && oldValue != null)
190 {
191 if (value == null)
192 value = string.Empty;
193 var tmp = (SmartDate)oldValue;
194 if (valueType.Equals(typeof(DateTime)))
195 tmp.Date = (DateTime)value;
196 else
197 tmp.Text = value.ToString();
198 return tmp;
199 }
200
201 if ((desiredType.IsPrimitive || desiredType.Equals(typeof(decimal))) &&
202 valueType.Equals(typeof(string)) && string.IsNullOrEmpty((string)value))
203 value = 0;
204
205 try
206 {
207 if (desiredType.Equals(typeof(string)) && value != null)
208 {
209 return value.ToString();
210 }
211 else
212 return Convert.ChangeType(value, desiredType);
213 }
214 catch
215 {
216 TypeConverter cnv = TypeDescriptor.GetConverter(desiredType);
217 TypeConverter cnv1 = TypeDescriptor.GetConverter(valueType);
218 if (cnv != null && cnv.CanConvertFrom(valueType))
219 return cnv.ConvertFrom(value);
220 else if (cnv1 != null && cnv1.CanConvertTo(desiredType))
221 return cnv1.ConvertTo(value, desiredType);
222 else
223 throw;
224 }
225 }
226
259 public static D CoerceValue<D>(Type valueType, object oldValue, object value)
260 {
261 return (D)(CoerceValue(typeof(D), valueType, oldValue, value));
262 }
263
264 #endregion
265
266 internal static void ThrowIfAsyncMethodOnSyncClient(ApplicationContext applicationContext, bool isSync, System.Reflection.MethodInfo method)
267 {
268 if (isSync
269 && applicationContext.ExecutionLocation != ApplicationContext.ExecutionLocations.Server
270 && MethodCaller.IsAsyncMethod(method))
271 {
272 throw new NotSupportedException(string.Format(Resources.AsyncMethodOnSyncClientNotAllowed, method.Name));
273 }
274 }
275
284 internal static void ThrowIfAsyncMethodOnSyncClient(ApplicationContext applicationContext, bool isSync, object obj, string methodName)
285 {
286 if (isSync
287 && applicationContext.ExecutionLocation != ApplicationContext.ExecutionLocations.Server
288 && MethodCaller.IsAsyncMethod(obj, methodName))
289 {
290 throw new NotSupportedException(string.Format(Resources.AsyncMethodOnSyncClientNotAllowed, methodName));
291 }
292 }
293
304 internal static void ThrowIfAsyncMethodOnSyncClient(ApplicationContext applicationContext, bool isSync, object obj, string methodName, params object[] parameters)
305 {
306 if (isSync
307 && applicationContext.ExecutionLocation != ApplicationContext.ExecutionLocations.Server
308 && MethodCaller.IsAsyncMethod(obj, methodName, parameters))
309 {
310 throw new NotSupportedException(string.Format(Resources.AsyncMethodOnSyncClientNotAllowed, methodName));
311 }
312 }
313 }
314
319 public enum CallType
320 {
324 Get,
328 Let,
332 Method,
336 Set
337 }
338}
A strongly-typed resource class, for looking up localized strings, etc.
static string AsyncMethodOnSyncClientNotAllowed
Looks up a localized string similar to Cannot synchronously call {0} which is an asynchronous method.
CallType
Valid options for calling a property or method via the Csla.Utilities.CallByName method.
Definition: Utilities.cs:320
@ Method
Invokes a method.
@ Set
Sets a value into a property.
@ Get
Gets a value from a property.
@ Let
Sets a value into a property.