首页 > 代码库 > 简单的接口框架

简单的接口框架

  日常开发中经常会用到接口,传输都基于http,.net下有简单的ashx或aspx等搭载接口或MVC下的WebApi,或Wcf等。。

之前开发中用到了Web轻型框架:Nancy,Json序列化工具ServiceStack.Text,于是将两者结合下构造一个我自己的小接口框架

一.服务端抽象

先上5个基本抽象类和接口

1.请求基类:可包含一些账户等信息

public class RequestBase    {    }

2.响应基类:包括响应状态

public class ResponseBase    {        public ResponseBase()        {            Status = new ResponseStatus();        }        public ResponseStatus Status { get; set; }    }
public class ResponseStatus    {        public ResponseStatus()        {            this.ErrCode = string.Empty;            this.ErrMsg = string.Empty;        }        public ResponseStatus(string errCode, string errMsg)        {            this.ErrCode = errCode;            this.ErrMsg = errMsg;        }        /// <summary>        /// 是否成功        /// </summary>        public bool IsSuccess        {            get            {                if (string.IsNullOrEmpty(ErrCode) || string.IsNullOrEmpty(ErrMsg))                {                    return true;                }                else                {                    return false;                }            }        }        /// <summary>        /// 错误码        /// </summary>        public string ErrCode { get; set; }        /// <summary>        /// 错误信息        /// </summary>        public string ErrMsg { get; set; }    }

3.接口验证接口:验证请求参数等

public interface IBaseService<R, S>        where R : RequestBase        where S : ResponseBase    {        /// <summary>        /// 请求验证        /// </summary>        /// <param name="request">请求实体</param>        /// <returns></returns>        ResponseStatus Vaild(R request);    }

4.接口逻辑处理接口:处理核心逻辑

public interface ICoreService<R, S>        where R : RequestBase        where S : ResponseBase    {        S GetResponse(R r);    }

最终一个接口的请求验证——处理流程变成了这样:

public class ServiceClient    {        public static S Excute<R, S>(R r, IBaseService<R, S> baseService, ICoreService<R, S> coreService)            where R : RequestBase            where S : ResponseBase        {            S s = System.Activator.CreateInstance<S>();            try            {                s.Status = baseService.Vaild(r);                if (s.Status.IsSuccess)                {                    s = coreService.GetResponse(r);                }            }            catch (Exception ex)            {                s.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);            }            return s;        }    }

以上是接口服务端抽象出来的各个部分

 

二.接口Host:包括接口部署寄存的web以及Url规则和反射

Host采用Nancy框架,主要有两个路由:

Post["{Service}/{Request}"] = p =>            {                ErrResponse errResponse = new ErrResponse();                try                {                    string reqName = p.Request.ToString().ToLower().Trim();                    string serviceName = p.Service.ToString().ToLower().Trim();                    if (!Config.ServiceTypeList.ContainsKey(serviceName) || !Config.RequestTypeList.ContainsKey(reqName))                    {                        errResponse.Status = new ResponseStatus("0", "无此接口");                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                    }                    Type request = Config.RequestTypeList[reqName];                    Type response = Config.ResponseTypeList[reqName];                    Type service = Config.ServiceTypeList[serviceName];                    object req = JsonSerializer.DeserializeFromStream(request, Request.Body);                    if (req == null)                    {                        errResponse.Status = new ResponseStatus("0", "请求参数不能为空或格式错误");                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                    }                    object res = Config.DelegateList[reqName](req);//直接缓存委托                    return JsonSerializer.SerializeToString(res, response);                }                catch (Exception ex)                {                    errResponse.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);                    return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                }            };            Get["{Service}/{Request}"] = p =>            {                ErrResponse errResponse = new ErrResponse();                try                {                    string reqName = p.Request.ToString().ToLower().Trim();                    string serviceName = p.Service.ToString().ToLower().Trim();                    if (!Config.ServiceTypeList.ContainsKey(serviceName) || !Config.RequestTypeList.ContainsKey(reqName))                    {                        errResponse.Status = new ResponseStatus("0", "无此接口");                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                    }                    Type request = Config.RequestTypeList[reqName];                    Type response = Config.ResponseTypeList[reqName];                    Type service = Config.ServiceTypeList[serviceName];                    string strReq = Request.Query["request"];                    object req = JsonSerializer.DeserializeFromString(strReq, request);                    if (req == null)                    {                        errResponse.Status = new ResponseStatus("0", "请求参数不能为空或格式错误");                        return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                    }                    object res = Config.DelegateList[reqName](req);//直接缓存委托效率更高                    return JsonSerializer.SerializeToString(res, response);                }                catch (Exception ex)                {                    errResponse.Status = new ResponseStatus("0", "接口内部异常" + ex.Message);                    return JsonSerializer.SerializeToString<ErrResponse>(errResponse);                }            };

一个Get,一个Post处理逻辑是一样的,本来想分开,后来没什么时间,

Nancy部分可以参考开源项目:https://github.com/NancyFx/Nancy

这里主要讲下

1.路由:"{Service}/{Request}"根据不同的Service以及不同的Request获取对应的Type,接口在启动时已将所有Service以及请求,响应的Type做了缓存,还有处理方法(后面讲)

2.Json序列化:ServiceStack.Text

3.初始化缓存:

public class Config    {        public static Dictionary<string, Type> RequestTypeList = new Dictionary<string, Type>();        public static Dictionary<string, Type> ResponseTypeList = new Dictionary<string, Type>();        public static Dictionary<string, Type> ServiceTypeList = new Dictionary<string, Type>();        //public static Dictionary<string, MethodInfo> MethodInfoList = new Dictionary<string, MethodInfo>();        public static Dictionary<string, DoService> DelegateList = new Dictionary<string, DoService>();        public static void Init()        {            if (RequestTypeList.Count > 0)            {                return;            }            EntityClient.AddToDomain();            Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();            Assembly entitysAss = ass.Where(t => t.FullName.Contains("FaceManage.Entitys")).FirstOrDefault();            Assembly serviceAss = ass.Where(t => t.FullName.Contains("FaceManage.Services")).FirstOrDefault();            List<Type> reqTypes = entitysAss.GetTypes().Where(t => t.BaseType == typeof(RequestBase)).ToList();            List<Type> resTypes = entitysAss.GetTypes().Where(t => t.BaseType == (typeof(ResponseBase))).ToList();            List<Type> serviceTypes = serviceAss.GetTypes().Where(t => t.BaseType == typeof(ServiceBase)).ToList();            foreach (Type item in reqTypes)            {                RequestTypeList.Add(item.Name.Replace("Request", "").ToLower().Trim(), item);            }            foreach (Type item in resTypes)            {                ResponseTypeList.Add(item.Name.Replace("Response", "").ToLower().Trim(), item);            }            foreach (Type item in serviceTypes)            {                ServiceTypeList.Add(item.Name.Replace("Service", "").ToLower().Trim(), item);                MethodInfo[] methods = item.GetMethods(BindingFlags.Public | BindingFlags.Static);                foreach (MethodInfo method in methods)                {                    DoService serviceDelegate = (DoService)Delegate.CreateDelegate(typeof(DoService), null, method);                    DelegateList.Add(method.Name.ToLower().Trim(), serviceDelegate);                    //MethodInfoList.Add(method.Name, method);                }            }        }    }

这里我们知道接口符合一个委托,

public delegate object DoService(object request);

刚刚说到缓存方法就是创建方法的委托,并进行缓存,效率较高

 MethodInfo[] methods = item.GetMethods(BindingFlags.Public | BindingFlags.Static);                foreach (MethodInfo method in methods)                {                    DoService serviceDelegate = (DoService)Delegate.CreateDelegate(typeof(DoService), null, method);                    DelegateList.Add(method.Name.ToLower().Trim(), serviceDelegate);                    //MethodInfoList.Add(method.Name, method);                }

三。创建一个接口
1.请求:
public class UpdateMemberTypeRequest : RequestBase    {        public int MemberId { get; set; }        public int MemberType { get; set; }    }

2.响应:

public class UpdateMemberTypeResponse : ResponseBase    {        public bool IsSuccess { get; set; }    }

3.验证服务:

public class UpdateMemberTypeBase : IBaseService<UpdateMemberTypeRequest, UpdateMemberTypeResponse>    {        public ResponseStatus Vaild(UpdateMemberTypeRequest request)        {            ResponseStatus status = new ResponseStatus();            try            {                if (request.MemberId <= 0)                {                    throw new Exception("会员Id不能小于0");                }            }            catch (Exception ex)            {                status.ErrCode = "0";                status.ErrMsg = ex.Message;            }            return status;        }    }

4.处理逻辑:

public class UpdateMemberTypeCore : ICoreService<UpdateMemberTypeRequest, UpdateMemberTypeResponse>    {        public UpdateMemberTypeResponse GetResponse(UpdateMemberTypeRequest request)        {            UpdateMemberTypeResponse response = new UpdateMemberTypeResponse();            UpdateMemberTypeModel model = UpdateMemberTypeModel.Init(request);            response.Status = model.UpdateMemberType();            if (response.Status.IsSuccess)            {                response.IsSuccess = true;            }            return response;        }    }

5.一行代码

public static object UpdateMemberType(object req)        {            UpdateMemberTypeRequest request = (UpdateMemberTypeRequest)req;            return ServiceClient.Excute<UpdateMemberTypeRequest, UpdateMemberTypeResponse>(request, new UpdateMemberTypeBase(), new UpdateMemberTypeCore());        }

这样一个接口就开发Ok,

当然还忘了一点,这个时候其实你已经完成建立你自己接口的SDK

public static T Excute<T, S>(S req, string url)        {            T rsp = Activator.CreateInstance<T>();            string reqJson = JsonSerializer.SerializeToString<S>(req);            string resJson = HttpHelper.DoPost(url, reqJson, Encoding.UTF8);            return JsonSerializer.DeserializeFromString<T>(resJson);        }

调用方:

AddCooperaterRequest request = new AddCooperaterRequest()            {                Name = "test",                PassWord = "test"            };            AddCooperaterResponse response = EntityClient.Excute<AddCooperaterResponse, AddCooperaterRequest>(request, "http://localhost/FaceManage/BaseMember/AddCooperater");

原项目将过几天开源