WCF開發框架之插件化應用模式升級


自從在《Winform開發框架之插件化應用框架實現》一文中,介紹並總結了Winform開發框架插件化應用框架的實現后,贏得了很多同行和客戶的支持,於是把我的WCF開發框架、混合式開發框架都進行了升級,把它們都提升到插件化應用的高度上。本文主要介紹WCF開發框架,如何實現插件化的應用。從我隨筆《基於我的Winform開發框架擴展而成的WCF開發框架》介紹可以看到,一般的WCF應用,是在客戶端添加服務應用的方式,然后使用自動生成的WCF服務客戶端代理來訪問相應的服務的,這種方式比較方便快捷,但是也增加了客戶端界面和WCF服務的耦合性,架構布局如下所示。

 

為了更好有效利用松耦合的特點,以及插件化應用的特點,我對整個WCF開發框架進行了一個大的調整,以便更好整合及利用好的特點。如下圖所示,插件化應用框架的啟動模塊,它除了依賴基礎服務模塊中(包括權限管理模塊和字典模塊),其他的模塊如WCF服務模塊、主業務插件模塊A(主業務模塊B)等都是通過配置方式實現對接的,他們之間沒有明顯的耦合關系。

   

整個項目工程的布局如下所示,其中BaseUIDx為基礎界面類,方便各個插件模塊重用而分離出來的。其他模塊的功能如上圖所示。

主業務插件模塊是指各種各種的插件化業務模塊,他們本身包含有界面部分、WCF服務調用、以及業務邏輯等內容。

 

為了更好分離WCF服務的部署和WCF服務邏輯(這也是最佳實踐),實現更好的代碼控制和重用,WCF項目的架構關系設置成如下所示。

其中WHC.WareHouseMis.WCFLibrary是整個WCF服務的業務邏輯模塊,它囊括了統一調用接口Facade層、WCF業務實現WCFLibrary層、BLL業務層、數據接口IDAL層、數據訪問實現DAL層、實體類Entity層。

當然,以上的關系不需要手工來做這些繁瑣的代碼對應關系,只需要設計好表后,使用代碼生成工具Database2Sharp一鍵生成就可以了,其中很多項目關系已經生成好了,增量開發的時候,重新引用下文件關系即可。

而且整個WCF不在使用在界面層直接引用WCF服務的方式,而采用了自定義的客戶端信道(允許從自定義的配置文件中加載)方式實現對應WCF服務客戶端代理類的創建。

以WCF的調用類ItemDetailCaller為例,使用代碼生成工具生成的代碼,它已經繼承了某個接口IItemDetailService服務基類了,並給它指定了具體的WCF服務節點即可,如下代碼所示。

    public class ItemDetailCaller : BaseService<ItemDetailInfo>, IItemDetailService
    {
        public ItemDetailCaller()  : base()
        {
            this.endpointConfigurationName = EndPointConfig.ItemDetailService;
        }

實現接口IItemDetailService的函數很有規律,使用下面類似的代碼即可。

        public List<ItemDetailInfo> FindByBigType(string bigType)
        {
            List<ItemDetailInfo> result = new List<ItemDetailInfo>();

            IItemDetailService service = CreateSubClient();
            ICommunicationObject comm = service as ICommunicationObject;
            comm.Using(client =>
            {
                result = service.FindByBigType(bigType);
            });

            return result;
        }

這樣進行了包裝后,我們使用WCF服務就好像之前的Winform開發框架使用BLLFactory的方式一樣了,WCF服務調用示例代碼如下所示。

                    bool succeed = CallerFactory<IItemDetailService>.Instance.Update(info, info.ID.ToString());
                    if (succeed)
                    {
                        try
                        {
                            StockInfo stockInfo = CallerFactory<IStockService>.Instance.FindByItemNo2(this.txtItemNo.Text, this.txtBelongWareHouse.Tag.ToString());
                            if (stockInfo != null)
                            {
                                stockInfo.WareHouse = txtBelongWareHouse.Text;
                                CallerFactory<IStockService>.Instance.Update(stockInfo, stockInfo.ID.ToString());
                            }

                            //不管是更新還是新增,如果對應的備件編碼在庫房沒有初始化,初始化之
                            bool isInit = CallerFactory<IStockService>.Instance.CheckIsInitedWareHouse(this.txtBelongWareHouse.Text, this.txtItemNo.Text);
                            if (!isInit)
                            {
                                CallerFactory<IStockService>.Instance.InitStockQuantity(info, 0, this.txtBelongWareHouse.Text);
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageDxUtil.ShowTips(string.Format("初始化庫存為0失敗:", ex.Message));
                        }

                        return true;
                    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM