예제 #1
0
        /// <summary>
        /// 创建动态属性赋值的委托
        /// </summary>
        /// <returns>动态属性赋值的委托</returns>
        /// <param name="property">属性</param>
        public static DynamicPropertySetHandler CreateDynamicPropertySetHandler(PropertyInfo property)
        {
            // 如果缓存中存在
            if (dynamicPropertySetHandlers.ContainsKey(property))
            {
                return(dynamicPropertySetHandlers[property]);
            }

            #region Emit 由于老是有安全性问题,使用 Expression 替代
            //DynamicMethod method = new DynamicMethod( string.Format( "DynamicPropertySet{0}", Guid.NewGuid() ), null, new[] { typeof( object ), typeof( object ) }, true );

            //ILGenerator gen = method.GetILGenerator();

            //Type parameterType = property.GetSetMethod().GetParameters()[0].ParameterType;

            //gen.DeclareLocal( parameterType );

            //gen.Emit( OpCodes.Ldarg_0 );
            //gen.Emit( OpCodes.Castclass, property.DeclaringType );
            //gen.Emit( OpCodes.Ldarg_1 );

            //if( parameterType.IsValueType )
            //{
            //    gen.Emit( OpCodes.Unbox, parameterType );

            //    if( typeMap[parameterType] == null )
            //    {
            //        gen.Emit( OpCodes.Ldobj, parameterType );
            //    }
            //    else
            //    {
            //        OpCode load = (OpCode)typeMap[parameterType];
            //        gen.Emit( load );
            //    }
            //}
            //else
            //{
            //    gen.Emit( OpCodes.Castclass, parameterType );
            //}

            //gen.EmitCall( OpCodes.Callvirt, property.GetSetMethod(), null );

            //gen.Emit( OpCodes.Ret );
            #endregion

            var instance     = Expression.Parameter(typeof(object));
            var castInstance = Expression.Convert(instance, property.DeclaringType);

            var value     = Expression.Parameter(typeof(object));
            var castValue = Expression.Convert(value, property.PropertyType);

            var assign = Expression.Assign(castInstance, castValue);

            DynamicPropertySetHandler handler = Expression.Lambda <DynamicPropertySetHandler>(assign, instance, value).Compile();

            dynamicPropertySetHandlers.Add(property, handler);

            return(handler);
        }
예제 #2
0
        /// <summary>
        /// 创建动态属性赋值的委托
        /// </summary>
        /// <returns>动态属性赋值的委托</returns>
        /// <param name="property">属性</param>
        public static DynamicPropertySetHandler CreateDynamicPropertySetHandler(PropertyInfo property)
        {
            // 如果缓存中存在
            if (dynamicPropertySetHandlers.ContainsKey(property))
            {
                return(dynamicPropertySetHandlers[property]);
            }

            DynamicMethod method = new DynamicMethod(string.Format("DynamicPropertySet{0}", Guid.NewGuid()), null, new[] { typeof(object), typeof(object) }, true);

            ILGenerator gen = method.GetILGenerator();

            Type parameterType = property.GetSetMethod().GetParameters()[0].ParameterType;

            gen.DeclareLocal(parameterType);

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, property.DeclaringType);
            gen.Emit(OpCodes.Ldarg_1);

            if (parameterType.IsValueType)
            {
                gen.Emit(OpCodes.Unbox, parameterType);

                if (typeMap[parameterType] == null)
                {
                    gen.Emit(OpCodes.Ldobj, parameterType);
                }
                else
                {
                    OpCode load = (OpCode)typeMap[parameterType];
                    gen.Emit(load);
                }
            }
            else
            {
                gen.Emit(OpCodes.Castclass, parameterType);
            }

            gen.EmitCall(OpCodes.Callvirt, property.GetSetMethod(), null);

            gen.Emit(OpCodes.Ret);

            DynamicPropertySetHandler handler = (DynamicPropertySetHandler)method.CreateDelegate(typeof(DynamicPropertySetHandler));

            dynamicPropertySetHandlers.Add(property, handler);

            return(handler);
        }
예제 #3
0
        public void SetValue(Object obj, Object value, Object[] index)
        {
            if (setHandler != null)
            {
                setHandler(obj, value, index);
                return;
            }

            Int32 moduleKey  = info.Module.GetHashCode();
            Int32 handlerKey = info.MetadataToken;

            setHandler = DynamicCacheFactory <DynamicPropertySetHandler> .Caches
                         .GetOrAdd(moduleKey, innerModuleKey => new ConcurrentDictionary <Int32, DynamicPropertySetHandler>())
                         .GetOrAdd(handlerKey, innerHandlerKey => DynamicMethodFactory.CreateSetHandler(type, info));

            setHandler(obj, value, index);
        }
예제 #4
0
        /// <summary>
        /// 将指定的值写入到对象的属性中
        /// </summary>
        /// <param name="propertyInfo">属性的PropertyInfo</param>
        /// <param name="obj">待写入的对象</param>
        /// <param name="value">将写入的值</param>
        /// <param name="index">如果是一个索引Property,请指定索引值,否则,指定null</param>
        public static void SetValue(PropertyInfo propertyInfo, object obj, object value, object[] index)
        {
            DynamicPropertySetHandler handler = null;
            int key = propertyInfo.MetadataToken;

#if Server
            handler = CachePropertySet.GetOrAdd(key, new Func <int, DynamicPropertySetHandler>((i) => CreateSetHandler(propertyInfo)));
#else
            lock (CachePropertySet)
            {
                if (CachePropertySet.ContainsKey(key))
                {
                    handler = CachePropertySet[key];
                }
                else
                {
                    handler = CreateSetHandler(propertyInfo);
                    CachePropertySet.Add(key, handler);
                }
            }
#endif

            handler(obj, value, index);
        }
예제 #5
0
        /// <summary>
        /// 通过 Emit 方式设置属性值
        /// </summary>
        /// <param name="property"></param>
        /// <param name="instance"></param>
        /// <param name="value"></param>
        public static void EmitSetValue(this PropertyInfo property, object instance, object value)
        {
            DynamicPropertySetHandler handler = DynamicHelper.CreateDynamicPropertySetHandler(property);

            handler(instance, value);
        }