<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      在WPF中使用依賴注入的方式創建視圖

      在WPF中使用依賴注入的方式創建視圖

      0x00 問題的產生

      互聯網時代桌面開發真是越來越少了,很多應用都轉到了瀏覽器端和移動智能終端,相應的軟件開發上的新技術應用到桌面開發的文章也很少。我之前主要做WPF,今年開始學習Web應用開發,于是就接觸到了.NET Core,其中的很多概念很值得在桌面開發中借鑒。例如在.NET Core MVC中,Controller的依賴是通過構造函數注入的,注入的過程由框架實現,我們在寫Controller時只要在構造函數參數中羅列出要依賴的服務即可,進一步的,把服務抽象為接口,那么核心的業務邏輯就徹底解耦出來了,依賴的服務可以是任意的實現方式(當然前提是要滿足需求)。WPF一般都是用MVVM模式開發,那么是不是可以讓ViewModel對其它服務的依賴也通過構造函數自動注入,而不是每次都要new出一個ViewModel呢?這篇文章主要就討論這個問題,并嘗試寫了個View和ViewModel的容器來實現。

      0x01 最初的設計

      .NET Core MVC中之所以能做到Controller的依賴自動注入,主要就是因為Controller實例是由MVC框架創建的。我們要想讓ViewModel中的依賴自動注入,那么這個ViewModel肯定需要自動創建。考慮到View與ViewModel之間的對應也算是一種依賴關系,那么就可以把View和ViewModel之間的這種對應關系以及其它服務的依賴關系都放到容器里,當需要View的時候,根據View的類型從容器中找到對應的ViewModel,然后根據ViewModel的依賴,從容器中獲取服務,然后把View的DataContext設置為ViewModel的實例,最終返回View,那么就實現了ViewModel的自動依賴注入了。

      0x02 更進一步的設計

      按照上面那個方案我寫了一個簡易的依賴注入容器,證明是可以用的。不過要想真正在相對嚴肅一點的環境中開發,對依賴注入容器的要求就不是那么簡單了。我需要花時間去開發一個嚴謹一點的依賴注入容器,這不僅需要時間,關鍵水平有限,目前市面上已經存在了很多優秀的依賴注入容器,我沒必要造輪子(為了學習或更深入理解原理而去造輪子的行為不在此列),但常見的依賴注入容器在配置服務時(例如綁定A和B)一般都限制B對A有繼承關系,所以現有的依賴注入容器無法配置View和ViewModel的依賴。因此考慮把View和ViewModel的依賴關系單獨存到一個容器中,服務的依賴放到第三方容器,為了能夠適配第三方容器,可以提供一個接口,通過接口對第三方容器進行簡易的包裝即可使用,這樣就可以任意選擇自己喜歡的強大的第三方依賴注入容器了。

       

      0x03 部分代碼和示例

      在開始看代碼之前,先說一下存儲View和ViewModel關系的容器AvalonContainer(后面簡稱View容器),使用這個容器的Wire方法可以配置View和ViewModel之間的對應關系,GetView方法可以獲取View,同時給View的DataContext配置好了指定的ViewModel,并且ViewModel注入了依賴。要創建一個AvalonContainer需要在構造函數中傳入IContainer對象,這個接口用于對第三方依賴注入容器實現包裝,以便用于AvalonContainer,第三方依賴注入容器主要作用是從中獲取ViewModel的依賴,以及往容器中添加ViewModel(如果需要的話)。

      我自己寫的依賴注入容器太簡易了,當時只是用來測試,實際應用中應該都會使用第三方容器,所以示例直接用的第三方容器Ninject。

      核心的步驟是創建一個Ninject容器,用Ninject容器綁定依賴,然后用Ninject容器創建View容器,配置View和ViewModel依賴。這樣需要時就可以直接從View容器創建View,獲得的View的DataContext已經設置為ViewModel實例并注入了ViewModel的依賴。

       

      ViewModel中一般在構造函數參數中注入依賴。對于不同的依賴注入容器,也可以通過給屬性配置相應的Attribute的方式聲明依賴注入,不過這種方式對ViewModel的侵入太強了,而且不同的依賴注入容器往往提供不同的Attribute,更換時會比較麻煩,還是構造函數注入比較好,更換依賴注入容器不會產生影響。下面截圖是TestOneView對應的ViewModel,在構造函數中注入了倉儲和日志的依賴,感覺就像.NET Core MVC中的Controller。

       

      當需要OneTestView窗口時,可以如下圖所示創建并顯示。

       

      為了能夠適配任意的第三方依賴注入容器,提供了IContainer接口,在使用第三方依賴注入容器時需要通過這個接口適配一下,這種感覺就像電腦輸出接口可以有HDIM、DVI、VGA,顯示器輸入接口只有VGA,需要轉接頭來轉換一下。

       

      其中Get方法用于從第三方容器中獲取ViewModel并注入依賴,Wire<T>()方法用于往第三方容器中添加ViewModel。其中token是針對自帶依賴注入容器的,完全可以忽略不管。

      其實對于Ninject來說是完全不需要Wire這個方法的,因為即使這個類型沒有添加到容器中,在Get時Ninject也會創建對象并注入其中的依賴,所以對Ninject的包裝如下,Wire方法直接忽略即可。但不能保證所有的第三方依賴注入容器都有這個特性,所以還是保留了這個接口。

      這樣依賴注入容器和View容器通過IContainer解耦,更換依賴注入容器不會影響到業務邏輯。

      如果因為某些特殊原因需要給同一個View綁定不同的ViewModel,可以在Wire時提供token參數,在GetView時使用同樣的token參數即可獲取相應的ViewModel。

      0x04 寫在最后

      View容器寫好后自己用了下感覺還可以,但因為ViewModel是動態添加的,所以無法在設計時看到數據,這確實是個問題。另外要說下起名字真的很難,之前大多數都是出于學習/練習的目的,就直接加個Ayx前綴,不過這次想發布一下,考慮到WPF開發代號是Avalon,就把它叫了AvalonDI。最后關于配置View和ViewModel依賴的方法,在NInject中是用的Bind,這個感覺比較好理解。不過我覺得把接口和接口的實現綁定到一起,用裝配/組裝更貼切。想像一下,電視提供了標準輸入接口,我們可以接錄像機、游戲機、電腦。同樣游戲機提供了接口,可以插不同的卡帶、不同的手柄,當把他們連在一起時,用Wire感覺更合適一點。

      Github:https://github.com/durow/AvalonDI

      nuget:Install-Package Ayx.AvalonDI

      samples里面提供了一個WpfSample,用的自帶的依賴注入容器,一個NinjectSample,用的Ninject作為依賴注入容器。

       


      更多內容歡迎訪問我的博客:http://www.durow.vip

      posted @ 2016-08-25 13:56  durow  閱讀(5390)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 色 亚洲 日韩 国产 综合| 日韩一区二区三区无码a片| 秋霞人妻无码中文字幕| 久久亚洲精品中文字幕波多野结衣 | 亚洲高清国产拍精品熟女| 日韩中文字幕人妻一区| 国产福利精品一区二区| 色播久久人人爽人人爽人人片av | 少妇粗大进出白浆嘿嘿视频| 国产成人精品三级麻豆| 人妻精品久久无码区| 2019亚洲午夜无码天堂| 国产午夜福利精品视频| 精品无码一区二区三区电影| 欧美和黑人xxxx猛交视频| 亚洲无av在线中文字幕| 99久久国产综合精品色| 亚洲乱码中文字幕小综合| 2021亚洲国产精品无码| 国产精品69人妻我爱绿帽子 | 亚洲乱码中文字幕久久孕妇黑人| 日本道不卡一二三区视频| 亚洲大尺度无码专区尤物| 凹凸国产熟女精品视频| 日本不卡一区二区三区在线| 97成人碰碰久久人人超级碰oo| 人妻丰满熟妇av无码区不卡| 亚洲av伦理一区二区| 亚洲AV成人无码精品电影在线| 日韩av综合免费在线| 开心五月婷婷综合网站| 91无码人妻精品一区| 午夜高清福利在线观看| 国产精品亚洲av三区色| 亚洲中文字幕日产无码成人片| 一区二区三区放荡人妻| 自拍偷拍另类三级三色四色| 免费人成再在线观看视频| 免费观看的av在线播放| 蜜芽久久人人超碰爱香蕉| 天堂а√8在线最新版在线|