Exemplo n.º 1
0
        private object ImplementDelegate(Type delegateType, IRpcChannel channel, int remoteInstanceId, int localInstanceId)
        {
            RpcTypeDefinition type;

            lock (_proxyImplementations)
            {
                var hash = CreateTypesHash(delegateType);
                if (!_proxyImplementations.TryGetValue(hash, out type))
                {
                    var tb           = _moduleBuilder.DefineType($"{delegateType.Name}Shadow{Guid.NewGuid():n}");
                    var invokerField = CreateConstructor(tb);
                    var(localField, remoteField) = ImplementIRpcObjectProxy(tb);

                    CreateDestructor(tb, invokerField, localField, remoteField);

                    ImplementMethod(tb, delegateType.GetMethod("Invoke"), invokerField, remoteField, false);

                    type = new RpcTypeDefinition
                    {
                        Type = tb.CreateTypeInfo().AsType()
                    };
                    type.LocalIdField  = type.Type.GetField(localField.Name, BindingFlags.NonPublic | BindingFlags.Instance);
                    type.RemoteIdField = type.Type.GetField(remoteField.Name, BindingFlags.NonPublic | BindingFlags.Instance);

                    _proxyImplementations.Add(hash, type);
                }
            }



            var delObj = Activator.CreateInstance(type.Type, channel);

            Debug.Assert(type.LocalIdField != null, "type.LocalIdField != null");
            Debug.Assert(type.RemoteIdField != null, "type.RemoteIdField != null");
            type.LocalIdField.SetValue(delObj, localInstanceId);
            type.RemoteIdField.SetValue(delObj, remoteInstanceId);

            return(Delegate.CreateDelegate(delegateType, delObj, "Invoke"));
        }
Exemplo n.º 2
0
        private object ImplementInterfaces(Type[] interfaceTypes, IRpcChannel channel, int remoteInstanceId, int localInstanceId)
        {
            if (!AllowNonPublicInterfaceAccess)
            {
                if (interfaceTypes.All(interfaceType =>
                                       interfaceType.IsInterface && !interfaceType.IsPublic && !interfaceType.IsNestedPublic))
                {
                    throw new RpcFailedException("Cannot get non public interface.");
                }
            }

            RpcTypeDefinition type;

            lock (_proxyImplementations)
            {
                var hash = CreateTypesHash(interfaceTypes);

                if (!_proxyImplementations.TryGetValue(hash, out type))
                {
                    /*
                     #if !NETSTANDARD && DEBUG
                     * ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("RpcDynamicTypes"),
                     *  AssemblyBuilderAccess.RunAndSave);
                     #endif*/

                    //add a destructor so we can inform other side about us not needing the object anymore


                    var tb = _moduleBuilder.DefineType($"I{Guid.NewGuid():N}Shadow");

                    var invokerField = CreateConstructor(tb);

                    var(localField, remoteField) = ImplementIRpcObjectProxy(tb);

                    CreateDestructor(tb, invokerField, localField, remoteField);

                    var allInterfaceTypes = AllowNonPublicInterfaceAccess
                       ? interfaceTypes
                       : interfaceTypes.Where(i => i.IsPublic || i.IsNestedPublic);

                    foreach (var intf in allInterfaceTypes)
                    {
                        tb.AddInterfaceImplementation(intf);
                        foreach (var method in intf.GetMethods().Where(m => !m.IsSpecialName))
                        {
                            ImplementMethod(tb, method, invokerField, remoteField, true);
                        }

                        foreach (var property in intf.GetProperties())
                        {
                            var prop = tb.DefineProperty(property.Name, property.Attributes, property.PropertyType,
                                                         null);
                            if (property.GetMethod != null)
                            {
                                prop.SetGetMethod(ImplementMethod(tb, property.GetMethod, invokerField,
                                                                  remoteField,
                                                                  true));
                            }

                            if (property.SetMethod != null)
                            {
                                prop.SetSetMethod(ImplementMethod(tb, property.SetMethod, invokerField,
                                                                  remoteField,
                                                                  true));
                            }
                        }

                        foreach (var evnt in intf.GetEvents())
                        {
                            if (evnt.AddMethod != null)
                            {
                                ImplementMethod(tb, evnt.AddMethod, invokerField, remoteField, true);
                            }

                            if (evnt.RemoveMethod != null)
                            {
                                ImplementMethod(tb, evnt.RemoveMethod, invokerField, remoteField, true, true);
                            }
                        }
                    }


                    type = new RpcTypeDefinition
                    {
                        Type = tb.CreateTypeInfo().AsType()
                    };
                    type.LocalIdField  = type.Type.GetField(localField.Name, BindingFlags.NonPublic | BindingFlags.Instance);
                    type.RemoteIdField = type.Type.GetField(remoteField.Name, BindingFlags.NonPublic | BindingFlags.Instance);

                    _proxyImplementations.Add(hash, type);
                }
            }

            /*
             #if !NETSTANDARD && DEBUG
             * ab.Save(@"RpcDynamicTypes.dll");
             #endif*/


            var result = Activator.CreateInstance(type.Type, channel);

            Debug.Assert(type.LocalIdField != null, "type.LocalIdField != null");
            Debug.Assert(type.RemoteIdField != null, "type.RemoteIdField != null");
            type.LocalIdField.SetValue(result, localInstanceId);
            type.RemoteIdField.SetValue(result, remoteInstanceId);

            return(result);
        }