コード例 #1
0
 internal Factory(DynamicAssembly ab)
 {
     this.assembly  = ab;
     this.OfProxies = new Proxies(this);
     this.OfStubs   = new Stubs(this);
     this.Dynamic   = new Dynamic(this);
 }
コード例 #2
0
ファイル: Proxies.cs プロジェクト: milleniumbug/VanceStubbs
            public Func <TWrappedType, TState, TWrappedType> Create()
            {
                var tb           = this.ab.Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class);
                var abstractType = typeof(TWrappedType);

                tb.AddInterfaceImplementation(abstractType);

                var postEntryDelegateField = this.postEntry == null ? null : tb.DefineField(
                    nameof(this.postEntry),
                    this.postEntry.GetType(),
                    FieldAttributes.Private | FieldAttributes.Static);

                var preExitDelegateField = this.preExit == null ? null : tb.DefineField(
                    nameof(this.preExit),
                    this.preExit.GetType(),
                    FieldAttributes.Private | FieldAttributes.Static);

                var targetField = tb.DefineField(
                    "target",
                    abstractType,
                    FieldAttributes.InitOnly | FieldAttributes.Private);

                var stateField = tb.DefineField(
                    "state",
                    typeof(TState),
                    FieldAttributes.InitOnly | FieldAttributes.Private);

                {
                    var constructor = tb.DefineConstructor(
                        MethodAttributes.Public,
                        CallingConventions.HasThis,
                        new Type[] { targetField.FieldType, stateField.FieldType });
                    var il = constructor.GetILGenerator();
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Stfld, targetField);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Stfld, stateField);
                    il.Emit(OpCodes.Ret);
                }

                this.ab.ImplementAbstractMethods(tb, abstractType, ImplementAsDecorator, false);
                var typeInfo = tb.CreateTypeInfo();
                var runtimePostEntryField = typeInfo.GetField(nameof(this.postEntry), BindingFlags.Static | BindingFlags.NonPublic);

                runtimePostEntryField?.SetValue(typeInfo, this.postEntry);
                var runtimePreExitField = typeInfo.GetField(nameof(this.preExit), BindingFlags.Static | BindingFlags.NonPublic);

                runtimePreExitField?.SetValue(typeInfo, this.preExit);
                return((target, state) => (TWrappedType)this.ab.ActivateInstance(typeInfo, target, state));

                void ImplementAsDecorator(MethodInfo method, ILGenerator il)
                {
                    il.DeclareLocal(typeof(object[]));
                    if (method.ReturnType != typeof(void))
                    {
                        il.DeclareLocal(method.ReturnType);
                    }

                    var parameters = method.GetParameters();
                    var length     = parameters.Length;

                    if (postEntryDelegateField != null)
                    {
                        il.Emit(OpCodes.Ldc_I4, length);
                        il.Emit(OpCodes.Newarr, typeof(object));

                        for (int i = 0; i < length; ++i)
                        {
                            il.Emit(OpCodes.Dup);
                            il.Emit(OpCodes.Ldc_I4, i);
                            il.Emit(OpCodes.Ldarg, (short)(i + 1));
                            DynamicAssembly.TypeErase(il, parameters[i].ParameterType);
                            il.Emit(OpCodes.Stelem_Ref);
                        }

                        il.Emit(OpCodes.Stloc_0);
                        il.Emit(OpCodes.Ldsfld, postEntryDelegateField);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, targetField);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, stateField);
                        il.Emit(OpCodes.Ldloc_0);
                        il.EmitCall(OpCodes.Callvirt, postEntryDelegateField.FieldType.GetMethod("Invoke"), null);

                        for (int i = 0; i < length; ++i)
                        {
                            il.Emit(OpCodes.Ldloc_0);
                            il.Emit(OpCodes.Ldc_I4, i);
                            il.Emit(OpCodes.Ldelem_Ref);
                            DynamicAssembly.TypeRestore(il, parameters[i].ParameterType);
                            il.Emit(OpCodes.Starg, (short)(i + 1));
                        }
                    }

                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, targetField);
                    DynamicAssembly.UnrollParameterLoading(il, 1, length);
                    il.EmitCall(OpCodes.Callvirt, method, null);

                    if (preExitDelegateField != null)
                    {
                        il.Emit(OpCodes.Stloc_1);
                        il.Emit(OpCodes.Ldsfld, preExitDelegateField);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, targetField);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, stateField);
                        il.Emit(OpCodes.Ldloc_1);
                        DynamicAssembly.TypeErase(il, method.ReturnType);
                        il.EmitCall(OpCodes.Callvirt, preExitDelegateField.FieldType.GetMethod("Invoke"), null);
                        DynamicAssembly.TypeRestore(il, method.ReturnType);
                    }

                    il.Emit(OpCodes.Ret);
                }
            }
コード例 #3
0
ファイル: Proxies.cs プロジェクト: milleniumbug/VanceStubbs
 internal InstantiatedStatefulBuilder(DynamicAssembly ab)
 {
     this.ab = ab;
 }
コード例 #4
0
ファイル: Proxies.cs プロジェクト: milleniumbug/VanceStubbs
 internal InstantiatedStatelessBuilder(DynamicAssembly ab)
 {
     this.ab      = ab;
     this.builder = new InstantiatedStatefulBuilder <TWrappedType, object>(ab);
 }
コード例 #5
0
ファイル: Proxies.cs プロジェクト: milleniumbug/VanceStubbs
 internal ProxyBuilder(DynamicAssembly ab)
 {
     this.ab = ab;
 }
コード例 #6
0
ファイル: Proxies.cs プロジェクト: milleniumbug/VanceStubbs
 internal Proxies(Factory factory)
 {
     this.factory = factory;
     this.ab      = this.factory.Assembly;
 }