將Asp.Net Core和corefx移植到.Net 4.0

来源:http://www.cnblogs.com/sunnycase/archive/2017/07/26/7239507.html
-Advertisement-
Play Games

引言 因為工作內容的原因需要相容 XP,而 XP 最多支持到.Net Framework 4.0。因此無法享受到 .Net Core 帶來的一堆很好用的庫,好在無論 corefx 還是 Asp.Net Core 都是開源的,我們可以自行修改編譯出支持 .Net 4.0 的版本。 技術可行性 Net ...


引言

因為工作內容的原因需要相容 XP,而 XP 最多支持到.Net Framework 4.0。因此無法享受到 .Net Core 帶來的一堆很好用的庫,好在無論 corefx 還是 Asp.Net Core 都是開源的,我們可以自行修改編譯出支持 .Net 4.0 的版本。

技術可行性

Net 4.0 相比 4.5 和 netstandard 1.0,主要的差別有:

  • System.Threading.Tasks.Task 類型。.Net 4.0 的 Task 沒有 GetAwaiter 成員,編譯器無法生成使用 async await 的代碼。好在編譯器查找 Task.GetAwaiter 並不是直接查找成員方法,如果是擴展方法也可以,那麼我們通過對 Task 編寫 GetAwaiter 擴展方法就可以在 .Net 4.0 中使用 async await 了。
  • Reflection 類別的 API。.Net 4.5 對反射 API 進行了重構,分離出了 TypeInfo 用於運行時反射。在 .Net 4.0 中,我們可以自行編寫一個 TypeInfo 類,但是 .Net 4.5 中 TypeInfo 繼承自 Type。據我觀察實現中 GetType 返回的對象實際上就是一個 TypeInfo 對象,這一點我們無法通過自己編寫的 TypeInfo 做到,不過好在除了 mscorlib,其他庫並沒有用到這層繼承關係,因此為了不產生問題我實現的 TypeInfo 沒有繼承自 Type。
  • WeakReference<T>。.Net 4.5 中的 WeakReference<T> 並沒有繼承自 WeakReference,它的終結器方法是一個 InternalCall,也就是在 clr 中實現的。而我們無法修改 clr 的實現,因此我實現的 WeakReference<T> 繼承自 WeakReference,重用了它的終結器。
  • 其它一些類型中 API 的缺失。主要包括 GC、Cryptography。對於沒有的類型,我們可以添加實現,但對於已存在的類型是沒有辦法進行修改的。雖然 clr 中有 TypeForwardTo,配合 assembly redirecting 技術可以替換類型的實現,但 .Net 4.0 編譯的程式集預設引用了 mscorlib,而 mscorlib 並不能被 redirect,所以對於 mscorlib 中已存在類型的 API 缺失——這一點暫時沒有辦法解決。

已經移植的項目

corefx

  • System.Runtime:添加了 ExceptionDispatchInfo、IReadOnlyCollection<T>等一些只讀集合的介面、生成非同步方法所需要的 AsyncStateMachineAttribute、以及使用 MVVM 中很常用的 CallerMemberNameAttribute 等
  • System.AppContext:添加了 AppContext 類
  • System.Runtime.CompilerServices.Unsafe:添加了 Unsafe 類(ref 和 指針轉換、直接讀寫記憶體等)
  • System.Threading:添加了 Volatile 類
  • System.Threading.Tasks:添加支持 async await 相關的類
  • System.Security.Cryptography.Algorithms:添加了 IncrementalHash 的實現

Asp.Net Core

  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Options
  • Microsoft.Extensions.Configuration

這些寫過 Asp,Net Core 的應該很熟悉,他們也可以用在普通的 .Net 桌面程式中

一些開源項目

  • Autofac:一個功能很強大的 IoC 實現
  • AutoMapper:對象間的映射
  • MaterialDesignThemes:WPF 的 MaterialDesign

示例

  • 新建一個 .Net 4.0 項目
  • 在 Nuget 程式包源裡加上 https://www.myget.org/F/dotnet40/api/v3/index.json,並將優先順序調到最上面
  • install-package System.Threading.Tasks -Version 4.3.0-net40(註意一定要加上 Version)
  • 在 app.config 加上 assembly redirecting
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.12.0" newVersion="4.0.12.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.12.0" newVersion="4.0.12.0" />
      </dependentAssembly>
  •  然後你就可以愉快的 async await 了

 

下麵的示例是使用了

Caliburn.Micro

Microsoft.Extensions.DependencyInjection

Microsoft.Extensions.Configuration

Autofac

Autofac.Extensions.DependencyInjection

AutoMapper

AutoMapper.Extensions.Microsoft.DependencyInjection

    public class AppBootstrapper : BootstrapperBase
    {
        public IConfiguration Configuration { get; }
        public IServiceProvider ServiceProvider { get; private set; }
        private IContainer _container;

        public AppBootstrapper()
        {
            Configuration = LoadConfiguration();
            Initialize();
        }

        private IConfiguration LoadConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("config.json", false, false);
            return builder.Build();
        }

        protected override void Configure()
        {
            var serviceCollection = new ServiceCollection();
            ServiceProvider = ConfigureServices(serviceCollection);
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.AddAutoMapper(AssemblySource.Instance.ToArray());
            services.AddSingleton<IWindowManager>(new WindowManager());
            services.AddSingleton<IEventAggregator>(new EventAggregator());
            
            services.AddSingleton(p => _container);

            var builder = new ContainerBuilder();
            builder.Populate(services);
            builder.RegisterAssemblyModules(AssemblySource.Instance.ToArray());

            _container = builder.Build();
            return new AutofacServiceProvider(_container);
        }
}

 看起來和在 Asp.Net Core 中沒什麼差別。

總結

雖然工作環境限制我們只能使用 .Net 4.0,但俗話說沒有條件,創造條件也要上。將它們移植到 .Net 4.0 也是跟上 .Net Core 和開源的步伐的一種努力吧。

關於這些包和相關的版本號可以在 https://www.myget.org/feed/Packages/dotnet40 查看

關於移植到 .Net 4.0 的計劃我創建了一個 github 組織,裡面包含移植的所有項目 https://github.com/dotnet40/

最後,感謝大家花時間閱讀!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 建立一個 SignalR 連接 配置 SignalR 連接 在 WPF 客戶端里設置連接的最大值 設置 Query String 參數 讀取 query string 指定傳輸協議 可以指定以下四種方式 LongPollingTransport ServerSentEventsTransport W ...
  • 心得體會:沒事谷歌谷歌 ...
  • 如何將鍵盤快捷方式映射到自定義按鈕,怎麼使用快捷鍵啟動自己創建的菜單,剛開始做的時候迷糊了,找了很久。可能也是因為剛開始做不是很明白,後面慢慢就懂了。其實非常簡單的。 很多快捷鍵已經在Visual studio中使用的,在確定快捷鍵之前驗證下你想設置的快捷鍵是否可以使用,當然是不可以重覆啦,是吧。 ...
  • 每個控制項都有自己預設的模板,這是MS本身就編寫好的,如果我們能夠得到這些模板的XAML代碼,那麼它將是學習模板的最好的示例,要想獲得某個控制項ctrl的預設模板,請調用以下方法: ...
  • SignalR 的 generated proxy 服務端 JavaScript 客戶端 generated proxy 非 generated proxy 什麼時候使用 generated proxy 如果你要給客戶端的方法註冊多個事件處理器,那麼你就不能使用 generated proxy。如果 ...
  • nopCommerce 3.9 中插件類型整理,詳細介紹 IWidgetPlugin 插件顯示原理,載入流程分析。 ...
  • 對於使用集群,負載均衡組件是必不可少的。包括在應用層和服務層都可以使用負載均衡。 負載均衡 我瞭解的負載均衡分兩種,使用硬體:F5和A10,和使用開源軟體:Nginx和LVS。 這裡先做個記錄,後面研究了之後再來補充。 ...
  • 搜索引擎在大型網站中也非常重要,尤其是對於大數據的處理方面,比如日誌的實時收集和分析。 搜索引擎 我研究的是ElasticSearch,最好要研究整個ELK解決方案。 先記錄在這裡,等研究完了再來完善!!! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...