一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

WPF企業內訓全程實錄(下)

  摘要

  WPF企業內訓全程實錄由于文章比較長,所以一共拆分成了三篇,上篇WPF企業內訓全程實錄(上)主要講了基礎,中篇WPF企業內訓全程實錄(中)主要講解開發模式、團隊協作及應用框架,起著承上啟下的作用,主要講解開發模式、團隊協作及應用框架。這篇作為該實錄的下篇——終結篇,起著總結的作用,主要講解其他技術的引用、WPF項目及性能優化、部署與更新等議題。

  其實如果大家仔細看目錄,可以發現我安排的順序是首先講解最基本的概念和基礎內容、然后過渡到開發模式及框架、最后結合其他技術和項目實際運用,這也是學習并應用一門技術最好的流程。上篇實際上主要有兩個側重點:一則就是理清脈絡——歷史淵源、概念引入及基本闡述;二則是講解WPFBasic——主要細究WPF的每個知識點,基本涵蓋了WPF的方方面面;如果大家感興趣,可以下載代碼并進行仔細研究,如果有不懂的地方也可以參考我寫的WPF 基礎到企業應用系列,這里受篇幅限制,就不詳細重復論述。中篇主要圍繞WPF開發模式、WPF團隊協作和MVVM框架三個議題進行闡述,側重于為什么要引入MVC/MVP/MVVM模式、從根本上說這些模式是為了解決什么問題、針對不同的開發模式,團隊協作會有哪些具體的改變、了解并使用常用的開發框架以及追根索源探究并實現自己的開發框架。下篇則主要總結前面所講的內容,同時介紹其他技術引入、WPF項目及性能優化與部署與自動更新等概念,其目的在于項目具體應用層次的歸納和總結。

  章節綱要

· 1.摘要

· 2.本文提綱

· 3.簡要介紹

· 4.WPF介紹

· 5.WPF基礎

· 6.WPF工具

· 7.WPF開發模式

· 8.WPF團隊協作

· 9.了解并使用MVVM框架

· 10.自己開發MVVM框架

· 11.其他技術引入

· 12.WPF項目及性能優化

· 13.部署與自動更新

· 14.總結

· 15.詳細技術索引

  十一. 其他技術引入

  通過WPF 基礎到企業應用和前面兩篇文章,我們基本講解了WPF的基礎知識和框架相關細節,可以用以下這幅圖進行簡要概括:

圣殿騎士

  那么下面我們就來探討一下WPF和其他技術之間的銜接問題。我們之前做項目都有一個基本流程,大致包括以下幾個方面:

1. 基礎開發平臺與工具:在開發一個中、大型項目之前,我們一般都會有技術選型的過程,比如選擇Linux + Apache + php + MySQL或者Linux + Apache + Java (WebSphere) + Oracle再或者我們最熟悉的Windows Server 2003/2008 + IIS + C#/ASP.NET + SQL Server,當然這些操作系統、WEB服務器、開發語言和數據庫在一定條件下可以任意搭配,比如你想用FreeBSD操作系統,你想用Ruby或者Python語言,你想用DB2或者其他數據庫等。決定了開發平臺和語言之后,就需要有定制的開發工具,比如Java你可能需要Eclipse或者MyEclipse插件,NET你需要強大的Visual Studio或者MONO環境下使用SharpDevelop,php你可能需要強大的Zend。簡而言之,不管使用什么開發平臺,都需要對應的開發套件與開發工具作為輔助。當然我們今天談的是WPF項目的開發,所以必然我們會首先選擇Windows Server 2003/2008 + IIS + C#/ASP.NET + SQL Server這種搭配,也有人會說可以考慮MONO下的WPF開發和部署,不過很遺憾,MONO下針對WPF并沒有完全進行實現。

2. 基礎框架及資源:這里的基礎框架是指有沒有現成的數據訪問框架、通用權限框架、異常和日志處理框架、IOC框架、AOP框架、簡單的CMS管理框架、Office文檔及PDF交互、報表及打印功能等,因為有了這些以后,開發項目就簡單了許多,我們只需要關注具體的業務處理就行,這樣可以使項目更加高效且穩定的完成。

3. 邏輯架構:邏輯架構往往決定了你如何劃分模塊以及如何來分層,這個要根據項目的具體情況而定,比如項目的大小、項目模塊的多少以及開發方式、開發團隊等。往往在這一階段決定項目的整體架構(三層及多層架構、是否有必要搭建ESB與SOA等)。

4. 物理搭建:之前在做WEB應用的時候,會非常重視物理結構及環境的搭建,因為往往它在項目伸縮性、靈活性以及負載方面起著至關重要的作用,其實在決定邏輯架構的時候也必須要考慮到物理架構,我們這里所說的物理架構就是指整個系統或者多個系統在物理環境上的一個部署情況,比如Web Server集群、App Server集群、文件服務器集群、圖片服務器集群、流媒體服務器集群、全文檢索服務器集群、緩存服務器集群、負載均衡服務器、數據庫主從、讀寫服務器集群等的部署情況。做簡單的WPF管理系統也許并不用考慮這么多,如果要做大型的WPF播放器以及大型的WPF應用,這些都得經過仔細的斟酌才行。

5. 框架的選擇:這個地方是選擇整個應用程序的框架,當然選擇的前提還必須參考前面的邏輯與物理結構。具體框架包括數據底層處理框架、公共基礎框架以及我們前面所提及的諸如MVC/MVP/MVVM模式等。

6. 其他處理:面向對象設計與實現、面向方面思想、權限系統設計、緩存體系設計、異常及日志框架設計、分布式及負載均衡等都是我們需要考慮的重點和要點。最后要特別注意團隊及項目規范、項目整體開發流程、版本與配置管理、項目開發注意細節等問題。

  十二. WPF項目及性能優化

  一,WPF項目

  1)之前的項目架構

  在講WPF項目架構與基礎結構之前,我們先來看一下之前搭建的WEB應用程序:

clip_image002clip_image004  上面的兩幅圖具體概念如下:

01,User Interface即UI層:該層作為數據輸入和展示的界面,是與用戶交互的有效途徑,所以它起著至關重要的作用。往往給人第一印象的就是UI層,在設計的時候也要根據不同的技術或者不同的要求進行斟酌。通常可以把UI分為B/S UI、C/S UI以及WEB服務。在這里就是我們的ASP.NET項目。

02,WebModelCommon:這層作為UI與領域邏輯的中間層,它的充當了橋梁、篩選、過濾和驗證的作用。它主要包括兩個工程,WebHelper主要提供給UI一些常用操作。WebLogic主要對UI與領域邏輯的數據進行轉換、篩選、驗證及過濾操作。

03,Business Logic:Domain Model (Data Model Layer)始終是應用程序的核心,必須投入大量精力,按照面向對象的分析和設計 (OOAD) 最佳做法進行設計同時按照OOP進行開發。

04,FrameWork:主要包括數據訪問框架、通用權限框架、異常和日志處理框架、IOC框架、AOP框架等基礎或常用功能。

05,SOA:這一層不是必須的,根據項目的具體情況進行取舍,如果業務比較復雜且交互項目繁多,那么SOA可以減輕我們的負擔;如果業務比較單一且相對簡單,就可以直接調用或者使用Web Service/Remoting/WCF作為通信框架即可。在實施SOA的過程中,可以自己使用WCF+WF搭建一個小型輕量級的SOA框架,也可以使用諸如Biztalk等軟件。

06,Reference:這里主要包括第三方的框架和組件項目,把這些文件分門別類地集中放在此目錄下。

07,Solution Items:項目的規范、流程、重要文件等。

08,Test:這里主要放置測試需要的一些信息,如測試版本、測試文檔等。

09,Publish:這個文件夾主要放置發布的版本。

  這個框架能解決大多數問題,但仍有不完善之處。

  1)WPF或Silverlight架構

  在MVVM模式中,你需要一個為View量身定制的model,那么這個model實際上就是上圖ViewModel。ViewModel包含所有UI所需要的接口、屬性和命令,這樣只需要通過Binding使他們進行關聯,就可以使二者之間達到松散耦合,所以這樣一來,UI就可以由UI專業人員用 Design和Blend來實現(當然很多效果還是需要用傳統的制圖軟件,所以我們都稱這種想法叫理想狀態),代碼人員也可以專心寫他的邏輯和業務代碼,所以這樣分工和協作變得更輕松、更愉快了。更漂亮的是View完全可以由(Unit/Automatic Test)所取代,所以單元測試也變得相對簡單。這對于我們的開發人員和測試人員無疑是一個很好的解脫,同時也提高了系統的可測性、穩定性和維護性。數據綁定系統同時也提供了標準化的方式傳輸到視圖的錯誤驗證和輸入驗證(但是個人覺得不是很好用,所以我們在實際的項目當中會寫一套自己的驗證框架)。

2010-12-8 22-07-25

  那么根據上面這幅圖,我們具體可以得出如下結論:

1,首先介紹的是UI層,該層作為數據輸入和展示的界面,是與用戶交互的有效途徑,所以它起著至關重要的作用。往往給人第一印象的就是UI層,在設計的時候也要根據不同的技術或者不同的要求進行斟酌。通常可以把UI分為B/S UI、C/S UI以及WEB服務。

2,ViewModel作為用戶界面和業務領域模型的中間層,它往往起著類似于橋梁的作用(UI和領域業務邏輯層之間的橋梁以及耦合的隔離者)。

3,Domain Model (Data Model Layer)始終是應用程序的核心,必須投入大量精力,按照面向對象的分析和設計 (OOAD) 最佳做法進行設計同時按照OOP進行開發。

4,Model、View 和 ViewModel 層之間實施嚴格的分離,也強調了它們之間是一種松散耦合的關系。

5,每一層或者每一個模塊都有自己完整的單元測試,這樣即提高了代碼質量,同時也增強了穩定性和可維護性。

6,不要為了MVVM而MVVM,不要強調UI端不產生一句后臺代碼而把所有代碼都扔進ViewModel,因為有的操作如果不參與邏輯流程,放在UI端處理會更好,這也符合UI和邏輯隔離的最終原則。

7,數據底層操作層可以隨意的搭配,既可以使用傳統的方式也可以用ORM的方式,這個根據團隊或項目的具體情況作抉擇。如傳統的存儲過程或者腳本、借助于企業庫、IBATIS.NET、Nhibernate,Active Record,Entity framework,Linq To Sql,entity framework或者Custom ORM等。

8,Database做為最底層,它對應用程序起著最為關鍵的作用,項目沒有數據就等于失去了最本質的東西,除非這個項目和數據沒有太多關聯,所以必須投入大量的時間和精力在這一層,這也是數據庫庫團隊存在的必要。最典型的問題包括數據庫優化、數據庫拆分、分離、同步、數據挖掘以及數據庫的備份與復原等。

  前段時間本來要重構一個項目,但由于諸多原因,這個項目沒有能夠在整體架構上進行調整,這里也把項目整體結構圖貼出來,供大家參考:

Arc1  上面的兩幅圖具體概念如下:

01,UI:該層作為數據輸入和展示的界面,是與用戶交互的有效途徑,所以它起著至關重要的作用。往往給人第一印象的就是UI層,在設計的時候也要根據不同的技術或者不同的要求進行斟酌。通常可以把UI分為B/S UI、C/S UI以及WEB服務。在這里就是我們的WPF項目。

02,ViewModel作為用戶界面和業務領域模型的中間層,它往往起著類似于橋梁的作用(UI和領域業務邏輯層之間的橋梁以及耦合的隔離者),這里沒有把它從UI里面獨立出來,所以它放在UI或者獨立出來均可。

03,LogicBusiness:Domain Model (Data Model Layer)始終是應用程序的核心,必須投入大量精力,按照面向對象的分析和設計 (OOAD) 最佳做法進行設計同時按照OOP進行開發。

04,Common:主要包括數據訪問框架、通用權限框架、異常和日志處理框架、IOC框架、AOP框架等基礎或常用功能。

05,SOA Service:這一層不是必須的,根據項目的具體情況進行取舍,如果業務比較復雜且繁多,那么SOA可以減輕我們的負擔;如果業務比較單一且相對簡單,就可以直接調用或者使用Web Service/Remoting/WCF作為通信框架即可。在實施SOA的過程中,可以自己使用WCF+WF搭建一個小型輕量級的SOA框架,也可以使用諸如Biztalk等軟件。

06,DataAccess:數據庫訪問組件。

07,AddedDll:這里主要包括第三方的框架和組件項目,把這些文件分門別類地集中放在此目錄下。

08,UnitTest:對每層及每個模塊進行單元測試。

  從上面WEB與WPF兩個項目中可以看到具體的差別與聯系:聯系在于公共的東西都是不會變的;差別在于WEB與WPF都有各自的特點,所以在處理上也有一些細微的區別!

  二,性能優化

  關于性能優化,在任何項目都會有所涉及,使用WPF的項目也不例外(或者更甚)。那么針對WPF項目,我們如何來做好性能優化呢?其實這個問題比較大,因為往往某個細節的操作會影響到整個WPF應用程序的性能,所以在做項目的時候一般都會針對這些性能優化操作列一個表(詳細說明性能優化點及注意事項)。WPF性能優化就像之前做WEB優化一樣,都有一些“銀彈”可供參考,WEB項目有Yahoo團隊實踐分享——網站性能優化的條黃金守則和業界的一些經驗;WPF作為出道不久的技術,主要參考微軟提供的性能優化注意事項以及自己的實踐經驗。本來是想羅列一些性能優化點,無奈由于時間倉促且怕羅列不全面或不正確,所以把它留在以后心情好的時候再續,不然就會起到不能幫助讀者反而誤導讀者的效果。

  十三. 部署與自動更新

  一個優良的軟件都會有自己完整的部署與自動更新流程,C/S應用程序尤其如此,所以如何解決客戶端的部署與自動升級問題便是一個非常重要的問題。大家都知道ClickOnce 無疑是微軟對Client/Server模式部署的最佳解決方案,但正是因為它的功能特別強大而且又要使用相當簡單,所以在產品的封裝上就特別嚴實,基本上就暴露了一些簡單的操作接口,這樣用戶就無法做定制化的操作,所以我們下面主要探討不使用ClickOnce的操作流程。

  一,打包操作

  關于打包操作,現在市面上有很多的打包工具與代碼,但最為常用的要數Installshield和微軟自帶的打包工具軟件,兩者在這方面都有不俗的表現,前者強調打包的定制化以及多樣性,后者強調易操作及快速性。如果你想要更多漂亮及定制化的操作,可以選擇Installshield+腳本的方式;如果你想做一般的效果,那么微軟自帶的打包工具軟件就特別適合;當然這也不是絕對的定律,只是一般情況下的選擇,下面我們就主要來講解微軟自帶的打包工具軟件。

  1) 創建安裝和部署項目:

  1,右鍵點擊當前解決方案—>Add—>New Project,在彈出的窗口中選擇Other Project Types—>Setup and Deployment—>Setup Project;然后輸入項目的名字,點擊“OK”按鈕。新添加的安裝和部署項目就會出現在解決方案列表中。

  2) 添加項目輸出及制作安裝界面:

  1,首先把你要安裝的項目加進來,也就是加入到應用程序文件夾,由于VS SetUp設置比較簡單,你只需要按照操作步驟一步一步設置即可。在完成應用程序文件夾之后設置開始菜單和用戶桌面的快捷方式。

  2,右鍵點擊安裝項目,選擇View—>User Interface可以看到VS SetUp為我們提供的一些默認安裝界面,當然你也可以創建、修改或者移除這些窗口,總之你可以定制化你的安裝步驟和頁面。

  3) 注冊表問題:

  和前面的操作類似,對于注冊表的設置也比較簡單,右鍵點擊安裝項目,選擇View->Registry即可創建、修改及移除注冊表鍵值。

  4) 創建組件注冊項目:

  1,右擊當前解決方案—>Add—>New Project,在彈出的窗口中選擇 Visual C#—>Class Library;然后在下方文本框中輸入Name,點擊“OK”按鈕。新添加的項目會出現在解決方案列表中。

  2,右鍵點擊該項目—>Add—>New Item,在彈出的窗口中選擇Installer Class;在下方文本框中輸入名字,點擊“Add”按鈕添加文件并關閉窗口。

  3,選中剛添加的文件,按F7或者View Code轉到代碼頁,在代碼頁面添加以下方法:

namespace RegsvrDll
{
[RunInstaller(true)]
public partial class InstallerReg : Installer
{
public InstallerReg()
{
InitializeComponent();
}

public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
}

protected override void OnAfterInstall(IDictionary savedState)
{
base.OnAfterInstall(savedState);

string LogicDir = Context.Parameters["LogicDir"];

// Close the writer and underlying file.
// 注冊CDO組件
// /s 關閉注冊成功的提示窗口顯示,/c退出cmd窗口
System.Diagnostics.Process.Start("cmd", @"/c regsvr32 " + @LogicDir + @"ComUtilities.dll /s");

string path = @LogicDir + @"App.exe";
using (RegistryKey regWrite = Registry.LocalMachine.CreateSubKey("SOFTWARE//Microsoft//Windows//CurrentVersion//App Paths"))
{
regWrite.SetValue("App.exe", path);
regWrite.Close();
}
}

protected override void OnBeforeInstall(IDictionary savedState)
{
base.OnBeforeInstall(savedState);
}
}
}

  注意:需要加入using System.Configuration.Install;

  5) 在安裝和部署項目中添加要安裝的項目和文件:

  1, 添加項目:右擊項目—>View—>File System,在出現的界面中,右擊左列的Application Folder—>Add—>Project Output,在彈出的窗口中選擇相應的Project,然后點擊“OK”按鈕。多個項目重復多次。在這里我們假設我們開發的項目為 MainProject,注冊組件的項目名稱為RegDll,那么我在彈出的窗口中先選擇項目MainProject,點擊“OK”后,我在重復添加項目 RegDll。

  2,添加文件:右擊項目—>View—>File System,在出現的界面中,右擊左列的Application Folder—>Add—>File,在彈出的窗口中選擇C:/WINDOWS/system32 /misexec.exe;

  3,創 建快捷方式:在右列中選擇Primary output from MainProject(Active),右擊 選擇Create Shortcut to Primary output from MainProject(Active),你可以按F2給新添加的快捷方式更名。右擊msiexec.exe 選擇 Create Shortcut to misexec.exe,你可以按F2將剛生成的快捷方式更名為“卸載”;

  4,創建程序組:右擊左列的User’s Programs Menu選擇 Add—>Fold,你可以將新創建的文件夾更名,當軟件安裝完畢后它將出現在程序組中,然后將上一步創建的兩個快捷方式拖到新創建的文件夾中。

  5,實現“卸載”的功能:選中安裝和部署項目,按F4,復制ProductCode的內容,然后選中“卸載”快捷方式,按F4,將Arguments 的內容更改為:/x 剛復制的ProductCode的內容。

  6) 安裝時注冊組件問題:

  右擊安裝和部署項目—>View—>Custom Actions,在出現的界面中右擊左列的Install—>Add Custom Action,選擇Application Folder中的Primary output from RegDll(Active)。

clip_image002  修改“主輸出來自RegDll (活動)”的CustomActionData屬性為 /LogicDir="[TARGETDIR]/"

clip_image004  7) 自動檢測當前系統中MDAC、.NET Framework版本、Windows Installer3.1是否滿足版本要求,如果不滿足則安裝:

  右擊安裝和部署項目選擇屬性,在彈出的窗口中點擊按鈕 “Prerequisites”。選中MDAC2.8、.NET Framework2.0、Windows Installer3.1;然后選中Download prerequisites from the same location as my application 單選按鈕,點擊“OK”,再點擊“OK”。

  8) 重新編譯項目生成項目安裝包,這個時候就可以把安裝包Host在網上供用戶下載。

  二,自動更新

  1),簡要介紹

  眾所周知,對于一般的軟件開發,在開始的時候都會有一個技術選型的階段,最大的選型就是首先要確定是選擇Client/Server模式還是 Browser/Server模式。綜合而論:兩者各有優劣,在很多方面都不能被對方互相取代,如在適用InterNET、維護工作量等方面,B/S比C /S要強很多;但在運行速度、數據安全、人機交互等方面,B/S就遠不如C/S那么強大。所以綜上所述,凡是C/S的強項,便是B/S的弱項,反之亦然。由于今天討論的是自動更新組件,所以接下來我們就往這方面細講,既然C/S模式在運行速度、數據安全、人機交互有這么多的優點,尤其是客戶端技術日益發展的今天,如何解決客戶端的部署與自動升級問題便是一個非常重要的問題。

  2),ClickOnce與自定義之間的權衡

  在前面的摘要中我們簡單介紹了自動更新功能的重要性,在這一小節里我們來談一下為什么不使用微軟給我們提供的自動更新組件ClickOnce,大家都知道ClickOnce給我們提供了很多功能:簡單說來,ClickOnce 應用程序就是任何使用 ClickOnce 技術發布的 Windows 窗體或控制臺應用程序。可以采用三種不同的方法發布 ClickOnce 應用程序:從網頁發布、從網絡文件共享發布或是從媒體(如 CD-ROM)發布。ClickOnce 應用程序既可以安裝在最終用戶的計算機上并在本地運行(即使當計算機脫機時也可以運行),也可以僅以聯機模式運行,而不在最終用戶的計算機上永久安裝任何內容。ClickOnce 應用程序可以自行更新;這些應用程序可以在較新版本變為可用時檢查較新版本,并自動替換所有更新的文件。開發人員可以指定更新行為;網絡管理員也可以控制更新策略,如將更新標記為強制性的。最終用戶或管理員還可以對更新進行回滾,使應用程序恢復到早期的版本。

  從上面大家可以看出ClickOnce 無疑是微軟對Client/Server模式部署的最佳解決方案,但正是因為它的功能特別強大而且又要使用相當簡單,所以在產品的封裝上就特別嚴實,基本上就暴露了一些簡單的操作接口,這樣就無形把一些定制化的操作拒之于門外,比如:

  • 用戶不能自己指定安裝路徑。
  • 對自動更新流程不能做定制化的操作。
  • 對自動更新的UI不能定制化的設計。

  正因為這幾個原因,所以很多企業都會做一些定制化的組件來實現自動更新的功能,基于此,我們這里也實現了一個非常簡單的自動更新組件.

  3),自定義更新操作流程

  其實自動更新的原理很簡單,分析起來無非就是簡單的幾步操作,當然實現方式也是大同小異,這里我們就選一種較簡單的方式:

  1.啟動主程序,主程序里面調用升級程序,升級程序連接到IIS或者FTP。

  2.升級程序獲取服務器端XML配置文件中新版本程序的更新日期或版本號或文件大小。

  3.升級程序獲取原有客戶端應用程序的最近一次更新日期或版本號或文件大小,然后兩者進行比較;如果新版本日期>原有程序的最新日期,則提示用戶是否升級;或如果新版本版本號>原有程序的版本號,則提示用戶是否升級;再或如果新版本文件大小>原有程序的文件大小,則提示用戶是否升級。本文主要采用一般的做法,就是通過版本號來進行對比。

  4.如果用戶選擇升級,則獲取下載文件列表;

  5.在本地建立與遠程IIS或者FTP相應的臨時目錄,然后下載到這個臨時目錄文件下;

  6.刪除舊的主程序,拷貝臨時文件夾中的文件到相應的位置;

  8.結束升級流程并重新啟動主程序。  

  4),自動更新效果圖

  當我們運行主程序(WinForm或者WPF),如果服務器上有最新的版本,就會彈出如下頁面進行提示并讓用戶選擇是否更新。

2010-10-13  當用戶不需要更新時,可以選擇Skip按鈕跳過并繼續主程序流程,反之則進入如下頁面。

2010-10-13

  在下載的過程中,用戶可以選擇Cancel停止下載并重新回到主流程。

  十四,總結

  上篇WPF企業內訓全程實錄(上)主要講解歷史淵源、概念引入、基本闡述以及WPF的每個知識點。中篇WPF企業內訓全程實錄(中)主要主要圍繞WPF開發模式、WPF團隊協作和MVVM框架三個議題進行闡述。下篇WPF企業內訓全程實錄(下)將著重強調結合其他技術共同打造WPF項目、相關性能優化、以及部署與更新問題。另外如果有不懂的地方也可以參考之前寫的WPF 基礎到企業應用系列,最后聲明一下,由于圣殿騎士才識淺薄,所以以上觀點只是個人的看法與心得,遺漏和錯誤之處也敬請海涵。懷著技術分享與交流的態度分享出來,希望各位多多指教!

NET技術WPF企業內訓全程實錄(下),轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 欧美成人网在线综合视频 | 好吊逼 | 亚洲精品国产福利在线观看 | 国产成人一区二区三区在线播放 | 亚洲第一区精品日韩在线播放 | 亚洲黄色免费 | 中国一级特黄特色真人毛片 | 男女牲交一级毛片 | 黄 色 成 年人在线 黄 色 免 费 网站在线观看 | 久久影院中文字幕 | 欧美色视频网站 | 91精品视频在线看 | 亚洲视频毛片 | 香蕉eeww99国产在线观看 | 亚洲综合视频一区 | 国产精品九九久久一区hh | 91在线品视觉盛宴免费 | 久久中文网中文字幕 | 性开放网站 | 69国产成人综合久久精品 | 一区二区三区四区在线观看视频 | 五月天婷婷色综合 | 综合区小说区图片区在线一区 | 黄视频在线观看免费视频 | 免费观看精品视频999 | 中文字幕1区2区 | 多色视频 | 精品久久久久久久一区二区伦理 | 精品欧美一区二区三区在线观看 | 久久亚洲国产成人精品性色 | 思思久久这里只精品99re66 | 在线欧美色 | 亚洲一区二区三区免费看 | 国产福利2021最新在线观看 | 2021国产精品成人免费视频 | 亚洲综合国产 | 中文字幕日韩精品亚洲七区 | 草草草视频 | 四虎4hu永久免费视频大全 | 国产精品麻豆久久99 | 欧美xxxx色视频在线观看免费 |