码迷,mamicode.com
首页 > 其他好文 > 详细

简单的接口框架

时间:2014-08-05 19:04:19      阅读:349      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   os   io   for   

  日常开发中经常会用到接口,传输都基于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");

原项目将过几天开源

简单的接口框架,布布扣,bubuko.com

简单的接口框架

标签:des   style   blog   http   color   os   io   for   

原文地址:http://www.cnblogs.com/isingel/p/3892717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!