jeudi 26 novembre 2015

Silverlight - Reflection - dynamic class - Inject code in the setter

In Silverlight, I use a Dynamic class. I want to call boolean function before set property, for example :

Private _MyVar as Object
Public Property MyVar as Object
    Get
        return _MyVar
    End Get
    Set(value as Object)
        If IsUpdateProp(value,"MyVar") Then _myVar = value
    End Set
End Property

Private Function IsUpdateProp(value as Object, key as string) as Boolean
     If value Is Nothing AndAlso GetValueProperty(key) Is Nothing
                OrElse (value IsNot Nothing AndAlso 
                   GetValueProperty(key) IsNot Nothing AndAlso 
                          value.Equals(GetValueProperty(key))) Then
         Return False
     End If

     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(key))
     Return True`
End Function

I want to make this with reflection, my code :

Dim dp As DynamicProperty = properties(i)
Dim fb As FieldBuilder = tb.DefineField("_" & dp.Name, dp.Type,
            FieldAttributes.Private)
Dim pb As PropertyBuilder = tb.DefineProperty(dp.Name, 
             PropertyAttributes.HasDefault, dp.Type, Nothing)
Dim isModify = GetType(Dynamic.DynamicClass).GetMethod("SetModifyField",
                  New Type() {GetType(Object), GetType(String)})
Dim mbSet As MethodBuilder = tb.DefineMethod("set_" & dp.Name, 
                    MethodAttributes.Public Or 
                        MethodAttributes.SpecialName Or 
                           MethodAttributes.HideBySig, 
                                Nothing, New Type() {dp.Type})
Dim genSet As ILGenerator = mbSet.GetILGenerator()
Dim mLabel = genSet.DefineLabel

genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Ldarg_0)
genSet.Emit(OpCodes.Ldarg_1)
genSet.Emit(OpCodes.Box, dp.Type)
genSet.Emit(OpCodes.Ldstr, dp.Name)
genSet.Emit(OpCodes.Call, isModify)
genSet.Emit(OpCodes.Call, GetType(Convert).GetMethod("ToBoolean", 
                                    New   Type() {GetType(Object)}))
genSet.Emit(OpCodes.Stloc_0)
genSet.Emit(OpCodes.Ldloc_0)
genSet.Emit(OpCodes.Brfalse_S, mLabel)
genSet.Emit(OpCodes.Ldarg_0)
genSet.Emit(OpCodes.Ldarg_1)
genSet.Emit(OpCodes.Stfld, fb)
genSet.MarkLabel(mLabel)
genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Nop)
genSet.Emit(OpCodes.Ret)

At runtime, when I call setvalue on my property I get this error message:

System.Security.VerificationException: Cette opération pourrait déstabiliser le runtime." & vbCrLf & " à DynamicClass1.set_MyVar(Nullable`1 )

Thanks





Aucun commentaire:

Enregistrer un commentaire