/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="parameters"></param> /// <returns></returns> public static IDynamicConstructor GetDynamicConstructor(Type objectType, params Type[] parameterTypes) { if (parameterTypes == null) { parameterTypes = Type.EmptyTypes; } MethodCacheKey key = MethodCacheKey.Create(objectType.FullName, objectType.Name, parameterTypes); IDynamicConstructor dynamicConstructor = null; if (!_dynamicConstructors.TryGetValue(key, out dynamicConstructor)) { lock (_syncObj) { if (!_dynamicConstructors.TryGetValue(key, out dynamicConstructor)) { ConstructorInfo ctor = objectType.GetConstructor(parameterTypes); if (ctor != null) { dynamicConstructor = DynamicConstructor.Create(ctor); if (dynamicConstructor != null) { _dynamicConstructors.Add(key, dynamicConstructor); } } } } } return(dynamicConstructor); }
public static DataPortalMethodInfo GetMethodInfo(Type objectType, string methodName, params object[] parameters) { var key = new MethodCacheKey(objectType.FullName, methodName, MethodCaller.GetParameterTypes(parameters)); DataPortalMethodInfo result = null; var found = false; try { found = _cache.TryGetValue(key, out result); } catch { /* failure will drop into !found block */ } if (!found) { lock (_cache) { if (!_cache.TryGetValue(key, out result)) { result = new DataPortalMethodInfo(MethodCaller.GetMethod(objectType, methodName, parameters)); _cache.Add(key, result); } } } return(result); }
/// <summary> /// /// </summary> /// <param name="objectType"></param> /// <param name="types"></param> /// <returns></returns> public static IDynamicMethod GetDynamicMethod(Type objectType, string methodName, params object[] parameters) { MethodCacheKey key = MethodCacheKey.Create(objectType, methodName, parameters); IDynamicMethod dynamicMethod = null; if (!_dynamicMethods.TryGetValue(key, out dynamicMethod)) { lock (_dynamicMethods) { if (!_dynamicMethods.TryGetValue(key, out dynamicMethod)) { MethodInfo methodInfo = GetMethod(objectType, methodName, parameters); if (methodInfo != null) { dynamicMethod = DynamicMethod.Create(methodInfo); if (dynamicMethod != null) { _dynamicMethods.Add(key, dynamicMethod); } } } } } return(dynamicMethod); }
/// <seealso cref="java.lang.Object.equals(java.lang.Object)"> /// </seealso> public override bool Equals(object o) { /** * note we skip the null test for methodName and params * due to the earlier test in the constructor */ if (o is MethodCacheKey) { MethodCacheKey other = (MethodCacheKey)o; if (params_Renamed.Length == other.params_Renamed.Length && methodName.Equals(other.methodName)) { for (int i = 0; i < params_Renamed.Length; ++i) { if (params_Renamed[i] == null) { if (params_Renamed[i] != other.params_Renamed[i]) { return(false); } } else if (!params_Renamed[i].Equals(other.params_Renamed[i])) { return(false); } } return(true); } } return(false); }
public static DataPortalMethodInfo GetMethodInfo(Type objectType, string methodName, params object[] parameters) { var key = new MethodCacheKey(objectType.FullName, methodName, MethodCaller.GetParameterTypes(parameters)); DataPortalMethodInfo result = null; var found = false; #if NET5_0_OR_GREATER try { found = _cache.TryGetValue(key, out var methodInfo); result = methodInfo?.Item2; } catch { /* failure will drop into !found block */ } if (!found) { lock (_cache) { found = _cache.TryGetValue(key, out var methodInfo); result = methodInfo?.Item2; if (!found) { result = new DataPortalMethodInfo(MethodCaller.GetMethod(objectType, methodName, parameters)); var cacheInstance = AssemblyLoadContextManager.CreateCacheInstance(objectType, result, OnAssemblyLoadContextUnload); _cache.Add(key, cacheInstance); } } } #else try { found = _cache.TryGetValue(key, out result); } catch { /* failure will drop into !found block */ } if (!found) { lock (_cache) { if (!_cache.TryGetValue(key, out result)) { result = new DataPortalMethodInfo(MethodCaller.GetMethod(objectType, methodName, parameters)); _cache.Add(key, result); } } } #endif return(result); }
/// <summary> /// /// </summary> /// <param name="objectType"></param> /// <param name="propertyName"></param> /// <returns></returns> public static IDynamicProperty GetDynamicProperty(Type objectType, string propertyName) { Guard.ArgumentNotNull(objectType, "objectType"); Guard.ArgumentNotNullOrEmpty(propertyName, "propertyName"); MethodCacheKey key = MethodCacheKey.Create(objectType.FullName, propertyName, TypeHelper.GetParameterTypes()); IDynamicProperty dynamicProperty = null; if (!_dynamicProperties.TryGetValue(key, out dynamicProperty)) { lock (_syncObj) { if (!_dynamicProperties.TryGetValue(key, out dynamicProperty)) { PropertyInfo propertyInfo = objectType.GetProperty(propertyName, propertyFlags); if (propertyInfo == null) { ThrowHelper.ThrowInvalidOperationException(ReflectionSR.PropertyNotFound, objectType.FullName, propertyName); } dynamicProperty = DynamicProperty.Create(propertyInfo); _dynamicProperties.Add(key, dynamicProperty); } } } return(dynamicProperty); }
public static DataPortalMethodInfo GetMethodInfo(Type objectType, string methodName, params object[] parameters) { var key = new MethodCacheKey(objectType.Name, methodName, MethodCaller.GetParameterTypes(parameters)); DataPortalMethodInfo result = null; if (!_cache.TryGetValue(key, out result)) { lock (_cache) { if (!_cache.TryGetValue(key, out result)) { result = new DataPortalMethodInfo(MethodCaller.GetMethod(objectType, methodName, parameters)); _cache.Add(key, result); } } } return(result); }
private static DynamicMethodHandle GetCachedMethod(Type objType, string method, params Type[] parameters) { var key = new MethodCacheKey(objType, method, parameters); DynamicMethodHandle mh = null; if (!_methodCache.TryGetValue(key, out mh)) { MethodInfo info = GetMethod(objType, method, parameters); if (info != null) { lock (_methodCache) { if (!_methodCache.TryGetValue(key, out mh)) { mh = new DynamicMethodHandle(info); _methodCache.Add(key, mh); } } } } return mh; }
private static DynamicMethodHandle GetCachedMethod(MethodInfo info) { var key = new MethodCacheKey(info); DynamicMethodHandle mh = null; if (!_methodCache.TryGetValue(key, out mh)) { lock (_methodCache) { if (!_methodCache.TryGetValue(key, out mh)) { mh = new DynamicMethodHandle(info); _methodCache.Add(key, mh); } } } return mh; }
internal static DynamicMemberHandle GetCachedProperty(Type objectType, string propertyName) { var key = new MethodCacheKey(objectType, propertyName, new Type[] { typeof(object) }); DynamicMemberHandle mh = null; if (!_memberCache.TryGetValue(key, out mh)) { lock (_memberCache) { if (!_memberCache.TryGetValue(key, out mh)) { PropertyInfo info = objectType.GetProperty(propertyName, propertyFlags); if (info == null) throw new InvalidOperationException( string.Format("Member not found on object ({0})", propertyName)); mh = new DynamicMemberHandle(info); _memberCache.Add(key, mh); } } } return mh; }
internal static DynamicMemberHandle GetCachedField(Type objectType, string fieldName) { var key = new MethodCacheKey(objectType, fieldName, new Type[] { typeof(object) }); DynamicMemberHandle mh = null; if (!_memberCache.TryGetValue(key, out mh)) { lock (_memberCache) { if (!_memberCache.TryGetValue(key, out mh)) { FieldInfo info = objectType.GetField(fieldName, fieldFlags); if (info == null) throw new InvalidOperationException( string.Format("Resources.MemberNotFoundException:{0}", fieldName)); mh = new DynamicMemberHandle(info); _memberCache.Add(key, mh); } } } return mh; }
/// <summary> invokes the method. Returns null if a problem, the /// parameters return if the method returns something, or /// an empty string "" if the method returns void /// </summary> /// <param name="instance"> /// </param> /// <param name="context"> /// </param> /// <returns> Result or null. /// </returns> /// <throws> MethodInvocationException </throws> public override object Execute(object o, IInternalContextAdapter context) { /* * new strategy (strategery!) for introspection. Since we want * to be thread- as well as context-safe, we *must* do it now, * at execution time. There can be no in-node caching, * but if we are careful, we can do it in the context. */ IVelMethod method = null; object[] params_Renamed = new object[paramCount]; try { /* * sadly, we do need recalc the values of the args, as this can * change from visit to visit */ System.Type[] paramClasses = paramCount > 0 ? new System.Type[paramCount] : new System.Collections.Generic.List <Type>().ToArray(); for (int j = 0; j < paramCount; j++) { params_Renamed[j] = GetChild(j + 1).Value(context); if (params_Renamed[j] != null) { paramClasses[j] = params_Renamed[j].GetType(); } } /* * check the cache */ MethodCacheKey mck = new MethodCacheKey(methodName, paramClasses); IntrospectionCacheData icd = context.ICacheGet(mck); /* * like ASTIdentifier, if we have cache information, and the * Class of Object instance is the same as that in the cache, we are * safe. */ if (icd != null && (o != null && icd.ContextData == o.GetType())) { /* * Get the method from the cache */ method = (IVelMethod)icd.Thingy; } else { /* * otherwise, do the introspection, and then * cache it */ method = rsvc.Uberspect.GetMethod(o, methodName, params_Renamed, new Info(TemplateName, Line, Column)); if ((method != null) && (o != null)) { icd = new IntrospectionCacheData(); icd.ContextData = o.GetType(); icd.Thingy = method; context.ICachePut(mck, icd); } } /* * if we still haven't gotten the method, either we are calling * a method that doesn't exist (which is fine...) or I screwed * it up. */ if (method == null) { if (strictRef) { // Create a parameter list for the exception Error message System.Text.StringBuilder plist = new System.Text.StringBuilder(); for (int i = 0; i < params_Renamed.Length; i++) { System.Type param = paramClasses[i]; plist.Append(param == null ? "null" : param.FullName); if (i < params_Renamed.Length - 1) { plist.Append(", "); } } throw new MethodInvocationException("Object '" + o.GetType().FullName + "' does not contain method " + methodName + "(" + plist + ")", null, methodName, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column); } else { return(null); } } } catch (MethodInvocationException mie) { /* * this can come from the doIntrospection(), as the arg values * are evaluated to find the right method signature. We just * want to propogate it here, not do anything fancy */ throw mie; } /** * pass through application level runtime exceptions */ catch (System.SystemException e) { throw e; } catch (System.Exception e) { /* * can come from the doIntropection() also, from Introspector */ string msg = "ASTMethod.Execute() : exception from introspection"; log.Error(msg, e); throw new VelocityException(msg, e); } try { /* * Get the returned object. It may be null, and that is * valid for something declared with a void return type. * Since the caller is expecting something to be returned, * as long as things are peachy, we can return an empty * String so ASTReference() correctly figures out that * all is well. */ object obj = method.Invoke(o, params_Renamed); if (obj == null) { if (method.ReturnType == System.Type.GetType("System.Void")) { return(""); } } return(obj); } catch (System.Reflection.TargetInvocationException ite) { return(HandleInvocationException(o, context, ite.GetBaseException())); } /** Can also be thrown by method invocation **/ catch (System.ArgumentException t) { return(HandleInvocationException(o, context, t)); } /** * pass through application level runtime exceptions */ catch (System.SystemException e) { throw e; } catch (System.Exception e) { string msg = "ASTMethod.Execute() : exception invoking method '" + methodName + "' in " + o.GetType(); log.Error(msg, e); throw new VelocityException(msg, e); } }