程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#大型電商項目優化(三)——擴展性與支付

C#大型電商項目優化(三)——擴展性與支付

編輯:C#入門知識

C#大型電商項目優化(三)——擴展性與支付


開個玩笑,下面進入正題,之前系統的支付部分只需要支持支付寶和財付通,且支付代碼是寫在一個頁面文件裡的,也就是說,這個頁面文件包含了支付寶和財付通的支付請求、支付同步回調和異步回調。且不說代碼混亂可讀性差,其可擴展性也實在不敢恭維。其功能像這樣:       可將來需要支持其他支付平台呢,類似於快錢等支付平台,我們預期的是這樣甚至更多:       難道這些將來亟待擴展的功能還一一寫在頁面裡嗎?當然不能。在擴展支付功能之前,必須對原來的代碼做重構。   重構前我們需要對目前的支付做分析:支付需要哪些方法?哪些是公共的?經過總結,我們發現支付寶和財付通支付最主要的就是這三個方法:   1.提交支付請求   2.支付同步回調(重定向)   3.異步回調   當然,有些支付平台可能有不同,比如支付寶的退款接口,是沒有同步回調的。如果有更多的場景,我們可以擴展接口。   我們定義了這樣一個接口類:     public interface IPayment     {         /// <summary>         /// 支付         /// </summary>         void GoToPay(PaymentParameter parameters);         /// <summary>         /// 支付同步回調         /// </summary>         void PayReturn();         /// <summary>         /// 支付異步回調         /// </summary>         void PayNotify();     }   接下來構建基礎類,類名為PaymentBase,讓它繼承我們的接口類。基礎類中,我們定義各種平台支付所需要調用的公共方法,聲明支付所必需的對象,代碼如下:             protected string _orderId = string.Empty;         protected string _orderNum = string.Empty;         protected MerchantPayInfo _merchantPayInfo = null;         protected string _orderPrice;         protected string _productName = string.Empty;         protected string _orderType = string.Empty;         protected HttpResponse Response;         protected HttpRequest Request;         log4net.ILog log = log4net.LogManager.GetLogger("myDemo");           /// <summary>         /// 去支付         /// </summary>         public abstract void GoToPay(PaymentParameter parameters);         /// <summary>         /// 支付同步回調         /// </summary>         public abstract void PayReturn();         /// <summary>         /// 支付異步回調         /// </summary>         public abstract void PayNotify();         /// <summary>         /// 支付前的初始化         /// </summary>         /// <param name="parameters"></param>         protected void PaymentInitial(PaymentParameter parameters)         {...}   在PaymentInitial中為部分對象做初始化,這裡不做贅述。   准備工作就緒,接下來我們開始調用支付接口,首先是支付寶,我們定義一個類,可以叫作AliPayment,在其構造函數中為支付商家賬號對象賦值,然後開始為我們的三個最重要的方法編寫實現:                  public override void GoToPay(PaymentParameter parameters)         {             base.PaymentInitial(parameters);               ......var submit = new Submit(_merchantPayInfo.Akey);             //建立請求             string sHtmlText = submit.BuildRequest(sParaTemp, "get", "確認");             Response.ContentType = "text/html";             Response.Write(sHtmlText);             Response.End();         }         /// <summary>         /// 支付後同步調用         /// </summary>         public override void PayReturn()         {             ......         }         /// <summary>         /// 支付後異步調用         /// </summary>         public override void PayNotify()         {        ......           }   這三個方法的實現在支付寶接口文檔的demo裡有提供,大家可以參考。考慮到篇幅問題,這部分代碼就不貼出來了。   支付類型和方法都定義且實現完成,接下來就是調用了。考慮到可擴展性,我們希望調用部分的代碼在以後擴展時,都不需要修改,這裡我們可以通過配置實現。類似於我們所熟知的“控制反轉,依賴注入”:調用者不構造被調用者的實例,由容器構造被調用者的實例,再注入到調用者。當前的系統框架並沒有引入控制反轉策略,沒關系,框架裡沒有,我們可以自己寫個類似的。   這裡可以通過反射來構造支付類型的實例,創建類型實例的代碼如下:        /// <summary>         /// 創建對象實例         /// </summary>         /// <typeparam name="T">要創建對象的類型</typeparam>         /// <param name="assemblyName">類型所在程序集名稱</param>         /// <param name="nameSpace">類型所在命名空間</param>         /// <param name="className">類型名</param>         /// <returns></returns>         public static T CreateInstance<T>(string assemblyName, string nameSpace, string className)         {             try             {                 string fullName = nameSpace + "." + className;//命名空間.類型名                 //此為第一種寫法                 object ect = Assembly.Load(assemblyName).CreateInstance(fullName);//加載程序集,創建程序集裡面的 命名空間.類型名 實例                 return (T)ect;//類型轉換並返回                 //下面是第二種寫法                 //string path = fullName + "," + assemblyName;//命名空間.類型名,程序集                 //Type o = Type.GetType(path);//加載類型                 //object obj = Activator.CreateInstance(o, true);//根據類型創建實例                 //return (T)obj;//類型轉換並返回             }             catch             {                 //發生異常,返回類型的默認值                 return default(T);             }         }   這裡需要注意:我們所創建的支付類型必須要自己寫構造函數,否則無法通過此方法創建實例。   在輔助方案都完成之後,實際調用的地方代碼量是非常少的,我們看調用的代碼:                 string className = ConfigurationManager.AppSettings[payCode];                     payment = ReflectionHelper.CreateInstance<IPayment>("MyTestAssembly", "MyTestAssembly.Payment", className);                       PaymentParameter parameter = new PaymentParameter();                     parameter.LocalPath = "/Pay/Payment";                     parameter.OrderId = OrderId;                     parameter.OrderType = OrderType;                     payment.GoToPay(parameter);   配置的內容如下:   <!--支付寶支付方案類型配置,用於反射 Leon-->     <add key="0" value="AliPayment" />          <!--財付通支付方案類型配置,用於反射 Leon-->     <add key="1" value="TecentPayment" />

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved