예제 #1
0
        public override void GenerateCode(AssemblyBuilder assemblyBuilder)
        {
            string contentType, fileExtension;
            string originalSource, prettyPrintResource, compactedResource;

            ResourceCodeProvider provider = assemblyBuilder.CodeDomProvider as ResourceCodeProvider;

            if (provider != null)
            {
                originalSource = provider.CompileResource(
                    this,
                    base.VirtualPath,
                    out prettyPrintResource,
                    out compactedResource);

                contentType   = provider.ContentType;
                fileExtension = provider.FileExtension;
            }
            else
            {
                // read the resource contents
                using (TextReader reader = this.OpenReader())
                {
                    originalSource = compactedResource = prettyPrintResource = reader.ReadToEnd();
                }

                contentType   = "text/plain";
                fileExtension = "txt";
            }

            IResourceNameGenerator nameGenerator = assemblyBuilder.CodeDomProvider as IResourceNameGenerator;

            if (nameGenerator != null)
            {
                this.ResourceFullName = nameGenerator.GenerateResourceName(base.VirtualPath);
            }
            else
            {
                this.ResourceFullName = ResourceBuildProvider.GenerateTypeNameFromPath(base.VirtualPath);
            }

            byte[] gzippedBytes, deflatedBytes;
            ResourceBuildProvider.Compress(compactedResource, out gzippedBytes, out deflatedBytes);
            string hash = ResourceBuildProvider.ComputeHash(compactedResource);

            // generate a resource container
            CodeCompileUnit generatedUnit = new CodeCompileUnit();

            #region namespace ResourceNamespace

            CodeNamespace ns = new CodeNamespace(this.ResourceNamespace);
            generatedUnit.Namespaces.Add(ns);

            #endregion namespace ResourceNamespace

            #region public sealed class ResourceTypeName

            CodeTypeDeclaration resourceType = new CodeTypeDeclaration();
            resourceType.IsClass    = true;
            resourceType.Name       = this.ResourceTypeName;
            resourceType.Attributes = MemberAttributes.Public | MemberAttributes.Final;

            provider.SetBaseClass(resourceType);

            resourceType.BaseTypes.Add(typeof(IOptimizedResult));
            ns.Types.Add(resourceType);

            #endregion public sealed class ResourceTypeName

            #region [BuildPath(virtualPath)]

            string virtualPath = base.VirtualPath;
            if (HttpRuntime.AppDomainAppVirtualPath.Length > 1)
            {
                virtualPath = virtualPath.Substring(HttpRuntime.AppDomainAppVirtualPath.Length);
            }
            virtualPath = "~" + virtualPath;

            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(BuildPathAttribute)),
                new CodeAttributeArgument(new CodePrimitiveExpression(virtualPath)));
            resourceType.CustomAttributes.Add(attribute);

            #endregion [BuildPath(virtualPath)]

            #region private static readonly byte[] GzippedBytes

            CodeMemberField field = new CodeMemberField();
            field.Name       = "GzippedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            CodeArrayCreateExpression arrayInit = new CodeArrayCreateExpression(field.Type, gzippedBytes.Length);
            foreach (byte b in gzippedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static static readonly byte[] GzippedBytes

            #region private static readonly byte[] DeflatedBytes;

            field            = new CodeMemberField();
            field.Name       = "DeflatedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            arrayInit = new CodeArrayCreateExpression(field.Type, deflatedBytes.Length);
            foreach (byte b in deflatedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static readonly byte[] DeflatedBytes;

            #region string IOptimizedResult.Source { get; }

            // add a readonly property with the original resource source
            CodeMemberProperty property = new CodeMemberProperty();
            property.Name = "Source";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return originalSource; }
            if (originalSource == null || originalSource.Length <= 0x5DC)
            {
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(originalSource)));
            }
            else
            {
                string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(originalSource);
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Source { get; }

            #region string IOptimizedResult.PrettyPrinted { get; }

            // add a readonly property with the resource data
            property      = new CodeMemberProperty();
            property.Name = "PrettyPrinted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;

            if (String.Equals(originalSource, prettyPrintResource))
            {
                // get { return ((IOptimizedResult)this).Source; }
                CodeExpression thisRef = new CodeCastExpression(typeof(IOptimizedResult), new CodeThisReferenceExpression());
                CodePropertyReferenceExpression sourceProperty = new CodePropertyReferenceExpression(thisRef, "Source");
                property.GetStatements.Add(new CodeMethodReturnStatement(sourceProperty));
            }
            else
            {
                // get { return prettyPrintResource; }
                if (prettyPrintResource == null || prettyPrintResource.Length <= 0x5DC)
                {
                    property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(prettyPrintResource)));
                }
                else
                {
                    string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(prettyPrintResource);
                    property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
                }
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.PrettyPrinted { get; }

            #region string IOptimizedResult.Compacted { get; }

            // add a readonly property with the compacted resource data
            property      = new CodeMemberProperty();
            property.Name = "Compacted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return compactedResource; }
            if (compactedResource == null || compactedResource.Length <= 0x5DC)
            {
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(compactedResource)));
            }
            else
            {
                string escaped = ResourceBuildProvider.QuoteSnippetStringCStyle(compactedResource);
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(escaped)));
            }
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Compacted { get; }

            #region byte[] IOptimizedResult.Gzipped { get; }

            // add a readonly property with the gzipped resource data
            property      = new CodeMemberProperty();
            property.Name = "Gzipped";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return GzippedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "GzippedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Gzipped { get; }

            #region byte[] IOptimizedResult.Deflated { get; }

            // add a readonly property with the deflated resource data
            property      = new CodeMemberProperty();
            property.Name = "Deflated";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return DeflatedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "DeflatedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Deflated { get; }

            #region string IBuildResultMeta.ContentType { get; }

            // add a readonly property with the MIME type
            property      = new CodeMemberProperty();
            property.Name = "ContentType";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return contentType; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(contentType)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.ContentType { get; }

            #region string IBuildResultMeta.FileExtension { get; }

            // add a readonly property with the MIME type
            property      = new CodeMemberProperty();
            property.Name = "FileExtension";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return fileExtension; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(fileExtension)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.FileExtension { get; }

            #region string IBuildResultMeta.Hash { get; }

            // add a readonly property with the resource data
            property      = new CodeMemberProperty();
            property.Name = "Hash";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return hash); }

            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(hash)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.Hash { get; }

            if (this.VirtualPathDependencies.Count > 0)
            {
                resourceType.BaseTypes.Add(typeof(IDependentResult));

                #region private static readonly string[] Dependencies

                field            = new CodeMemberField();
                field.Name       = "Dependencies";
                field.Type       = new CodeTypeReference(typeof(string[]));
                field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

                arrayInit = new CodeArrayCreateExpression(field.Type, this.VirtualPathDependencies.Count);
                foreach (string key in this.VirtualPathDependencies)
                {
                    arrayInit.Initializers.Add(new CodePrimitiveExpression(key));
                }
                field.InitExpression = arrayInit;

                resourceType.Members.Add(field);

                #endregion private static readonly string[] Dependencies

                #region IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }

                // add a readonly property returning the static data
                property      = new CodeMemberProperty();
                property.Name = "VirtualPathDependencies";
                property.Type = new CodeTypeReference(typeof(IEnumerable <string>));
                property.PrivateImplementationType = new CodeTypeReference(typeof(IDependentResult));
                property.HasGet = true;
                // get { return Dependencies; }
                property.GetStatements.Add(new CodeMethodReturnStatement(
                                               new CodeFieldReferenceExpression(
                                                   new CodeTypeReferenceExpression(resourceType.Name),
                                                   "Dependencies")));
                resourceType.Members.Add(property);

                #endregion IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }
            }

            // allow the code provider to extend with additional properties
            provider.GenerateCodeExtensions(this, resourceType);

            // Generate _ASP FastObjectFactory
            assemblyBuilder.GenerateTypeFactory(this.ResourceFullName);

            assemblyBuilder.AddCodeCompileUnit(this, generatedUnit);
        }
예제 #2
0
        private void GenerateServiceProxyCode(AssemblyBuilder assemblyBuilder, Type serviceType)
        {
            IResourceNameGenerator nameGenerator = assemblyBuilder.CodeDomProvider as IResourceNameGenerator;

            if (nameGenerator != null)
            {
                this.ResourceFullName = nameGenerator.GenerateResourceName(base.VirtualPath);
            }
            else
            {
                this.ResourceFullName = ResourceBuildProvider.GenerateTypeNameFromPath(base.VirtualPath);
            }

            // TODO: consolidate app relative path conversion
            // calculate the service end-point path
            string proxyPath = ResourceHandler.EnsureAppRelative(base.VirtualPath).TrimStart('~');

            // build proxy from main service type
            JsonServiceDescription    desc  = new JsonServiceDescription(serviceType, proxyPath);
            JsonServiceProxyGenerator proxy = new JsonServiceProxyGenerator(desc);

            string proxyOutput = proxy.OutputProxy(false);

            proxyOutput = ScriptResourceCodeProvider.FirewallScript(proxyPath, proxyOutput, true);

            string debugProxyOutput = proxy.OutputProxy(true);

            debugProxyOutput = ScriptResourceCodeProvider.FirewallScript(proxyPath, debugProxyOutput, false);

            byte[] gzippedBytes, deflatedBytes;
            ResourceBuildProvider.Compress(proxyOutput, out gzippedBytes, out deflatedBytes);
            string hash = ResourceBuildProvider.ComputeHash(proxyOutput);

            // generate a service factory
            CodeCompileUnit generatedUnit = new CodeCompileUnit();

            #region namespace ResourceNamespace

            CodeNamespace ns = new CodeNamespace(this.ResourceNamespace);
            generatedUnit.Namespaces.Add(ns);

            #endregion namespace ResourceNamespace

            #region public sealed class ResourceTypeName : JsonServiceInfo

            CodeTypeDeclaration resourceType = new CodeTypeDeclaration();
            resourceType.IsClass    = true;
            resourceType.Name       = this.ResourceTypeName;
            resourceType.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            resourceType.BaseTypes.Add(typeof(IJsonServiceInfo));
            resourceType.BaseTypes.Add(typeof(IOptimizedResult));
            ns.Types.Add(resourceType);

            #endregion public sealed class ResourceTypeName : CompiledBuildResult

            #region [BuildPath(virtualPath)]

            string virtualPath = base.VirtualPath;
            if (HttpRuntime.AppDomainAppVirtualPath.Length > 1)
            {
                virtualPath = virtualPath.Substring(HttpRuntime.AppDomainAppVirtualPath.Length);
            }
            virtualPath = "~" + virtualPath;

            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(BuildPathAttribute)),
                new CodeAttributeArgument(new CodePrimitiveExpression(virtualPath)));
            resourceType.CustomAttributes.Add(attribute);

            #endregion [BuildPath(virtualPath)]

            #region private static readonly byte[] GzippedBytes

            CodeMemberField field = new CodeMemberField();
            field.Name       = "GzippedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            CodeArrayCreateExpression arrayInit = new CodeArrayCreateExpression(field.Type, gzippedBytes.Length);
            foreach (byte b in gzippedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static static readonly byte[] GzippedBytes

            #region private static readonly byte[] DeflatedBytes

            field            = new CodeMemberField();
            field.Name       = "DeflatedBytes";
            field.Type       = new CodeTypeReference(typeof(byte[]));
            field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

            arrayInit = new CodeArrayCreateExpression(field.Type, deflatedBytes.Length);
            foreach (byte b in deflatedBytes)
            {
                arrayInit.Initializers.Add(new CodePrimitiveExpression(b));
            }
            field.InitExpression = arrayInit;

            resourceType.Members.Add(field);

            #endregion private static readonly byte[] DeflatedBytes

            #region string IOptimizedResult.Source { get; }

            // add a readonly property with the original resource source
            CodeMemberProperty property = new CodeMemberProperty();
            property.Name = "Source";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;

            // get { return debugProxyOutput; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(debugProxyOutput)));
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Source { get; }

            #region string IOptimizedResult.PrettyPrinted { get; }

            // add a readonly property with the debug proxy code string
            property      = new CodeMemberProperty();
            property.Name = "PrettyPrinted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;

            // get { return ((IOptimizedResult)this).Source; }
            CodeExpression thisRef = new CodeCastExpression(typeof(IOptimizedResult), new CodeThisReferenceExpression());
            CodePropertyReferenceExpression sourceProperty = new CodePropertyReferenceExpression(thisRef, "Source");
            property.GetStatements.Add(new CodeMethodReturnStatement(sourceProperty));
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.PrettyPrinted { get; }

            #region string IOptimizedResult.Compacted { get; }

            // add a readonly property with the proxy code string
            property      = new CodeMemberProperty();
            property.Name = "Compacted";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return proxyOutput; }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(proxyOutput)));
            resourceType.Members.Add(property);

            #endregion string IOptimizedResult.Compacted { get; }

            #region byte[] IOptimizedResult.Gzipped { get; }

            // add a readonly property with the gzipped proxy code
            property      = new CodeMemberProperty();
            property.Name = "Gzipped";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return GzippedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "GzippedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Gzipped { get; }

            #region byte[] IOptimizedResult.Deflated { get; }

            // add a readonly property with the deflated proxy code
            property      = new CodeMemberProperty();
            property.Name = "Deflated";
            property.Type = new CodeTypeReference(typeof(byte[]));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IOptimizedResult));
            property.HasGet = true;
            // get { return DeflatedBytes; }
            property.GetStatements.Add(new CodeMethodReturnStatement(
                                           new CodeFieldReferenceExpression(
                                               new CodeTypeReferenceExpression(this.ResourceTypeName),
                                               "DeflatedBytes")));
            resourceType.Members.Add(property);

            #endregion byte[] IOptimizedResult.Deflated { get; }

            #region string IBuildResultMeta.Hash { get; }

            // add a readonly property with the hash of the resource data
            property      = new CodeMemberProperty();
            property.Name = "Hash";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return hash; }

            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(hash)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.Hash { get; }

            #region string IBuildResultMeta.ContentType { get; }

            // add a readonly property with the MIME of the resource data
            property      = new CodeMemberProperty();
            property.Name = "ContentType";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return ScriptResourceCodeProvider.MimeType; }

            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(ScriptResourceCodeProvider.MimeType)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.ContentType { get; }

            #region string IBuildResultMeta.FileExtension { get; }

            // add a readonly property with the extension of the resource data
            property      = new CodeMemberProperty();
            property.Name = "FileExtension";
            property.Type = new CodeTypeReference(typeof(String));
            property.PrivateImplementationType = new CodeTypeReference(typeof(IBuildResult));
            property.HasGet = true;
            // get { return ScriptResourceCodeProvider.FileExt; }

            property.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(ScriptResourceCodeProvider.FileExt)));
            resourceType.Members.Add(property);

            #endregion string IBuildResultMeta.FileExtension { get; }

            #region public Type IJrpcServiceInfo.ServiceType { get; }

            // add a static field with the service type
            property            = new CodeMemberProperty();
            property.Name       = "ServiceType";
            property.Type       = new CodeTypeReference(typeof(Type));
            property.Attributes = MemberAttributes.Public;
            property.ImplementationTypes.Add(new CodeTypeReference(typeof(IJsonServiceInfo)));
            property.HasGet = true;
            // get { return typeof(serviceType); }
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodeTypeOfExpression(serviceType.FullName)));
            resourceType.Members.Add(property);

            #endregion public Type IJrpcServiceInfo.ServiceType { get; }

            #region object IJrpcServiceInfo.CreateService();

            CodeMemberMethod codeMethod = new CodeMemberMethod();
            codeMethod.Name = "CreateService";
            codeMethod.PrivateImplementationType = new CodeTypeReference(typeof(IJsonServiceInfo));
            codeMethod.ReturnType = new CodeTypeReference(typeof(Object));
            // return new serviceType();
            codeMethod.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(serviceType)));
            resourceType.Members.Add(codeMethod);

            #endregion object IJrpcServiceInfo.CreateService();

            #region MethodInfo IJrpcServiceInfo.ResolveMethodName(string name);

            codeMethod      = new CodeMemberMethod();
            codeMethod.Name = "ResolveMethodName";
            codeMethod.PrivateImplementationType = new CodeTypeReference(typeof(IJsonServiceInfo));
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(String), "name"));
            codeMethod.ReturnType = new CodeTypeReference(typeof(MethodInfo));
            CodeVariableReferenceExpression nameParam = new CodeVariableReferenceExpression("name");

            // if (String.IsNullOrEmpty(name)) { return null; }
            CodeConditionStatement nullCheck = new CodeConditionStatement();
            nullCheck.Condition = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(String)), "IsNullOrEmpty", nameParam);
            nullCheck.TrueStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
            codeMethod.Statements.Add(nullCheck);

            Dictionary <string, MethodInfo> methodMap = JsonServiceBuildProvider.CreateMethodMap(serviceType);
            foreach (string name in methodMap.Keys)
            {
                CodeConditionStatement nameTest = new CodeConditionStatement();
                // if (String.Equals(name, methodName)) { ... }
                nameTest.Condition = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(String)), "Equals", nameParam, new CodePrimitiveExpression(name));

                // this.ServiceType
                CodePropertyReferenceExpression serviceTypeRef = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ServiceType");

                // method name
                CodePrimitiveExpression methodNameRef = new CodePrimitiveExpression(methodMap[name].Name);

                // this.ServiceType.GetMethod(methodNameRef)
                CodeMethodInvokeExpression methodInfoRef = new CodeMethodInvokeExpression(serviceTypeRef, "GetMethod", methodNameRef);

                // return MethodInfo;
                nameTest.TrueStatements.Add(new CodeMethodReturnStatement(methodInfoRef));
                codeMethod.Statements.Add(nameTest);
            }

            codeMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
            resourceType.Members.Add(codeMethod);

            #endregion MethodInfo IJrpcServiceInfo.ResolveMethodName(string name);

            #region string[] IJrpcServiceInfo.GetMethodParams(string name);

            codeMethod      = new CodeMemberMethod();
            codeMethod.Name = "GetMethodParams";
            codeMethod.PrivateImplementationType = new CodeTypeReference(typeof(IJsonServiceInfo));
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(String), "name"));
            codeMethod.ReturnType = new CodeTypeReference(typeof(String[]));
            CodeVariableReferenceExpression nameParam2 = new CodeVariableReferenceExpression("name");

            // if (String.IsNullOrEmpty(name)) { return new string[0]; }
            CodeConditionStatement nullCheck2 = new CodeConditionStatement();
            nullCheck2.Condition = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(String)), "IsNullOrEmpty", nameParam);
            nullCheck2.TrueStatements.Add(new CodeMethodReturnStatement(new CodeArrayCreateExpression(typeof(String[]), 0)));
            codeMethod.Statements.Add(nullCheck2);

            foreach (MethodInfo method in methodMap.Values)
            {
                string[] paramMap = JsonServiceBuildProvider.CreateParamMap(method);

                if (paramMap.Length < 1)
                {
                    continue;
                }

                CodeConditionStatement nameTest = new CodeConditionStatement();
                // if (String.Equals(name, method.Name)) { ... }
                nameTest.Condition = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(String)), "Equals", nameParam2, new CodePrimitiveExpression(method.Name));

                // = {...}
                CodePrimitiveExpression[] paramList = new CodePrimitiveExpression[paramMap.Length];
                for (int i = 0; i < paramMap.Length; i++)
                {
                    paramList[i] = new CodePrimitiveExpression(paramMap[i]);
                }

                // new string[] = {...}
                CodeArrayCreateExpression paramArray = new CodeArrayCreateExpression(typeof(String[]), paramList);

                // return string[];
                nameTest.TrueStatements.Add(new CodeMethodReturnStatement(paramArray));
                codeMethod.Statements.Add(nameTest);
            }

            codeMethod.Statements.Add(new CodeMethodReturnStatement(new CodeArrayCreateExpression(typeof(String[]), 0)));
            resourceType.Members.Add(codeMethod);

            #endregion string[] IJrpcServiceInfo.GetMethodParams(string name);

            if (this.VirtualPathDependencies.Count > 0)
            {
                resourceType.BaseTypes.Add(typeof(IDependentResult));

                #region private static readonly string[] Dependencies

                field            = new CodeMemberField();
                field.Name       = "Dependencies";
                field.Type       = new CodeTypeReference(typeof(string[]));
                field.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;

                arrayInit = new CodeArrayCreateExpression(field.Type, this.VirtualPathDependencies.Count);
                foreach (string key in this.VirtualPathDependencies)
                {
                    arrayInit.Initializers.Add(new CodePrimitiveExpression(key));
                }
                field.InitExpression = arrayInit;

                resourceType.Members.Add(field);

                #endregion private static readonly string[] Dependencies

                #region IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }

                // add a readonly property returning the static data
                property      = new CodeMemberProperty();
                property.Name = "VirtualPathDependencies";
                property.Type = new CodeTypeReference(typeof(IEnumerable <string>));
                property.PrivateImplementationType = new CodeTypeReference(typeof(IDependentResult));
                property.HasGet = true;
                // get { return Dependencies; }
                property.GetStatements.Add(new CodeMethodReturnStatement(
                                               new CodeFieldReferenceExpression(
                                                   new CodeTypeReferenceExpression(resourceType.Name),
                                                   "Dependencies")));
                resourceType.Members.Add(property);

                #endregion IEnumerable<string> IDependentResult.VirtualPathDependencies { get; }
            }

            // Generate _ASP FastObjectFactory
            assemblyBuilder.GenerateTypeFactory(this.ResourceFullName);

            assemblyBuilder.AddCodeCompileUnit(this, generatedUnit);
        }