1. 程式人生 > 其它 >WPF 框架開發 加入 InternalsVisibleToAttribute 特性讓其他程式集可以訪問 internal 許可權成員

WPF 框架開發 加入 InternalsVisibleToAttribute 特性讓其他程式集可以訪問 internal 許可權成員

技術標籤:WPF原始碼WPFc#WPFdotnetC#

在 WPF 框架開發中,其實很少有開發者有足夠的勇氣去更改現有的框架邏輯,因為 WPF 的功能十分龐大,很難測試全。更多的開發都是加功能以及開放已有功能。整個 WPF 框架的大體設計是十分好的,可以在框架裡面遵循對修改關閉的原則,定製化更多的是做注入,呼叫 internal 許可權成員 本文告訴大家如何給 WPF 框架加入 InternalsVisibleToAttribute 特性讓其他程式集可以訪問 internal 許可權成員

如果我不新加入一個程式集,而是在原有的程式集開發,加上新功能,是否可行?肯定是可以的,但是這樣做的開發效率不夠好。因為我為了在 VisualStudio 上構建 WPF 框架,我加入了一些構建黑科技,此時的 WPF 框架丟失了增量構建的功能。而一次 WPF 框架的構建需要 20 分鐘

因為我在 WPF 框架的定製開發中,更多的是訪問 internal 許可權成員新增新的類等,我幾乎沒有想去更改現有的邏輯。所以最簡方法就是新增一個程式集,讓整個 WPF 框架的 internal 許可權成員可以被我新增的程式集訪問。實現的方法是 InternalsVisibleToAttribute 特性

因為 WPF 是一個帶簽名的框架,大家都知道,一個帶簽名的程式集如果設定 InternalsVisibleToAttribute 特性,要求被設定的程式集也是被簽名的,詳細請看 dotnet 強簽名下使用 InternalsVisibleToAttribute 給程式集加上友元

接下來我需要新建一個程式集,我這裡叫 dotnetCampus.WPF 程式集,在這個程式集裡面自己新建簽名,然後配置到 WPF 框架各個專案

做法就是先通過 dotnet 強簽名下使用 InternalsVisibleToAttribute 給程式集加上友元 拿到簽名,然後拼接 InternalsVisibleToAttribute 的內容

[assembly:InternalsVisibleTo("dotnetCampus.WPF, PublicKey=0024000004800000940000000602000000240000525341310004000001000100256f5cb79140dbc25623807d6823ca4b5b602209eaaf71f064e5926a7039c24351c1e2ad3130e194631307ed36a76ad4b832e237a467fefbd693428c7ecc5d4cc26796f6f8b705311948e00f2be5fa2db52ddff50a5b3eb0acc715b45618c1a92532ae2326529fb9e0f58a44abf31e9b5701994464186d3b9f52169b6e0f80b9")]

將上面程式碼放在 WPF 的每個專案,此時就可以完成了 WPF 的配置了。下一步就是將這個 WPF 倉庫構建一下,可以使用命令列方式構建,詳細請看 手把手教你構建 WPF 框架的私有版本

在構建完成之後,從 WPF 的 artifacts 資料夾裡面,可以在 artifacts\packaging\Release\Microsoft.DotNet.Wpf.GitHub 資料夾找到構建輸出的所有內容

有兩個方法,一個是打包為 NuGet 包,另一個方法是作為 Dll 引用。我推薦使用 Dll 引用的方式,這個方式使用起來更簡單

做出 Dll 引用的方法需要先做一些準備

先建立一個空白的 WPF 引用,然後使用 self-contained 獨立方式釋出,釋出的時候小心 x86 和 x64 的不同。使用 x86 和 x64 需要和 WPF 打包關聯,我當前用的都是 x86 下的

拿出來空白 WPF 的釋出輸出內容,放在 CustomWPF\Lib 資料夾

artifacts\packaging\Release\Microsoft.DotNet.Wpf.GitHub\lib\netcoreapp5.0 的檔案內容拷貝替換 CustomWPF\Lib 資料夾的檔案,上面的 netcoreapp5.0 是需要根據你具體構建的 WPF 框架而更改

接著還需要將 artifacts\packaging\Release\Microsoft.DotNet.Wpf.GitHub\runtimes\win-x86\native 資料夾裡面的 Native 部分內容也拷貝到 CustomWPF\Lib 資料夾。其實在 WPF 中使用 x86 或 x64 構建的不同就是 runtimes 資料夾內的檔案而已

現在就構建完成了 Lib 自己定製版本的依賴檔案了,接下來就是將 dotnetCampus.WPF 程式集拷貝出來,放在 CustomWPF 資料夾裡面。在 dotnetCampus.WPF.csproj 新增引用

  <ItemGroup>
    <Reference Include="..\Lib\DirectWriteForwarder.dll" />
    <Reference Include="..\Lib\Microsoft.VisualBasic.Forms.dll" />
    <Reference Include="..\Lib\PresentationCore.dll" />
    <Reference Include="..\Lib\PresentationFramework-SystemCore.dll" />
    <Reference Include="..\Lib\PresentationFramework-SystemData.dll" />
    <Reference Include="..\Lib\PresentationFramework-SystemDrawing.dll" />
    <Reference Include="..\Lib\PresentationFramework-SystemXml.dll" />
    <Reference Include="..\Lib\PresentationFramework-SystemXmlLinq.dll" />
    <Reference Include="..\Lib\PresentationFramework.Aero.dll" />
    <Reference Include="..\Lib\PresentationFramework.Aero2.dll" />
    <Reference Include="..\Lib\PresentationFramework.AeroLite.dll" />
    <Reference Include="..\Lib\PresentationFramework.Classic.dll" />
    <Reference Include="..\Lib\PresentationFramework.dll" />
    <Reference Include="..\Lib\PresentationFramework.Luna.dll" />
    <Reference Include="..\Lib\PresentationFramework.Royale.dll" />
    <Reference Include="..\Lib\PresentationUI.dll" />
    <Reference Include="..\Lib\ReachFramework.dll" />
    <Reference Include="..\Lib\System.Design.dll" />
    <Reference Include="..\Lib\System.Drawing.Common.dll" />
    <Reference Include="..\Lib\System.Drawing.Design.dll" />
    <Reference Include="..\Lib\System.Drawing.dll" />
    <Reference Include="..\Lib\System.Printing.dll" />
    <Reference Include="..\Lib\System.Private.DataContractSerialization.dll" />
    <Reference Include="..\Lib\System.Private.Uri.dll" />
    <Reference Include="..\Lib\System.Private.Xml.dll" />
    <Reference Include="..\Lib\System.Private.Xml.Linq.dll" />
    <Reference Include="..\Lib\System.Security.Cryptography.OpenSsl.dll" />
    <Reference Include="..\Lib\System.Windows.Controls.Ribbon.dll" />
    <Reference Include="..\Lib\System.Windows.Forms.Design.dll" />
    <Reference Include="..\Lib\System.Windows.Forms.Design.Editors.dll" />
    <Reference Include="..\Lib\System.Windows.Forms.dll" />
    <Reference Include="..\Lib\System.Windows.Forms.Primitives.dll" />
    <Reference Include="..\Lib\System.Windows.Input.Manipulations.dll" />
    <Reference Include="..\Lib\System.Windows.Presentation.dll" />
    <Reference Include="..\Lib\System.Xaml.dll" />
    <Reference Include="..\Lib\UIAutomationClient.dll" />
    <Reference Include="..\Lib\UIAutomationClientSideProviders.dll" />
    <Reference Include="..\Lib\UIAutomationProvider.dll" />
    <Reference Include="..\Lib\UIAutomationTypes.dll" />
    <Reference Include="..\Lib\WindowsBase.dll" />
    <Reference Include="..\Lib\WindowsFormsIntegration.dll" />
  
  </ItemGroup>

現在嘗試在 dotnetCampus.WPF 程式集內寫程式碼,這裡的程式碼可以訪問 WPF 框架的 internal 成員

我將上面的製作完成的內容放在 CSDN 下載 歡迎小夥伴下載來試試

這部分的 WPF 程式碼我也放在 GitHub 歡迎小夥伴訪問

我搭建了自己的部落格 https://blog.lindexi.com/ 歡迎大家訪問,裡面有很多新的部落格。只有在我看到部落格寫成熟之後才會放在csdn或部落格園,但是一旦釋出了就不再更新

如果在部落格看到有任何不懂的,歡迎交流,我搭建了 dotnet 職業技術學院 歡迎大家加入

如有不方便在部落格評論的問題,可以加我 QQ 2844808902 交流

知識共享許可協議
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含連結:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。如有任何疑問,請與我聯絡。