示例#1
0
        /// <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);
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
 /// <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);
 }
示例#5
0
        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);
        }
示例#6
0
        /// <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);
        }
示例#8
0
 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;
 }
示例#9
0
 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;
 }
示例#10
0
 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;
 }
示例#11
0
 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;
 }
示例#12
0
        /// <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);
            }
        }