BrnShop开源网上商城第四讲:自定义插件

重要通知:BrnShop企业版NOSQL设计(基于Redis)已经开源!源码内置于最新版的BrnShop中,感兴趣的园友可以去下载来看看。官网地址:www.brnshop.com

  好了现在进入今天的正题:自定义插件。上一讲中我们已经阐述了BrnShop插件的工作机制,现在我们详细介绍下如何自定义插件。首先BrnShop的插件从功能上分为三类,分别是:

  • 开放授权插件(OAuth)
  • 支付插件
  • 配送插件

  对应的接口文件(注:位于BrnShop.Core项目的Plugin/Base文件夹中)依次如下:

  • IOAuthPlugin
  • IPayPlugin
  • IShipPlugin

  现在我们依次介绍下各个接口,首先登场的是IOAuthPlugin接口。先看它的定义:

    /// <summary>
/// BrnShop开放授权插件接口
/// </summary>
public interface IOAuthPlugin : IPlugin
{
/// <summary>
/// 登陆控制器
/// </summary>
string LoginController { get; } /// <summary>
/// 登陆动作方法
/// </summary>
string LoginAction { get; } /// <summary>
/// 登陆路由数据
/// </summary>
RouteValueDictionary LoginRouteValues { get; }
}

  对于一个开放授权插件来说,它只需要向主应用程序提供自己的一个登陆地址就可以,至于怎么授权验证等那都是插件自己的事情了。所以IOAuthPlugin接口内容仅仅是登陆地址的mvc3要素(控制器名,动作方法名,路由数据)就可以了,以QQ授权登陆为例:

  

  接下来是IPayPlugin接口,代码如下:

 

  成员比较多,我们分类来看就清晰了:

  • PayMode:代表支付的3种类型,这个属性非常重要,因为其它成员的实现跟他密切相关。
  • GetPayFee:计算订单的支付手续费。
  • GetRequestUrl:只在PayMode为在线付款时有效;返回支付地址,在BrnShop.Web项目的OrderController类的PayShow方法中调用。
  • ReturnController,ReturnAction,ReturnRouteValues:这3个成员为一组,并且只在PayMode为在线付款时有效;提供支付完成后的返回地址。
  • NotifyController,NotifyAction,NotifyRouteValues:这3个成员为一组,并且只在PayMode为在线付款时有效;提供支付完成后的回调地址。
  • AllowRecharge:系统预留成员,目前无用。

  最后我们来看下IShipPlugin接口,代码如下:

    /// <summary>
/// BrnShop配送插件接口
/// </summary>
public interface IShipPlugin : IPlugin
{
/// <summary>
/// 获得配送费用
/// </summary>
/// <param name="totalWeight">订单总重量</param>
/// <param name="productAmount">商品合计</param>
/// <param name="buyTime">购买时间</param>
/// <param name="shipRegionId">收货区域</param>
/// <param name="partUserInfo">购买用户</param>
/// <returns></returns>
decimal GetShipFee(int totalWeight, decimal productAmount, DateTime buyTime, int shipRegionId, PartUserInfo partUserInfo);
}

  这个接口比较简单,只是提供一个计算配送费用的成员。

  补充说明一下:以上3个接口都继承自IPlugin,这个接口提供后台配置地址mvc3要素,只在BrnShop.Web.Admin项目中的插件配置视图中使用,具体如下:

    @if (Model.ConfigRouteValues == null)
{
@Html.Action(Model.ConfigAction, Model.ConfigController)
}
else
{
@Html.Action(Model.ConfigAction, Model.ConfigController, Model.ConfigRouteValues)
}

  下面我们以支付宝插件为例来讲解下如何自定义一个插件。

   首先新建一个ASP.NET MVC3应用程序并引用需要的程序集,根据上一篇讲解我们知道需要修改非.net自带程序集的复制到本地属性和项目生成属性。具体如下图:

  至此我们的项目基本框架已经搭好了。现在我们需要添加一个插件说明文件(注:此文件为必须文件且文件名称必须为PluginInfo.config,还有不要忘记修改它的复制属性)。内容如下:

<?xml version="1.0" encoding="utf-8"?>
<PluginInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SystemName>alipay</SystemName>
<FriendlyName>支付宝</FriendlyName>
<ClassFullName>BrnShop.PayPlugin.Alipay.PluginService,BrnShop.PayPlugin.Alipay</ClassFullName>
<Folder>BrnShop.PayPlugin.Alipay</Folder>
<Description>阿里巴巴旗下支付工具</Description>
<Type>1</Type>
<Author>brnshop</Author>
<Version>1.0</Version>
<SupVersion>1.0.0</SupVersion>
<DisplayOrder>3</DisplayOrder>
<IsDefault>0</IsDefault>
</PluginInfo>

  这个文件是BrnShop.Core项目中的PluginInfo序列化文件,所以节点说明请参考下面代码:

 

  接下来我们定义一个类PluginService,并实现接口IPayPlugin,代码如下:

 

  因为支付宝有一些需要配置的属性要保存,例如收款支付宝帐户等。在此我们采用对象序列化和文件的方式来保存这些信息。首先定义一个设置信息类,代码如下:

 

  然后添加一个工具类PluginUtils来序列化和反序列化设置信息,代码如下:

 

  就下来就是前台和后台实现了。首先是后台实现,对于后台我们只需要提供一个可供修改支付宝配置的子方法就行了,此子方法在上面讲解"IPlugin"接口时已经给出了它的调用方式。代码如下:

 

  至于前台我们有3个方面需要去实现,第一个方面是返回调用动作方法,代码如下:

 

  第二个方面是通知调用动作方法,代码如下:

 

  第三个方面是我们需要提供一个支付宝简介的视图文件,这个视图文件在顾客支付订单时给其展示一些支付宝的说明信息,此文件有以下几点要求:

  • 文件名必须为"Show.cshtml"。
  • 此文件必须位于插件项目的Views文件夹的顶层中。
  • 此视图文件接收类型为OrderInfo的视图模型对象。

  这个视图文件在BrnShop.Web项目的支付展示视图文件PayShowModel.cshtml中调用,调用方式如下:

@Html.Partial(Model.ShowView, Model.OrderInfo)

  至此支付宝插件开发完成,至于其它类型的插件开发也都是大同小异。

  PS:最后附上一张BrnShop开启NOSQL前后的性能对比图,以商品详细页面为例:

   开启NOSQL前:

  开启NOSQL后:

  可见性能提升还是很明显的。

  有对网上商城程序设计感兴趣的朋友,欢迎加入QQ群:235274151,大家可以交流下!

BrnShop:自定义插件的更多相关文章

  1. BrnShop开源网上商城第四讲:自定义插件

    重要通知:BrnShop企业版NOSQL设计(基于Redis)已经开源!源码内置于最新版的BrnShop中,感兴趣的园友可以去下载来看看.官网地址:www.brnshop.com. 好了现在进入今天的 ...

  2. 深入学习jQuery自定义插件

    原文地址:jQuery自定义插件学习 1.定义插件的方法 对象级别的插件扩展,即为jQuery类的实例增加方法, 调用:$(选择器).函数名(参数);      $(‘#id’).myPlugin(o ...

  3. jquery自定义插件结合baiduTemplate.js实现异步刷新(附源码)

    上一篇记录了BaiduTemplate模板引擎使用示例附源码,在此基础上对使用方法进行了封装 自定义插件jajaxrefresh.js 代码如下: //闭包限定命名空间 (function ($) { ...

  4. Phonegap中自定义插件的使用

    在phonegap中需要实现特定相关的功能,可能需要自定义扩展一下功能,那么扩展phonegap组件就成为了可能. 源代码结构图: 本文目的在于讲述怎么扩展一个phonegap组件以及实现. 针对ph ...

  5. jquery自定义插件——以 选项卡插件为例

    一直打算尝试自定义插件,终于付诸实践了,现在把内容发表出来,与大家共勉. 我是根据自己正在用的插件,模仿其源码,实现的自定义插件,完成之后,在网上看相关资料,对自定义插件部分,有了更明确的认识. jq ...

  6. Cordova - 与iOS原生代码交互2(使用Swift开发Cordova的自定义插件)

    在前一篇文章中我介绍了如何通过 js 与原生代码进行交互(Cordova - 与iOS原生代码交互1(通过JS调用Swift方法)),当时是直接对Cordova生成的iOS工程项目进行编辑操作的(添加 ...

  7. jQuery自定义插件

    jQuery自定义插件 jQuery自定义插件按照功能分类,可以分为三类, 1>封装对象方法的插件,(也就是基于某个DOM元素的jQuery对象,局部的) 2>封装全局函数的插件,   ( ...

  8. cordova3.X 运用grunt生成plugin自定义插件骨架

    Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头.麦克风等.Cordova还提供了一组统一的JavaScript类库,以及为这些 ...

  9. cordova /phonegap 自定义插件

    ### cordova /phonegap 自定义插件 在使用cordova 的过程中,虽然官方提供的插件以及其他人开源的插件较多.但有时为了实现某种需求,还是需要自己编写插件. 以前总是会手动的配置 ...

随机推荐

  1. android tv 全屏幕垂直画

    它们的定义view 采纳canvas双缓冲方式,它可以减少呈现时间.提高性能. StaggeredView.java 源码例如以下: package com.xxx.demo; import andr ...

  2. 如何让格斗游戏的横版过关(2) Cocos2d-x 2.0.4

    在第一章<如何使横版格戏>基础上.添加角色运动.碰撞.敌人.AI和音乐音效,原文<How To Make A Side-Scrolling Beat 'Em Up Game Like ...

  3. 【通过做专题研习Android】知识点:SharedPreferences

    Ⅰ. 一个简短的引论 很多时候我们需要开发软件,为用户提供软件参数设置功能,比如,我们经常使用 QQ.用户可以设置自己是否同意加入一个陌生人为好友.对于软件的配置参数的存储,假设window採用ini ...

  4. int有符号和无符号类型内存 -- C

    /* int 有符号 0xffffffff == -1 0xfffffffe == -2 最小 0x80000000 == -21 4748 3648 最大 0x7fffffff == 21 4748 ...

  5. Redis实现高并发分布式序列号

    使用Redis实现高并发分布式序列号生成服务 序列号的构成 为建立良好的数据治理方案,作数据掌握.分析.统计.商业智能等用途,业务数据的编码制定通常都会遵循一定的规则,一般来讲,都会有自己的编码规则和 ...

  6. 采用tcpdump攫Android网络数据包

    1 空灵的原理 tcpdump(需Root用户执行)拦截和显示发送或收到过网络连接到该机器的TCP/IP和其它数据包.简单说就监控手机进出网络数据. 2 方法优劣 2.1长处 1.手机数据包无遗漏 2 ...

  7. c/c++ 基金会(七) 功能覆盖,虚函数,纯虚函数控制

    1.功能覆盖 ClassA , ClassB ,其中ClassB继承ClassA 类的定义如下面的: #ifndef _CLASSA_H #define _CLASSA_H #include < ...

  8. 【百度地图API】如何制作可拖拽的沿道路测距

    原文:[百度地图API]如何制作可拖拽的沿道路测距 摘要: 地图测距,大家都会,不就map.getDistance麼.可是,这只能测任意两点的直线距离,用途不够实际啊.比如,我想测试北京天安门到北京后 ...

  9. angularJS之使用指令封装DOM操作

    angularJS之使用指令封装DOM操作 创建指令 指令也是一种服务,只是这种服务的定义有几个特殊要求: 必须使用模块的directive()方法注册服务 必须以对象工厂/factory()方法定义 ...

  10. Objective-c中的单例

    单例是指静态分配的实例,就是只开辟一块内存,不会重新开辟内存,而 iphone sdk 中全是这种实例,例如[UIApplication sharedApplication] 返回一个指向代表应用程序 ...