private IMethodInvocationHandler WaitForRealMethodInvocationHandler() { // Wait for the real invocation handler to finish being contructed m_CreatorInterfaceInvocationHandler.m_FinishedEvent.WaitOne(); IMethodInvocationHandler realMethodInvocationHandler = m_CreatorInterfaceInvocationHandler.m_RealInvocationHandler.GetInvocationHandlerFor(m_MethodCaller, m_ReturnType, m_TargetMethod); return(realMethodInvocationHandler); }
/// <summary> /// Creates a new method that has the same signature as an existing one, but just calls a methodInvocationHandler when it's called. /// </summary> /// <param name="methodInvocationHandler">The thing that handles the call</param> /// <param name="signature">A method whose signature we want to duplicate</param> /// <param name="delegateType">The specific type of the delegate you'd like to create (it's safe to cast the return value to this type)</param> public Delegate CreateDelegateProxy(IMethodInvocationHandler methodInvocationHandler, MethodInfo signature, Type delegateType) { Type proxyType; lock (m_Sync) { m_DelegateProxyCache.TryGetValue(delegateType, out proxyType); } if (proxyType == null) { TypeBuilder typeBuilder = GetFreshType(); // Create a field in which to put the IMethodInvocationHandler FieldBuilder invocationHandlerField = typeBuilder.DefineField(c_FieldNameForInvocationHandler, typeof(IMethodInvocationHandler), FieldAttributes.Private); Type[] parameterTypes = GetParameterTypes(signature); MethodBuilder methodBuilder = typeBuilder.DefineMethod(c_DelegateMethodName, MethodAttributes.Public, signature.ReturnType, parameterTypes); BuildForwarderMethod(methodBuilder, parameterTypes, m_InvokeHappenedMethod, invocationHandlerField); // Finalise the type proxyType = typeBuilder.CreateType(); // Cache it lock (m_Sync) { m_DelegateProxyCache[delegateType] = proxyType; } } object proxyInstance = Activator.CreateInstance(proxyType); // Put the invocation handler in a field FieldInfo writeableInvocationHandlerField = proxyType.GetField(c_FieldNameForInvocationHandler, BindingFlags.Instance | BindingFlags.NonPublic); writeableInvocationHandlerField.SetValue(proxyInstance, methodInvocationHandler); return(Delegate.CreateDelegate(delegateType, proxyInstance, proxyType.GetMethod(c_DelegateMethodName))); }
/// <summary> /// Creates a new method that has the same signature as an existing one, but just calls a methodInvocationHandler when it's called. /// </summary> /// <param name="methodInvocationHandler">The thing that handles the call</param> /// <param name="signature">A method whose signature we want to duplicate</param> /// <param name="delegateType">The specific type of the delegate you'd like to create (it's safe to cast the return value to this type)</param> public Delegate CreateDelegateProxy(IMethodInvocationHandler methodInvocationHandler, MethodInfo signature, Type delegateType) { Type proxyType; lock (m_Sync) { m_DelegateProxyCache.TryGetValue(delegateType, out proxyType); } if (proxyType == null) { TypeBuilder typeBuilder = GetFreshType(); // Create a field in which to put the IMethodInvocationHandler FieldBuilder invocationHandlerField = typeBuilder.DefineField(c_FieldNameForInvocationHandler, typeof (IMethodInvocationHandler), FieldAttributes.Private); Type[] parameterTypes = GetParameterTypes(signature); MethodBuilder methodBuilder = typeBuilder.DefineMethod(c_DelegateMethodName, MethodAttributes.Public, signature.ReturnType, parameterTypes); BuildForwarderMethod(methodBuilder, parameterTypes, m_InvokeHappenedMethod, invocationHandlerField); // Finalise the type proxyType = typeBuilder.CreateType(); // Cache it lock (m_Sync) { m_DelegateProxyCache[delegateType] = proxyType; } } object proxyInstance = Activator.CreateInstance(proxyType); // Put the invocation handler in a field FieldInfo writeableInvocationHandlerField = proxyType.GetField(c_FieldNameForInvocationHandler, BindingFlags.Instance | BindingFlags.NonPublic); writeableInvocationHandlerField.SetValue(proxyInstance, methodInvocationHandler); return Delegate.CreateDelegate(delegateType, proxyInstance, proxyType.GetMethod(c_DelegateMethodName)); }