/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }