Пример #1
0
        private Type CreateProxyClass(Type rootInterfaceType, Type interfaceType, string path)
        {
            var serviceDescription = serviceDescriptionBuilder.Build(interfaceType);

            path = path ?? serviceDescription.Name;

            var typeBuilder  = DeclareType(interfaceType);
            var fieldCache   = new ProxyClassFieldCache(typeBuilder);
            var classContext = new ProxyClassBuildingContext(rootInterfaceType, path, typeBuilder, fieldCache);

            foreach (var methodDesc in serviceDescription.Methods)
            {
                CreateMethod(classContext, path, methodDesc);
            }
            CreateConstructor(classContext, path, serviceDescription);
            return(typeBuilder.CreateType());
        }
Пример #2
0
        private KeyValuePair <string, ImplementationCreationInfo> ConvertPair(InterfaceImplementationTypePair pair)
        {
            var serviceName = pair.Interface.GetServiceName();

            if (!pair.Interface.IsAssignableFrom(pair.ImplementationType))
            {
                throw new ArgumentException(string.Format("Given implementation for a '{0}' service ({1}) does not implement its interface", serviceName, pair.ImplementationType.FullName));
            }
            var constructor = FindLargestAppropriateConstructor(pair.ImplementationType);

            if (constructor == null)
            {
                throw new ArgumentException(string.Format("No appropriate constructor found for {0}", pair.ImplementationType.FullName));
            }
            var creationInfo = new ImplementationCreationInfo
            {
                Constructor = constructor,
                Description = serviceDescriptionBuilder.Build(pair.Interface)
            };

            return(new KeyValuePair <string, ImplementationCreationInfo>(pair.Interface.GetServiceName(), creationInfo));
        }
 public void Setup()
 {
     serviceDescription = new ServiceDescription(typeof(IMyService), "MyService", new SubserviceDescription[0],
         new[] {new MethodDescription(typeof(void), "DoSomething", new MethodParameterDescription[0])});
     serviceDescriptionBuilder = Substitute.For<IServiceDescriptionBuilder>();
     serviceDescriptionBuilder.Build(typeof(IMyService)).Returns(serviceDescription);
     container = new ServiceImplementationContainer(serviceDescriptionBuilder);
 }
Пример #4
0
        private Type CreateProxyClass(Type rootType, Type type, string path)
        {
            var serviceDescription = serviceDescriptionBuilder.Build(type);

            path = path ?? serviceDescription.Name;

            var typeBuilder = moduleBuilder.DefineType("__rpc_proxy_" + type.FullName + "_" + classNameDisambiguator++,
                                                       TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class,
                                                       typeof(object), new[] { type });

            #region Emit Fields
            var processorField = typeBuilder.DefineField("methodCallProcessor", typeof(IOutgoingMethodCallProcessor),
                                                         FieldAttributes.Private | FieldAttributes.InitOnly);
            var scopeField = typeBuilder.DefineField("scope", typeof(string),
                                                     FieldAttributes.Private | FieldAttributes.InitOnly);
            var timeoutSettingsField = typeBuilder.DefineField("timeoutSettings", typeof(TimeoutSettings),
                                                               FieldAttributes.Private | FieldAttributes.InitOnly);
            #endregion

            #region Begin Emit Constructor
            var constructorBuilder = typeBuilder.DefineConstructor(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                CallingConventions.Standard, ConstructorParameterTypes);
            var baseConstructor = typeof(object).GetConstructor(Type.EmptyTypes);
            var cil             = constructorBuilder.GetILGenerator();
            cil.Emit(OpCodes.Ldarg_0);
            cil.Emit(OpCodes.Call, baseConstructor);
            cil.Emit(OpCodes.Ldarg_0);
            cil.Emit(OpCodes.Ldarg_1);
            cil.Emit(OpCodes.Stfld, processorField);
            cil.Emit(OpCodes.Ldarg_0);
            cil.Emit(OpCodes.Ldarg_2);
            cil.Emit(OpCodes.Stfld, scopeField);
            cil.Emit(OpCodes.Ldarg_0);
            cil.Emit(OpCodes.Ldarg_3);
            cil.Emit(OpCodes.Stfld, timeoutSettingsField);
            #endregion

            foreach (var subserviceDesc in serviceDescription.Subservices)
            {
                #region Emit Subservice Property
                var proxyClass = CreateProxyClass(rootType, subserviceDesc.Service.Type, path + "/" + subserviceDesc.Name);

                var fieldBuilder = typeBuilder.DefineField("_" + subserviceDesc.Name, proxyClass,
                                                           FieldAttributes.Private | FieldAttributes.InitOnly);

                cil.Emit(OpCodes.Ldarg_0);
                cil.Emit(OpCodes.Ldarg_1);
                cil.Emit(OpCodes.Ldarg_2);
                cil.Emit(OpCodes.Ldarg_3);
                cil.Emit(OpCodes.Newobj, proxyClass.GetConstructor(ConstructorParameterTypes));
                cil.Emit(OpCodes.Stfld, fieldBuilder);

                var methodBuilder = typeBuilder.DefineMethod("get_" + subserviceDesc.Name,
                                                             MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig |
                                                             MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual,
                                                             subserviceDesc.Service.Type, Type.EmptyTypes);
                methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed);
                var il = methodBuilder.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, fieldBuilder);
                il.Emit(OpCodes.Ret);

                var propertyBuilder = typeBuilder.DefineProperty(subserviceDesc.Name,
                                                                 PropertyAttributes.None, subserviceDesc.Service.Type, Type.EmptyTypes);
                propertyBuilder.SetGetMethod(methodBuilder);
                #endregion
            }

            #region End Emit Constructor
            cil.Emit(OpCodes.Ret);
            #endregion

            foreach (var methodDesc in serviceDescription.Methods)
            {
                #region Emit Method
                var parameterTypes = methodDesc.Parameters.Select(x => x.Way == MethodParameterWay.Val ? x.Type : x.Type.MakeByRefType()).ToArray();
                var dynamicMethod  = EmitDynamicMethod(rootType, path, methodDesc, parameterTypes, codecContainer);
                dynamicMethods.Add(dynamicMethod);
                var dynamicMethodPointer = MethodHelpers.ExtractDynamicMethodPointer(dynamicMethod);

                var methodBuilder = typeBuilder.DefineMethod(methodDesc.Name,
                                                             MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig |
                                                             MethodAttributes.NewSlot | MethodAttributes.Virtual,
                                                             dynamicMethod.ReturnType, parameterTypes);
                methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed);

                var il = methodBuilder.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, processorField);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, scopeField);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, timeoutSettingsField);
                for (int i = 0; i < methodDesc.Parameters.Count; i++)
                {
                    il.Emit(OpCodes.Ldarg, i + 1);
                }
                il.Emit_Ldc_IntPtr(dynamicMethodPointer);
                il.EmitCalli(OpCodes.Calli, CallingConventions.Standard,
                             dynamicMethod.ReturnType,
                             dynamicMethod.GetParameters().Select(x => x.ParameterType).ToArray(),
                             null);
                il.Emit(OpCodes.Ret);
                #endregion
            }

            return(typeBuilder.CreateType());
        }