Silverlightクライアントでは、実行時にクラスを生成してDataGridにバインドします。私はthisブログの投稿に基づいてメソッドを使用しています。 これで、プロパティセットでValidatePropertyを呼び出すことで、DataGridのセル検証を使用したいと考えています。しかし、プロパティは実行時に生成されるので、私はこれをReflection.Emitで行う必要があります。プロパティ設定ツールで検証コードを発行するには
これは私がILで生成するC#のである:
public int TestProperty
{
get { return testProperty; }
set
{
Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "TestProperty" });
testProperty = value;
}
}
これは、ILでどのようにILspy逆コンパイル、この方法です:
.property int32 TestProperty
{
.get public hidebysig specialname
instance int32 get_TestProperty() cil managed
{
// Method begins at RVA 0x224c
// Code size 12 (0xc)
.maxstack 1
.locals init (
[0] int32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld int32 class SilverlightApplication2.testclass::testProperty
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // End of method testclass.get_TestProperty
.set public hidebysig specialname
instance void set_TestProperty (
int32 value
) cil managed
{
// Method begins at RVA 0x2264
// Code size 43 (0x2b)
.maxstack 5
.locals init (
[0] class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext
)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: box int32
IL_0007: ldarg.0
IL_0008: ldnull
IL_0009: ldnull
IL_000a: newobj instance void [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext::.ctor(object, class [mscorlib]System.IServiceProvider, class [mscorlib]System.Collections.Generic.IDictionary`2<object, object>)
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: ldstr "TestProperty"
IL_0016: callvirt instance void [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext::set_MemberName(string)
IL_001b: nop
IL_001c: ldloc.0
IL_001d: call void [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.Validator::ValidateProperty(object, class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext)
IL_0022: nop
IL_0023: ldarg.0
IL_0024: ldarg.1
IL_0025: stfld int32 class SilverlightApplication2.testclass::testProperty
IL_002a: ret
} // End of method testclass.set_TestProperty
}
そしてこれはリフレクションでそれを書き込もうと私です。 Emitter:
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Box, typeof(Int32));
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldnull);
setIL.Emit(OpCodes.Ldnull);
Type[] types = new Type[3];
types[0] = typeof(object);
types[1] = typeof(IServiceProvider);
types[2] = typeof(IDictionary<object, object>);
setIL.Emit(OpCodes.Newobj, typeof(System.ComponentModel.DataAnnotations.ValidationContext).GetConstructor(types));
setIL.Emit(OpCodes.Stloc_0);
setIL.Emit(OpCodes.Ldloc_0);
setIL.Emit(OpCodes.Ldstr, "TestProperty");
setIL.Emit(OpCodes.Callvirt, typeof(System.ComponentModel.DataAnnotations.ValidationContext).GetMethod("set_MemberName"));
setIL.Emit(OpCodes.Ldloc_0);
setIL.Emit(OpCodes.Call, typeof(System.ComponentModel.DataAnnotations.Validator).GetMethod("ValidateProperty"));
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Stfld, fieldBuilder);
setIL.Emit(OpCodes.Ret);
これは私のコードの一部です。これはValidator.Validaなしで動作させることができましたtePropertyに最後の4行のコードを追加します。他の16行では、検証機能を追加したいが、今は 'Operationがランタイム'例外を不安定にする可能性がある。
あなたはアスペクト指向プログラミングに見たことがありますか? http://en.wikipedia.org/wiki/Aspect-oriented_programming – MattDavey