如果使用WeChatAPI,它扮演着什么样的角色?

从图中我们可以看到主要分为3个部分:

1.业务系统

2.WeChatAPI:

  WeChatWebAPI,主要是接收微信服务器请求;

  WeChatAPI Service:主要是提供一些微信基础操作给业务系统使用。(这里有个问题,目前规划是不包含回调业务系统的。当然这并不是无法扩展的。)

3.微信服务器

项目结构

1.Test:测试目录

  1.1UnitTest:单元测试目录

    WeChatService.Test:微信服务测试

2.UI:界面目录

  WeChatWebAPI:微信网页接口,接收微信服务器请求

3.Server:服务端目录

  Business:主要是通过触发Event来执行Commands,隔离底层业务逻辑。

  Commands:真正的微信业务指令,在此层与微信服务器交互。

  Contracts:提供微信服务接口契约。

  Events:定义微信业务事件。

  Models:定义数据契约、微信交互对象、枚举等。

4.Insfrastructure:基础设施目录

  4.1Lib:类库目录

    CommonLib:通用辅助类库

    WCFLib:WCF辅助类库

  4.2Plugins:插件目录

    DispatchchingCenter:调度中心负责映射Event和Command的关系,并提供一些通用业务逻辑的处理。

5.Publish:发布目录(目前还没有做,这里将会做成Windows服务,主要是真正发布时用的环境)

6.DevEnvironment:开发环境目录(主要是针对开发,方便调试)

  DevHost:开发主机,可直接针对此项目进行调试。

时序图

实现一个接口:自定义菜单查询

微信API传送门:http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html

  分析微信接口

1. http请求:GET,地址为:https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN

2.请求参数只有一个 access_token

3.返回参数,这个微信偷懒了,可以看创建菜单接口里很清晰 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 

  创建Model

根据分析接口得到一个结果,发送请求时是不需要新的实体,而返回结果是需要的。

BaseMenu.cs

     /// <summary>
/// 菜单基类
/// </summary>
[DataContract(Name = "menu")]
[KnownType(typeof(ClickMenu))]
[KnownType(typeof(DropDownMenu))]
[KnownType(typeof(ViewMenu))]
public class BaseMenu
{
/// <summary>
/// 菜单名称
/// </summary>
[DataMember(Name = "name")]
public string Name { get; set; }
}

MenuList.cs

     /// <summary>
/// 菜单列表
/// </summary>
[DataContract(Name = "menu_list")]
public class MenuList
{
/// <summary>
/// 菜单集合
/// </summary>
[DataMember(Name = "button")]
public List<BaseMenu> MenuSet { get; set; }
}

DropDownMenu.cs

     /// <summary>
/// 下拉菜单
/// </summary>
[DataContract(Name = "drop_down_menu")]
public class DropDownMenu : BaseMenu
{
/// <summary>
/// 子菜单
/// </summary>
[DataMember(Name = "sub_button")]
public List<BaseMenu> MenuSet { get; set; }
}

ViewMenu.cs

     /// <summary>
/// 跳转URL菜单
/// </summary>
[DataContract(Name = "view_menu")]
public class ViewMenu : BaseMenu
{
/// <summary>
/// 类型
/// </summary>
[DataMember(Name = "type")]
public string Type { get { return "view"; } set { } } /// <summary>
/// 跳转的URL
/// </summary>
[DataMember(Name = "url")]
public string Url { get; set; }
}

ClickMenu.cs

     /// <summary>
/// 点击推事件菜单
/// </summary>
[DataContract(Name = "click_menu")]
public class ClickMenu : BaseMenu
{
/// <summary>
/// 类型
/// </summary>
[DataMember(Name = "type")]
public string Type { get { return "click"; } set { } } /// <summary>
/// 事件关键字
/// </summary>
[DataMember(Name = "key")]
public string Key { get; set; }
}

需要注意两点:

1. DataContract(Name=xxx) 和 DataMember(Name=xxx) 其实是告诉序列化器,序列化后的参数名。因为C#的命名规则跟微信的不一样,所以为了方便C#开发,我保持了原有的命名规则,通过这种方式在序列化时改成微信要求的参数名。

2. BaseMenu的[KnowType(typeof(xxx))] ,这个是因为在接口定义上并没有细化到 DorpDownMenu、ViewMenu、ClickMenu,而是抽离出一个基类来操作的,为了引用时可以感知到派生类,需要增加KnowType特性,这是WCF的事情,不详说了。

  创建Event

GetMenuEvent.cs

     /// <summary>
/// 查询菜单事件
/// </summary>
public class GetMenuEvent : DispatchEvent, IAccessTokenAuth
{
public string AccessToken { get; set; } public MenuList MenuList { get; set; }
}

通过上面分析微信接口我们知道,参数应该只有一个AccessToken,为什么会多一个MenuList?

这个问题之前文章有写到,简单提一下,是为了Commands直接操作引用类型,把值从GetMenuEvent类传回来。

DispatchEvent:这个是告诉Dispatcher,当前类是一个调度事件。这样Dispatcher就会在你激活这个事件时去找对应的Command。

IAccessTokenAuth:调度器执行DispatchHandler之前会执行BeforeActive,从而激活AccessTokenCommand.FillAccessToken来帮助填充AccessToken。这一块之前也有说过。

  实现Command

1.添加一个CommandRequest,指定访问的URL

MenuCommandRequest.cs

     /// <summary>
/// 查询菜单命令请求
/// </summary>
public class GetMenuCommandRequest : BaseCommandRequest
{
public GetMenuCommandRequest(string accessToken)
{
this.Method = HttpMethod.GET;
this.URL = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken);
}
}

2.添加一个Command,实现GetMenuEvent

         /// <summary>
/// 查询菜单
/// </summary>
/// <param name="e"></param>
[DispatchHandler(typeof(GetMenuEvent))]
public void GetMenu(GetMenuEvent e)
{
var commandRequest = new GetMenuCommandRequest(e.AccessToken); e.MenuList = CommandHelper.GetWeChatResponseObject<Models.Menu.MenuList>(commandRequest);
}
  创建Business

MenuOperation.cs

         public MenuList GetMenu()
{
var getMenuEvent = new GetMenuEvent(); Dispatcher.ActiveEvent(getMenuEvent); return getMenuEvent.MenuList;
}
  创建Service Contract

IMenuService.cs

         [OperationContract]
[FaultContractAttribute(typeof(FaultMessage))]
MenuList GetMenu();

WeChatService.cs

         public Models.Menu.MenuList GetMenu()
{
return new Businesses.Menu.MenuOperation().GetMenu();
}

这个类库关系到你的服务是否真正的提供出去。因为这里使用的是WCF,Copy我的类即可,如果研究WCF的话可自行搜索相关教程。

  修改配置文件

因为我并没有新增一个新的服务契约接口类,所以此时并不需要增加下面的代码,只是点明一下是哪里让它生效的而已。

DevHost项目的app.config

         <endpoint address="http://localhost:15000/WeChatService/Menu"
binding="basicHttpBinding"
bindingConfiguration="WeChatBinding"
contract="Contracts.Interfaces.Menu.IMenuService" >
</endpoint>

PS:这个例子流程上没什么大问题,就是json序列化成menu的时候为null,因为赶着出这篇博客,所以还没修复这个问题。

等我有空把这个修复一下。大概定位到问题是我这里抽象了一个BaseMenu,然后序列化器不识别。

你是不是跟我们一样,对编程还充满激情?

我可以做这些事情是因为我对知识的敬畏,越了解越可怕。

但我不畏惧,因为这探索知识的路上有我、有你、有他们。

如果你想加入我们,可以加我们的群:7424099

最后,源码传送门:http://git.oschina.net/doddgu/WeChatAPI

最后的最后,再次提示:这并不是一个完整的项目!!!

PS:时序图里出现PrintSQL,这个其实不存在的,因为Copy了之前的文档,图片已经上传了就没改。

【轮子狂魔】WeChatAPI 开源系统架构详解的更多相关文章

  1. WeChatAPI 开源系统架构详解

    WeChatAPI 开源系统架构详解 如果使用WeChatAPI,它扮演着什么样的角色? 从图中我们可以看到主要分为3个部分: 1.业务系统 2.WeChatAPI: WeChatWebAPI,主要是 ...

  2. 大型web系统架构详解

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) 动态应用,是相对于网站静态内 ...

  3. Flume日志收集系统架构详解--转

     2017-09-06 朱洁 大数据和云计算技术 任何一个生产系统在运行过程中都会产生大量的日志,日志往往隐藏了很多有价值的信息.在没有分析方法之前,这些日志存储一段时间后就会被清理.随着技术的发展和 ...

  4. NopCommerce源码架构详解--初识高性能的开源商城系统cms

    很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...

  5. NopCommerce源码架构详解

    NopCommerce源码架构详解--初识高性能的开源商城系统cms   很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...

  6. Nop--NopCommerce源码架构详解专题目录

    最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...

  7. Hyperledger Fabric架构详解

    区块链开源实现HYPERLEDGER FABRIC架构详解 区块链开源实现HYPERLEDGER FABRIC架构详解 2018年5月26日 陶辉 Comments 10 Comments hyper ...

  8. mysql show variables系统变量详解

    mysql系统变量详解 mysqld服务器维护两种变量.全局变量影响服务器的全局操作.会话变量影响具体客户端连接相关操作. 服务器启动时,将所有全局变量初始化为默认值.可以在选项文件或命令行中指定的选 ...

  9. 领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

随机推荐

  1. MacOS(苹果电脑&苹果系统)连接京瓷300i 打印机

    前往京瓷官网下载打印机驱动: http://www.kyoceradocumentsolutions.com.cn/support/mfp/download/taskalfa300i.html 驱动安 ...

  2. Office 365实现单点登录系列(3)—使用Azure AD Connect 进行目录同步

    Hello 小伙伴们,我回来了~ 2017年底中招了流感,还得了结膜炎,我也是无奈的···但使命感驱使我还是要把文章更完(这么敬业还不点赞关注(*^__^*) ) 我们接着上一篇文章继续说,上一篇已经 ...

  3. Win10下安装sulley

    sulley是一款针对网络协议的fuzz框架,记录下安装过程备忘 1.安装MinGW 下载:https://github.com/develersrl/gccwinbinaries/releases/ ...

  4. c++问题整理

    1.C++ 多态,多态的实现,c++虚函数,虚函数和纯虚函数有什么区别,虚函数的实现原理,虚继承,析构函数能否为虚,为什么析构要虚函数,析构函数声明为虚函数的作用,构造函数为啥不能定义为虚函数,析构函 ...

  5. active developer path ("/Applications/Xcode.app/Contents/Developer")

    -> git xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer" ...

  6. RANSAC与 最小二乘(LS, Least Squares)拟合直线的效果比较

    代码下载地址: 1.Matlab版本:http://pan.baidu.com/s/1eQIzj3c.进入目录后,请自行定位到该博客的源代码与数据的目录“

  7. sqoop-1.4.7 搭建

    sqoop搭建环境:   jdk1.8    hadoop分布式集群(HDFS)     HIVE(看使用情况) 下载网址:http://sqoop.apache.org/ 建议: sqoop1.4. ...

  8. iis7中session丢失的解决方法小结

    这篇文章主要介绍了在windows server 2008系统中,session丢失的解决方法,供大家学习参考 问题描述: Windows Server 2008 +IIS +ASP.net +SQL ...

  9. 内部元素一一相应的集合的算法优化,从list到hashmap

    说是算法优化,基本上是在吹牛,仅仅只是算是记录下,我写代码时候的思路.毕竟还是小菜鸟. 我要开一个party,与会者都是情侣,可是情侣并非一起过来的,而是有先有后,可是每位与会者来的时候都拿着一束鲜花 ...

  10. Git知多少!!!

    第一次写博客,内心有点小激动呀!首先祝大家圣诞快乐~~啦啦啦~~好了,我要步入正题啦!今天是上班第二周,终于开始写需求啦!开森~~撒花~~ 来这里第一个要学的就是git的操作啦!入职第一天发了一个大大 ...