public string Generate(GenerationOptions options) { var compileUnit = this.GenerateUnit(options); var provider = new CSharpCodeProvider(); using (var sw = new StringWriter()) { provider.GenerateCodeFromCompileUnit(compileUnit, sw, new CodeGeneratorOptions {}); string codeText = sw.GetStringBuilder().ToString(); return SugarUp(codeText.Substring(codeText.IndexOf("using", System.StringComparison.Ordinal))); } }
public CodeCompileUnit GenerateUnit(GenerationOptions generationOptions) { string serviceInterfaceNamespace = "ServiceStack.ServiceInterface"; var type = generationOptions.Target; var codeDomNamespace = new CodeNamespace("ServiceStackGen.Tests.Examples"); var compileUnit = new CodeCompileUnit(); var globalNamespace = new CodeNamespace(); globalNamespace.Imports.Add(new CodeNamespaceImport(serviceInterfaceNamespace)); compileUnit.Namespaces.Add(globalNamespace); compileUnit.Namespaces.Add(codeDomNamespace); globalNamespace.Comments.Clear(); var @class = new CodeTypeDeclaration(generationOptions.TypeName); @class.BaseTypes.Add(serviceInterfaceNamespace + ".Service"); codeDomNamespace.Types.Add(@class); @class.Members.Add(new CodeMemberField(type.FullName, "_" + LowerCamelCase(type.Name))); //add constructor var ctor = new CodeConstructor(); ctor.Parameters.Add(new CodeParameterDeclarationExpression(type.FullName,LowerCamelCase(type.Name))); ctor.Attributes = MemberAttributes.Public; @class.Members.Add(ctor); var thisDotField = new CodeTypeReferenceExpression( "_" + LowerCamelCase(type.Name)); var assignment = new CodeAssignStatement(thisDotField, new CodeArgumentReferenceExpression(LowerCamelCase(type.Name))); ctor.Statements.Add(assignment); //generate methods which are mapped to their own wrapping types type.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance) .Where(m => { if (generationOptions.MethodNameRegex != null) { return Regex.IsMatch(m.Name, generationOptions.MethodNameRegex); } return true; }) .ToList() .ForEach(m => { var request = new CodeTypeDeclaration(m.Name); codeDomNamespace.Types.Add(request); var response = new CodeTypeDeclaration(m.Name + "Result"); codeDomNamespace.Types.Add(response); //create any method var anyMethod = new CodeMemberMethod { Name = "Any", Attributes = MemberAttributes.Public }; //add parameters anyMethod.Parameters.Add(new CodeParameterDeclarationExpression(m.Name, LowerCamelCase(request.Name))); //add return anyMethod.ReturnType = new CodeTypeReference(response.Name); //add methodBody var proxy = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("_" + LowerCamelCase(type.Name)),m.Name); m.GetParameters().ToList().ForEach(p => { //request request.Members.Add(new CodeMemberProperty { Name = UpperCamelCase(p.Name), Type = new CodeTypeReference(TypeName(p.ParameterType.FullName)), Attributes = MemberAttributes.Abstract | MemberAttributes.Public, HasGet = true, HasSet = true}); //proxy assignment var proxyAssign = new CodePropertyReferenceExpression( new CodeTypeReferenceExpression(LowerCamelCase(request.Name)) ,UpperCamelCase(p.Name)); proxy.Parameters.Add(proxyAssign); }); if (m.ReturnType != typeof (void)) { response.Members.Add(new CodeMemberProperty { Name = "Result", Type = new CodeTypeReference(TypeName(m.ReturnType.FullName)), Attributes = MemberAttributes.Abstract | MemberAttributes.Public, HasGet = true, HasSet = true }); var creation = new CodeObjectCreateExpression(TypeName(m.Name + "Result")); var variableCreation = new CodeVariableDeclarationStatement("var", LowerCamelCase( TypeName(m.Name + "Result")), creation); anyMethod.Statements.Add(variableCreation); //assign to proxy var reference = new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(LowerCamelCase(m.Name + "Result")), "Result"); anyMethod.Statements.Add(new CodeAssignStatement(reference, proxy)); anyMethod.Statements.Add(new CodeMethodReturnStatement { Expression = new CodeVariableReferenceExpression( LowerCamelCase(m.Name + "Result")) }); } else { anyMethod.Statements.Add(proxy); // return null anyMethod.Statements.Add( new CodeMethodReturnStatement { Expression = new CodePrimitiveExpression(null) }); } @class.Members.Add(anyMethod); }); return compileUnit; }