public object CreateWrapperFromType(Type templateType, MethodToProxify[] methodsToProxify, PropertyToProxify[] propsToProxify = null) { Trace.Assert(templateType != null); Trace.Assert(methodsToProxify != null && methodsToProxify.Length > 0); string ns = templateType.Assembly.FullName; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(ns), SAVE_TEST_DLL ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = SAVE_TEST_DLL ? assemblyBuilder.DefineDynamicModule(ns, "testil.dll") : assemblyBuilder.DefineDynamicModule(ns); TypeBuilder wrapperBuilder = moduleBuilder.DefineType(templateType.FullName + "Proxy", TypeAttributes.Public, typeof(JishProxy), new Type[0]); CreateProxyConstructor(wrapperBuilder); for (int i = 0; i < methodsToProxify.Length; i++) { CreateProxyMethod(wrapperBuilder, i, methodsToProxify.ElementAt(i)); } if (propsToProxify != null) { for (int i = 0; i < propsToProxify.Length; i++) { GenerateProxyProperty(wrapperBuilder, i, propsToProxify.ElementAt(i)); } } Type wrapperType = wrapperBuilder.CreateType(); if (SAVE_TEST_DLL) assemblyBuilder.Save("testil.dll"); return Activator.CreateInstance(wrapperType, new object[] { methodsToProxify }); }
private bool IsValidDelegateMethod(MethodToProxify mp) { ParameterInfo[] parameters = mp.RealMethod.GetParameters(); ParameterInfo[] delegateParams = parameters.Where(IsParamDelegate).ToArray(); if (delegateParams.Length == 0) { return(false); } if (delegateParams.Length > 1) { throw new NotSupportedException("Only single delegate callback methods supported. I.e. Cannot have a callback and an errback."); } return(true); }
private void CreateProxyMethod(TypeBuilder wrapperBuilder, int thissIdx, MethodToProxify methodToProxify) { Trace.Assert(wrapperBuilder != null); Trace.Assert(thissIdx >= 0); Trace.Assert(methodToProxify != null); MethodInfo realMethod = methodToProxify.RealMethod; ParameterInfo[] realParams = realMethod.GetParameters(); IList <Type[]> parameterCombinations = GetAllParameterCombinations(realMethod); foreach (Type[] parameters in parameterCombinations) { var methodBuilder = wrapperBuilder.DefineMethod(GetProxMethodName(methodToProxify, realMethod), MethodAttributes.Public | MethodAttributes.Virtual, realMethod.ReturnType, parameters); if (realMethod.GetGenericArguments().Length > 0) { // Generics all get changed to objects realMethod = realMethod.MakeGenericMethod(realMethod.GetGenericArguments().Select(a => typeof(Object)).ToArray()); } EmitMethodWithParameterCombo(thissIdx, realMethod, parameters, methodBuilder, realParams); } }
private string GetProxMethodName(MethodToProxify methodToProxify, MethodInfo realMethod) { string name = methodToProxify.OverrideMethodName ?? realMethod.Name; return(IsValidDelegateMethod(methodToProxify) ? (name + "_internal") : name); }
private void CreateProxyMethod(TypeBuilder wrapperBuilder, int thissIdx, MethodToProxify methodToProxify) { Trace.Assert(wrapperBuilder != null); Trace.Assert(thissIdx >= 0); Trace.Assert(methodToProxify != null); MethodInfo realMethod = methodToProxify.RealMethod; ParameterInfo[] realParams = realMethod.GetParameters(); IList<Type[]> parameterCombinations = GetAllParameterCombinations(realMethod); foreach (Type[] parameters in parameterCombinations) { var methodBuilder = wrapperBuilder.DefineMethod(GetProxMethodName(methodToProxify, realMethod), MethodAttributes.Public | MethodAttributes.Virtual, realMethod.ReturnType, parameters); if (realMethod.GetGenericArguments().Length > 0) { // Generics all get changed to objects realMethod = realMethod.MakeGenericMethod(realMethod.GetGenericArguments().Select(a => typeof (Object)).ToArray()); } EmitMethodWithParameterCombo(thissIdx, realMethod, parameters, methodBuilder, realParams); } }
private bool IsValidDelegateMethod(MethodToProxify mp) { ParameterInfo[] parameters = mp.RealMethod.GetParameters(); ParameterInfo[] delegateParams = parameters.Where(IsParamDelegate).ToArray(); if (delegateParams.Length == 0) return false; if (delegateParams.Length > 1) throw new NotSupportedException("Only single delegate callback methods supported. I.e. Cannot have a callback and an errback."); return true; }
private string GetProxMethodName(MethodToProxify methodToProxify, MethodInfo realMethod) { string name = methodToProxify.OverrideMethodName ?? realMethod.Name; return IsValidDelegateMethod(methodToProxify) ? (name + "_internal") : name; }