如果重新写restfull接口的话,定义各种DTO类型就是一个很大的工作量。考虑到webservcie已经定义了很多类型,所以打算采用反射的方式将webservice接口和方法全部提取出来,转化为restfull接口。
代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace XX.WebService.Test
{
public class WebServcieToRestfull
{
///
/// 生成API接口
///
public void GenerateApiInterfaceClasses()
{
var assembly = Assembly.Load("XX.WebService");
var types = assembly.GetTypes();
//方法,转换为API方法
var typeList = new List();
foreach (var type in types)
{
var attrs = type.GetCustomAttributes();
if (attrs.Any())
{
typeList.Add(type);
}
}
foreach (var type in typeList)//接口类
{
var typeName = type.Name.Replace("Service", "");
var methods = type.GetMethods();
var clist = new List();
foreach (var m in methods)
{
var mattr = m.GetCustomAttribute();
if (mattr != null)//接口方法
{
var mname = m.Name.Substring(0, 1).ToUpper() + m.Name.Substring(1);
var paras = m.GetParameters();
var rtnType = string.Format("{0}", m.ReturnType.Name);
if (rtnType == "Void")
{
rtnType = string.Format("{0}Response", mname);
}
var mstr = GetAPIMethodStr(mname);
clist.Add(mstr);
if (paras.Any(p => p.IsOut))
{
var outParams = paras.Where(p => p.IsOut).ToArray();
var outMehodStr = GetAPIOutMethodStr(mname, outParams);
clist.Add(outMehodStr);
}
}
}
var classStr = string.Join("\r\n", clist);
var fileStr = GetAPIInteraceNameSpaceStr(typeName, classStr);
using (FileStream fsWrite = new FileStream("I" + typeName + "API.cs", FileMode.OpenOrCreate))
{
byte[] myByte = System.Text.Encoding.UTF8.GetBytes(fileStr);
fsWrite.Write(myByte, 0, myByte.Length);
};
}
}
///
/// 生成API类
///
public void GenerateApiClasses()
{
var assembly = Assembly.Load("XX.WebService");
var types = assembly.GetTypes();
//方法,转换为API方法
var typeList = new List();
foreach (var type in types)
{
var attrs = type.GetCustomAttributes();
if (attrs.Any())
{
typeList.Add(type);
}
}
foreach (var type in typeList)//接口类
{
var typeName = type.Name.Replace("Service", "");
var methods = type.GetMethods();
var clist = new List();
foreach (var m in methods)
{
var mattr = m.GetCustomAttribute();
if (mattr != null)//接口方法
{
var mname = m.Name.Substring(0, 1).ToUpper() + m.Name.Substring(1);
var paras = m.GetParameters();
var rtnType = string.Format("{0}Response", mname);
var mstr = GetMethodStr(rtnType, mname);
clist.Add(mstr);
if (paras.Any(p => p.IsOut))
{
var outParams = paras.Where(p => p.IsOut).ToArray();
var outMehodStr = GetOutMethodStr(rtnType, mname, outParams);
clist.Add(outMehodStr);
}
}
}
var classStr = string.Join("\r\n", clist);
var fileStr = GetAPINameSpaceStr(typeName, classStr);
using (FileStream fsWrite = new FileStream(typeName + "API.cs", FileMode.OpenOrCreate))
{
byte[] myByte = System.Text.Encoding.UTF8.GetBytes(fileStr);
fsWrite.Write(myByte, 0, myByte.Length);
};
}
}
///
/// 生成API类型类
///
public void GenerateApiTypeClasses()
{
var assembly = Assembly.Load("XX.WebService");
var types = assembly.GetTypes();
//类型
var nsTypes = new Dictionary>();
var typeClasses = new Dictionary();
foreach (var type in types)
{
var attrs = type.GetCustomAttributes();
if (attrs.Any())
{
var nameSpace = type.Namespace
.Replace("XX.WebService.", "")
.Replace("Service", "");
if (!nsTypes.ContainsKey(nameSpace))
{
nsTypes.Add(nameSpace, new List());
}
nsTypes[nameSpace].Add(type);
}
}
foreach (var ns in nsTypes)
{
var typeList1 = ns.Value;
var clist = new List();
foreach (var type in typeList1)
{
var properties = type.GetProperties();
var plist = new List();
foreach (var p in properties)
{
var ptype = p.PropertyType.Name;
var pname = p.Name;
if (p.Name == "adType")
{
ptype = "int?";
}
if (p.Name == "operator")
{
pname = "@operator";
}
var str = GetPropertyStr(ptype, pname);
plist.Add(str);
}
var propertiesStr = string.Join("\r\n", plist);
var classStr = GetClassStr(type.Name, propertiesStr);
clist.Add(classStr);
}
var classesStr = string.Join("\r\n", clist);
typeClasses.Add(ns.Key, classesStr);
}
//方法
var typeList = new List();
foreach (var type in types)
{
var attrs = type.GetCustomAttributes();
if (attrs.Any())
{
typeList.Add(type);
}
}
foreach (var type in typeList)//接口类
{
var typeName = type.Name.Replace("Service", "");
var methods = type.GetMethods();
var clist = new List();
foreach (var m in methods)
{
var mattr = m.GetCustomAttribute();
if (mattr != null)//接口方法
{
var mname = m.Name.Substring(0, 1).ToUpper() + m.Name.Substring(1);
if (mname == "GetChangedCpcPlanId")
{
var a = 1;
}
var api = mattr.Action
.Replace("https://api.XX.com/sem/sms/v1/", "")
.Replace("Service/", "/");
var responseClassStr = "";
var paras = m.GetParameters();
//out参数,转化为ResponseClass
if (paras.Any(p => p.IsOut))
{
var outParams = paras.Where(p => p.IsOut).ToArray();
var responsepropertiesStr = GetParameterToPropertiesStr(outParams);
if (m.ReturnType.Name != "Void")
{
var rtnTypeName = m.ReturnType.Name;
var rntProName = rtnTypeName.Replace("[]", "");
rntProName = rntProName.Substring(0, 1).ToLower() + rntProName.Substring(1) + "Vos";
var str = GetPropertyStr(rtnTypeName, rntProName);
responsepropertiesStr = str + "\r\n" + responsepropertiesStr;
}
responseClassStr = GetResponseClass(mname, responsepropertiesStr);
}
else
{
var responsepropertiesStr = "";
if (m.ReturnType.Name != "Void")
{
var rtnTypeName = m.ReturnType.Name;
var rntProName = rtnTypeName.Replace("[]", "");
rntProName = rntProName.Substring(0, 1).ToLower() + rntProName.Substring(1);
if (rntProName == "string") rntProName = "string1";
var str = GetPropertyStr(rtnTypeName, rntProName);
responsepropertiesStr = str + "\r\n" + responsepropertiesStr;
}
responseClassStr = GetResponseClass(mname, responsepropertiesStr);
}
var requestProperties = paras.Where(p => !p.IsOut).ToArray();
var propertiesStr = GetParameterToPropertiesStr(requestProperties);
//单独处理PageType
if (requestProperties.Length == 1 && requestProperties[0].ParameterType.Name == "PageType")
{
var rp = requestProperties[0];
var bodyType = rp.ParameterType.Name;
var classStr1 = GetRequestClass2(api, mname, bodyType, responseClassStr);
clist.Add(classStr1);
continue;
}
var classStr = GetRequestClass(api, mname, propertiesStr, responseClassStr);
clist.Add(classStr);
}
}
var typeClass = typeClasses[typeName];
clist.Add(typeClass);
var classesStr = string.Join("\r\n", clist);
var fileStr = GetNameSpaceStr(typeName, classesStr);
using (FileStream fsWrite = new FileStream(typeName + "Request.cs", FileMode.OpenOrCreate))
{
byte[] myByte = System.Text.Encoding.UTF8.GetBytes(fileStr);
fsWrite.Write(myByte, 0, myByte.Length);
};
}
}
///
/// 接口方法
///
///
///
///
private string GetMethodStr(string rtnType, string mname)
{
var str = @"
public Response<{1}> {0}({0}Request request)
{
var resp = api.Post<{1}>(request);
return resp;
}";
return str
.Replace("{0}", mname)
.Replace("{1}", rtnType);
}
///
/// 包含out参数的接口方法
///
///
///
///
///
private string GetOutMethodStr(string rtnType, string mname, ParameterInfo[] properties)
{
var list1 = new List();
var list2 = new List();
foreach (var p in properties)
{
if (p.Name.EndsWith("Specified")) continue;
var out1 = string.Format(@"out {0} {1}", p.ParameterType.Name.Replace("&", ""), p.Name);
list1.Add(out1);
var code1 = string.Format(@" {0} = resp.data.{0};", p.Name);
list2.Add(code1);
}
var outParams = string.Join(" ,", list1);
var outCodes = string.Join("\r\n", list2);
var str = @"
public Response<{3}> {0}({0}Request request, {1})
{
var resp = api.Post<{3}>(request);
{2}
return resp;
}";
return str.Replace("{0}", mname)
.Replace("{1}", outParams)
.Replace("{2}", outCodes)
.Replace("{3}", rtnType);
}
///
/// 接口方法接口定义
///
///
///
private string GetAPIMethodStr(string mname)
{
var str = @"
Response<{0}Response> {0}({0}Request request);";
return str.Replace("{0}", mname);
}
///
/// 包含参数的接口方法接口定义
///
///
///
///
private string GetAPIOutMethodStr(string mname, ParameterInfo[] properties)
{
var list1 = new List();
foreach (var p in properties)
{
if (p.Name.EndsWith("Specified")) continue;
var out1 = string.Format(@"out {0} {1}", p.ParameterType.Name.Replace("&", ""), p.Name);
list1.Add(out1);
}
var outParams = string.Join(" ,", list1);
var str = @"
Response<{0}Response> {0}({0}Request request, {1});";
return str.Replace("{0}", mname)
.Replace("{1}", outParams);
}
///
/// 所有属性
///
///
///
private string GetParameterToPropertiesStr(ParameterInfo[] properties)
{
var plist = new List();
foreach (var p in properties)
{
if (p.Name.EndsWith("Specified")) continue;
var str = GetPropertyStr(p.ParameterType.Name.Replace("&", ""), p.Name);
plist.Add(str);
}
var propertiesStr = string.Join("\r\n", plist);
return propertiesStr;
}
///
/// 所有请求类
///
///
///
///
///
///
private string GetRequestClass(string api, string typeName, string paramstr, string responseClass)
{
var str = @"
[APIMetadata(""/api/v2/{0}"")]
public class {1}Request : RequestBase
{
public {1}RequestType body { get; set; }
}
public class {1}RequestType
{
{2}
}
{3}";
return str.Replace("{0}", api)
.Replace("{1}", typeName)
.Replace("{2}", paramstr)
.Replace("{3}", responseClass);
}
///
/// 所有请求类2
///
///
///
///
///
///
private string GetRequestClass2(string api, string typeName, string bodyType, string responseClass)
{
var str = @"
[APIMetadata(""/api/v2/{0}"")]
public class {1}Request : RequestBase
{
public {2} body { get; set; }
}
{3}";
return str.Replace("{0}", api)
.Replace("{1}", typeName)
.Replace("{2}", bodyType)
.Replace("{3}", responseClass);
}
private string GetResponseClass(string typeName, string paramstr)
{
var str = @"
public class {0}Response
{
{1}
}";
return str.Replace("{0}", typeName).Replace("{1}", paramstr);
}
private string GetClassStr(string tableName, string propertiesStr)
{
var str = @"
public class {0}
{
{1}
}";
//return string.Format(str, tableName, propertiesStr);
return str.Replace("{0}", tableName).Replace("{1}", propertiesStr);
}
private string GetPropertyStr(string type, string name)
{
var str = @" public {0} {1} { get; set; }";
return str.Replace("{0}", type).Replace("{1}", name);
}
private string GetNameSpaceStr(string ns, string calssesStr)
{
var str = @"using XX.Framework;
using System;
using System.Collections.Generic;
using System.Text;
namespace XX.WebService.Request.{0}
{
{1}
}";
return str.Replace("{0}", ns).Replace("{1}", calssesStr);
}
private string GetAPINameSpaceStr(string typename, string methodsStr)
{
var str = @"using XX.Framework;
using XX.WebService.Request.{0};
using XX.WebService.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace XX.WebService.Implements
{
public class {0}API : I{0}API
{
IAPIService api;
ILogService log;
public {0}API(IAPIService api, ILogService log)
{
this.api = api;
this.log = log;
}
{1}
}
}";
return str.Replace("{0}", typename).Replace("{1}", methodsStr);
}
private string GetAPIInteraceNameSpaceStr(string typename, string methodsStr)
{
var str = @"using XX.Framework;
using XX.WebService.Request.{0};
using System;
using System.Collections.Generic;
using System.Text;
namespace XX.WebService.Interfaces
{
public interface I{0}API
{
{1}
}
}";
return str.Replace("{0}", typename).Replace("{1}", methodsStr);
}
}
}