public ActorProxyGeneratorBuildResult Build(
            Type proxyInterfaceType,
            IEnumerable <InterfaceDescription> interfaceDescriptions)
        {
            // create the context to build the proxy
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetProxyAssemblyName(proxyInterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetProxyAssemblyNamespace(proxyInterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(proxyInterfaceType));
            var result = new ActorProxyGeneratorBuildResult(context);

            // ensure that method data types are built for each of the remote interfaces
            var methodBodyTypesResultsMap = interfaceDescriptions.ToDictionary(
                d => d,
                d => this.CodeBuilder.GetOrBuildMethodBodyTypes(d.InterfaceType));

            // build the proxy class that implements all of the interfaces explicitly
            result.ProxyType = this.BuildProxyType(context, proxyInterfaceType, methodBodyTypesResultsMap);

            // build the activator type to create instances of the proxy
            result.ProxyActivatorType = this.BuildProxyActivatorType(context, proxyInterfaceType, result.ProxyType);

            // build the proxy generator
            result.ProxyGenerator = this.CreateProxyGenerator(
                proxyInterfaceType,
                result.ProxyActivatorType);

            context.Complete();
            return(result);
        }
        private Type BuildProxyActivatorType(
            CodeBuilderContext context,
            Type proxyInterfaceType,
            Type proxyType)
        {
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetProxyActivatorClassName(proxyInterfaceType),
                interfaces: new[] { typeof(IProxyActivator) });

            AddCreateInstanceMethod(classBuilder, proxyType);
            return(classBuilder.CreateTypeInfo().AsType());
        }
        private Type BuildProxyType(
            CodeBuilderContext context,
            Type proxyInterfaceType,
            IDictionary <InterfaceDescription, MethodBodyTypesBuildResult> methodBodyTypesResultsMap)
        {
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetProxyClassName(proxyInterfaceType),
                baseType: this.proxyBaseType,
                interfaces: methodBodyTypesResultsMap.Select(item => item.Key.InterfaceType).ToArray());

            this.AddGetReturnValueMethod(classBuilder, methodBodyTypesResultsMap);
            this.AddInterfaceImplementations(classBuilder, methodBodyTypesResultsMap);

            return(classBuilder.CreateTypeInfo().AsType());
        }
        private static Type BuildResponseBodyType(
            ICodeBuilderNames codeBuilderNames,
            CodeBuilderContext context,
            MethodDescription methodDescription)
        {
            var responseBodyTypeBuilder = CodeBuilderUtils.CreateDataContractTypeBuilder(
                moduleBuilder: context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                typeName: codeBuilderNames.GetResponseBodyTypeName(methodDescription.Name),
                dcNamespace: codeBuilderNames.GetDataContractNamespace());

            var returnDataType = methodDescription.ReturnType.GetGenericArguments()[0];

            CodeBuilderUtils.AddDataMemberField(
                dcTypeBuilder: responseBodyTypeBuilder,
                fieldType: returnDataType,
                fieldName: codeBuilderNames.RetVal);

            return(responseBodyTypeBuilder.CreateTypeInfo().AsType());
        }
        private static Type BuildRequestBodyType(
            ICodeBuilderNames codeBuilderNames,
            CodeBuilderContext context,
            MethodDescription methodDescription)
        {
            var requestBodyTypeBuilder = CodeBuilderUtils.CreateDataContractTypeBuilder(
                moduleBuilder: context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                typeName: codeBuilderNames.GetRequestBodyTypeName(methodDescription.Name),
                dcNamespace: codeBuilderNames.GetDataContractNamespace());

            foreach (var argument in methodDescription.Arguments)
            {
                CodeBuilderUtils.AddDataMemberField(
                    dcTypeBuilder: requestBodyTypeBuilder,
                    fieldType: argument.ArgumentType,
                    fieldName: argument.Name);
            }

            return(requestBodyTypeBuilder.CreateTypeInfo().AsType());
        }
        public MethodBodyTypesBuildResult Build(InterfaceDescription interfaceDescription)
        {
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetMethodBodyTypesAssemblyName(interfaceDescription.InterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetMethodBodyTypesAssemblyNamespace(interfaceDescription.InterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(interfaceDescription.InterfaceType));

            var result = new MethodBodyTypesBuildResult(context)
            {
                MethodBodyTypesMap = new Dictionary <string, MethodBodyTypes>(),
            };

            foreach (var method in interfaceDescription.Methods)
            {
                result.MethodBodyTypesMap.Add(
                    method.Name,
                    Build(this.CodeBuilder.Names, context, method));
            }

            context.Complete();
            return(result);
        }
        public MethodDispatcherBuildResult Build(
            InterfaceDescription interfaceDescription)
        {
            var context = new CodeBuilderContext(
                assemblyName: this.CodeBuilder.Names.GetMethodDispatcherAssemblyName(interfaceDescription.InterfaceType),
                assemblyNamespace: this.CodeBuilder.Names.GetMethodDispatcherAssemblyNamespace(interfaceDescription
                                                                                               .InterfaceType),
                enableDebugging: CodeBuilderAttribute.IsDebuggingEnabled(interfaceDescription.InterfaceType));

            var result = new MethodDispatcherBuildResult(context);

            // ensure that the method body types are built
            var methodBodyTypesBuildResult =
                this.CodeBuilder.GetOrBuildMethodBodyTypes(interfaceDescription.InterfaceType);

            // build dispatcher class
            var classBuilder = CodeBuilderUtils.CreateClassBuilder(
                context.ModuleBuilder,
                ns: context.AssemblyNamespace,
                className: this.CodeBuilder.Names.GetMethodDispatcherClassName(interfaceDescription.InterfaceType),
                baseType: this.methodDispatcherBaseType);

            this.AddCreateResponseBodyMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult);
            this.AddOnDispatchAsyncMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult);
            this.AddOnDispatchMethod(classBuilder, interfaceDescription, methodBodyTypesBuildResult);

            var methodNameMap = GetMethodNameMap(interfaceDescription);

            // create the dispatcher type, instantiate and initialize it
            result.MethodDispatcherType = classBuilder.CreateTypeInfo().AsType();
            result.MethodDispatcher     = (TMethodDispatcher)Activator.CreateInstance(result.MethodDispatcherType);
            var v2MethodDispatcherBase = (ActorMethodDispatcherBase)result.MethodDispatcher;

            v2MethodDispatcherBase.Initialize(interfaceDescription, methodNameMap);

            context.Complete();
            return(result);
        }
        private static MethodBodyTypes Build(
            ICodeBuilderNames codeBuilderNames,
            CodeBuilderContext context,
            MethodDescription methodDescription)
        {
            var methodDataTypes = new MethodBodyTypes()
            {
                RequestBodyType              = null,
                ResponseBodyType             = null,
                HasCancellationTokenArgument = methodDescription.HasCancellationToken,
            };

            if ((methodDescription.Arguments != null) && (methodDescription.Arguments.Length != 0))
            {
                methodDataTypes.RequestBodyType = BuildRequestBodyType(codeBuilderNames, context, methodDescription);
            }

            if (TypeUtility.IsTaskType(methodDescription.ReturnType) && methodDescription.ReturnType.GetTypeInfo().IsGenericType)
            {
                methodDataTypes.ResponseBodyType = BuildResponseBodyType(codeBuilderNames, context, methodDescription);
            }

            return(methodDataTypes);
        }
 public ActorProxyGeneratorBuildResult(CodeBuilderContext buildContext)
     : base(buildContext)
 {
 }
 public MethodDispatcherBuildResult(CodeBuilderContext buildContext)
     : base(buildContext)
 {
 }
 public MethodBodyTypesBuildResult(CodeBuilderContext buildContext)
     : base(buildContext)
 {
 }