Exemple #1
0
        /// <summary>
        /// Creates a proxy for an actor component object and places it in an existing actor
        /// </summary>
        internal CreatorInterfaceInvocationHandler(ObjectCreator <IActorComponent> creator, IActor rootObject, ProxyFactory proxyFactory)
        {
            // We need to lock on the root when using an existing actor
            ThreadPool.QueueUserWorkItem(
                delegate
            {
                Hooking.ActorCallWrapper(() =>
                {
                    IActorComponent newObject            = creator();
                    ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, rootObject, proxyFactory);

                    m_RealInvocationHandler = temp;
                    m_FinishedEvent.Set();
                });
            });
        }
Exemple #2
0
        /// <summary>
        /// Creates an interceptor for an object that doesn't exist yet.
        ///
        /// This will trigger its asynchronous construction.
        /// </summary>
        public CreatorInterfaceInvocationHandler(ObjectCreator <IActor> creator, ProxyFactory proxyFactory)
        {
            ThreadPool.QueueUserWorkItem(
                delegate
            {
                Hooking.ActorCallWrapper(
                    () =>
                {
                    IActor newObject = creator();
                    ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, newObject, proxyFactory);

                    m_RealInvocationHandler = temp;
                    m_FinishedEvent.Set();
                });
            });
        }
        /// <summary>
        /// Creates a proxy for an actor component object and places it in an existing actor
        /// </summary>
        internal CreatorInterfaceInvocationHandler(ObjectCreator<IActorComponent> creator, IActor rootObject, ProxyFactory proxyFactory)
        {
            // We need to lock on the root when using an existing actor
            ThreadPool.QueueUserWorkItem(
                delegate
                {
                    Hooking.ActorCallWrapper(() =>
                    {
                        IActorComponent newObject = creator();
                        ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, rootObject, proxyFactory);

                        m_RealInvocationHandler = temp;
                        m_FinishedEvent.Set();
                    });
                });
        }
        /// <summary>
        /// Creates an interceptor for an object that doesn't exist yet.
        /// 
        /// This will trigger its asynchronous construction.
        /// </summary>
        public CreatorInterfaceInvocationHandler(ObjectCreator<IActor> creator, ProxyFactory proxyFactory)
        {
            ThreadPool.QueueUserWorkItem(
                delegate
                {
                    Hooking.ActorCallWrapper(
                        () =>
                        {
                            IActor newObject = creator();
                            ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, newObject, proxyFactory);

                            m_RealInvocationHandler = temp;
                            m_FinishedEvent.Set();
                        });
                });
        }
Exemple #5
0
        /// <summary>
        /// Creates something that implements the given interface, and forwards all calls to the invocationHandler
        /// </summary>
        public object CreateInterfaceProxy(IInterfaceInvocationHandler invocationHandler, Type interfaceType, bool throwOnNonActorMethod)
        {
            if (!interfaceType.IsInterface)
            {
                // Only allowing interfaces for the moment, fail fast
                throw new InvalidOperationException("The type " + interfaceType +
                                                    " is not an interface, so an NAct proxy cannot be created for it.");
            }

            if (interfaceType.IsNotPublic)
            {
                throw new InvalidOperationException("The interface " + interfaceType +
                                                    " is not public, so an NAct proxy cannot be created for it.");
            }

            Type proxyType;

            lock (m_Sync)
            {
                m_InterfaceProxyCache.TryGetValue(interfaceType, out proxyType);
            }

            if (proxyType == null)
            {
                TypeBuilder typeBuilder = GetFreshType();

                ForEveryMethodIncludingSuperInterfaces(
                    interfaceType,
                    delegate(MethodInfo eachMethod)
                {
                    if (throwOnNonActorMethod && eachMethod.ReturnType != typeof(void) &&
                        !typeof(IActorComponent).IsAssignableFrom(eachMethod.ReturnType))
                    {
                        // The method has a return type, fail fast
                        throw new InvalidOperationException("The interface " + interfaceType +
                                                            " contains the method " +
                                                            eachMethod +
                                                            " which has a non-void return type. Actors may only have methods with void return types.");
                    }

                    Type[] parameterTypes       = GetParameterTypes(eachMethod);
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(eachMethod.Name,
                                                                           eachMethod.Attributes &
                                                                           ~MethodAttributes.Abstract,
                                                                           eachMethod.ReturnType, parameterTypes);

                    if (eachMethod.ReturnType == typeof(void))
                    {
                        // This is an asynchronous call, use the appropriate IMethodInvocationHandler to move it to the right thread
                        // Create a field in which to put the IMethodInvocationHandler
                        FieldBuilder invocationHandlerField =
                            typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                    typeof(IMethodInvocationHandler),
                                                    FieldAttributes.Private);
                        BuildForwarderMethod(methodBuilder, parameterTypes, m_InvokeHappenedMethod,
                                             invocationHandlerField);
                    }
                    else
                    {
                        // This is a request for a subinterface - create a method that will return a proxied version of it
                        FieldBuilder invocationHandlerField =
                            typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                    typeof(IMethodInvocationHandler),
                                                    FieldAttributes.Private);
                        BuildForwarderMethod(methodBuilder, parameterTypes, m_ReturningInvokeHappenedMethod,
                                             invocationHandlerField);
                    }
                });

                typeBuilder.AddInterfaceImplementation(interfaceType);

                // Finalise the type
                proxyType = typeBuilder.CreateType();

                // Save it in the cache (this may have raced with another thread, worst that can happen is an unused extra type is created)
                lock (m_Sync)
                {
                    m_InterfaceProxyCache[interfaceType] = proxyType;
                }
            }

            object proxyInstance = Activator.CreateInstance(proxyType);

            // Now we can write all the invocation handlers
            ForEveryMethodIncludingSuperInterfaces(
                interfaceType,
                delegate(MethodInfo eachMethod)
            {
                FieldInfo writeableInvocationHandlerField =
                    proxyType.GetField(InvocationHandlerNameForMethod(eachMethod), BindingFlags.NonPublic | BindingFlags.Instance);

                MethodCaller methodCaller = CreateMethodCaller(eachMethod);

                writeableInvocationHandlerField.SetValue(proxyInstance,
                                                         invocationHandler.GetInvocationHandlerFor(
                                                             methodCaller, eachMethod.ReturnType, eachMethod));
            });

            return(proxyInstance);
        }
Exemple #6
0
        /// <summary>
        /// Creates something that implements the given interface, and forwards all calls to the invocationHandler
        /// </summary>
        public object CreateInterfaceProxy(IInterfaceInvocationHandler invocationHandler, Type interfaceType, bool throwOnNonActorMethod)
        {
            if (!interfaceType.IsInterface)
            {
                // Only allowing interfaces for the moment, fail fast
                throw new InvalidOperationException("The type " + interfaceType +
                                                    " is not an interface, so an NAct proxy cannot be created for it.");
            }

            if (interfaceType.IsNotPublic)
            {
                throw new InvalidOperationException("The interface " + interfaceType +
                                                    " is not public, so an NAct proxy cannot be created for it.");
            }

            Type proxyType;
            lock (m_Sync)
            {
                m_InterfaceProxyCache.TryGetValue(interfaceType, out proxyType);
            }

            if (proxyType == null)
            {
                TypeBuilder typeBuilder = GetFreshType();

                ForEveryMethodIncludingSuperInterfaces(
                    interfaceType,
                    delegate(MethodInfo eachMethod)
                        {
                            if (throwOnNonActorMethod && eachMethod.ReturnType != typeof (void) &&
                                !typeof (IActorComponent).IsAssignableFrom(eachMethod.ReturnType))
                            {
                                // The method has a return type, fail fast
                                throw new InvalidOperationException("The interface " + interfaceType +
                                                                    " contains the method " +
                                                                    eachMethod +
                                                                    " which has a non-void return type. Actors may only have methods with void return types.");
                            }

                            Type[] parameterTypes = GetParameterTypes(eachMethod);
                            MethodBuilder methodBuilder = typeBuilder.DefineMethod(eachMethod.Name,
                                                                                   eachMethod.Attributes &
                                                                                   ~MethodAttributes.Abstract,
                                                                                   eachMethod.ReturnType, parameterTypes);

                            if (eachMethod.ReturnType == typeof (void))
                            {
                                // This is an asynchronous call, use the appropriate IMethodInvocationHandler to move it to the right thread
                                // Create a field in which to put the IMethodInvocationHandler
                                FieldBuilder invocationHandlerField =
                                    typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                            typeof (IMethodInvocationHandler),
                                                            FieldAttributes.Private);
                                BuildForwarderMethod(methodBuilder, parameterTypes, m_InvokeHappenedMethod,
                                                     invocationHandlerField);
                            }
                            else
                            {
                                // This is a request for a subinterface - create a method that will return a proxied version of it
                                FieldBuilder invocationHandlerField =
                                    typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                            typeof (IMethodInvocationHandler),
                                                            FieldAttributes.Private);
                                BuildForwarderMethod(methodBuilder, parameterTypes, m_ReturningInvokeHappenedMethod,
                                                     invocationHandlerField);
                            }
                        });

                typeBuilder.AddInterfaceImplementation(interfaceType);

                // Finalise the type
                proxyType = typeBuilder.CreateType();

                // Save it in the cache (this may have raced with another thread, worst that can happen is an unused extra type is created)
                lock (m_Sync)
                {
                    m_InterfaceProxyCache[interfaceType] = proxyType;
                }
            }

            object proxyInstance = Activator.CreateInstance(proxyType);

            // Now we can write all the invocation handlers
            ForEveryMethodIncludingSuperInterfaces(
                interfaceType,
                delegate(MethodInfo eachMethod)
                    {
                        FieldInfo writeableInvocationHandlerField =
                            proxyType.GetField(InvocationHandlerNameForMethod(eachMethod), BindingFlags.NonPublic | BindingFlags.Instance);

                        MethodCaller methodCaller = CreateMethodCaller(eachMethod);

                        writeableInvocationHandlerField.SetValue(proxyInstance,
                                                                    invocationHandler.GetInvocationHandlerFor(
                                                                        methodCaller, eachMethod.ReturnType, eachMethod));
                    });

            return proxyInstance;
        }