沒錯,對于ASP.NET Core 2而言,大部分庫主要是以.NET Core 2為目標的,這是為了能順利地使用.NET Standard TFM中暫不可用的新增API。對于需要以諸如Microsoft.Extensions.*、Entity Framework Core,以及其他少數庫等多個平臺為目標的代碼,需要繼續使用.NET Standard。
在詢問微軟為何不直接開發包含必要API的.NET Standard 2.1后,Kévin Chalet繼續問到:
我的問題很簡單:RTM之前,你們是否由可能重新調整/撤銷這些改動,讓用戶能夠繼續在.NET Desktop上使用ASP.NET Core 2.0軟件包,還是說.NET Desktop上的ASP.NET Core 2.0已經徹底沒戲了?(這對包括我在內的很多人都是個很不利的因素)。
雖然不打算全文引用,但很多開發者均對此表達了類似的顧慮。
Scott Hanselman試圖通過自己對于在.NET Framework中繼續使用ASP.NET Core的主要理由安撫開發者:
AD – 老實說,如果希望直接調用LDAP,這方面還存在比較大的問題。雖然目前依然可以通過Windows Auth進行身份驗證,但我們計劃今年夏天針對Core 2.0提供更具體的DirectoryServices名稱空間。
Drawing – 這也是個問題。我們計劃今年夏天為Core 2.0提供相關能力,但在此之前,這些Netstandard選項也廣泛存在于ImageSharp、ImageResizer、Mono等選項中。
COM自動化 – 這一特性在Core 2.0中從未實現過,如果希望自尋煩惱,開發者當然可以使用PInvoke,如果這樣的煩惱還嫌不夠,還可以為net461+進程使用本地WebAPI。
與WFP應用實現代碼共享 – 沒錯,這在Netstandard2.0中是完全可行的。
隨后Scott Hanselman重申說:
.NET Core正在經歷快速的并行發展,發展速度遠遠超過了完整版.NET Framework,其實這是好事。通過基于.NET Core 2.0(別忘了,這可是.NET Standard的超集)構建ASP.NET Core 2.0應用,這意味著可以用遠超NetFx甚至Netstandard的速度進行開發。
雖然.NET Core 2.0是.NET Standard的超集,但并不是.NET Framework的超集。Kévin Chalet寫到:
很多被重新引入.NET Core 2.0的“古老的”API實際上都是歷史殘余,(從功能上來看)從來未能正常使用過。更不用提.NET Core目前依然缺乏很多API,甚至特意省略了對很多領域的支持(IdentityModel、WCF服務器、遠程、完整的AppDomain支持等)。
試圖勸說大家可以“安全地”將自己使用.NET Desktop開發的ASP.NET Core 1.0應用遷移至使用.NET Core開發的ASP.NET Core 2.0應用,在我看來這是徹頭徹尾的謊言。
談到該技術的發展速度,他又補充說:
我覺得(大部分)人們關心的并不是這個。很多人根本不需要發展速度如此快的庫,他們更想要穩定的庫,借此按自己的節奏將其集成于老應用,同時無需擔心兼容性風險。
包括Allan Lindqvist在內,很多開發者還擔心此舉可能造成社區產生嫌隙。
很多真心認可Asp.NET Core 1.1的開發者感覺自己被背叛了,他們現在可能會不愿意切換至沒有了Core的2.0版。這么說也許顯得不合理,但我想說的是,很多人都會產生這樣的感覺,同時他們將不得不應對其他更保守的同事提出的各種問題。
這些重要嗎?Asp.NET Core2/.NET Core2會因此而“亡”嗎?不會,但會拖累用戶的接受速度,讓整個生態系統支離破碎,在我看來這才是最大的悲哀。我希望大家都能使用2.0版所包含的所有出色技術,但是將交叉編譯能力限制為只能用于.NET Standard無疑會對此產生影響。當然,對大部分固守原有代碼庫的普通開發者來說這不算是個問題,但只不過是將問題轉嫁給了他們的經理。
另一個顧慮在于,這個決定是內部私下做出的,并沒有公示或公開討論。Demis Bellot認為:
由于官方事先并未公布這一消息或聽取用戶反饋,也沒有進行意見征集或給出合理的理由,這個決定“似乎”是完全與社區無關的,也沒有對現有.NET生態可能產生的影像進行任何分析,可能導致整個生態系統在未來幾年內變得支離破碎。取消對.NET v4.x的支持,意味著很多企業無法通過足夠平滑的方式將現有代碼遷移至ASP.NET的全新開發模型。這一舉措不能讓他們加速接受.NET Core,反而會打消他們這樣做的念頭,嚴重的碎片化會進一步導致整個.NET生態一分為二。我覺得最終的結果將會與Python 2/3的情況差不多,不可避免得受到碎片化的傷害,造成十幾年都無法挽回的后果。
繼續說回有關庫支持的問題,Gulbanana列舉了一些他本人需要,但.NET Core不支持的特性:
我們是Core CLR和可移植能力的忠實“鐵粉”,我們已經將自己的很多組件移植到了多個不同的Netstandard。目前我們已經通過Linux托管了一個應用,預計未來會有更多應用這樣做。然而很快將完全無法進行移植了!目前我們一些依然在維護的代碼依賴下列技術:
NTLM身份驗證(包括一些與令牌和SPN有關的高級應用場景)。
System.Drawing如上所述(這方面有個趣聞:我們需要使用一些古老的圖像格式,例如TIFF,而新的OSS庫根本不支持)。
連接至WCF/SOAP API - 依然在我們的代碼中大量使用。
Windows Crypto API(包括RSACng、ECDSA,以及用于PKI令牌的CSP)。
WPF GUI - 我們的客戶短期內不會升級至 Windows 10,但就算升級了,他們也不會使用商店應用。
Microsoft Office Interop實現數據導入和導出(主要使用Access和Excel)。
Visual Studio的擴展能力
第三方插件,例如Oracle ADO.NET提供程序
Core CLR可能永遠不會支持其中的某些技術,但這些技術也有自己的價值,同時也是新應用開發工作的基礎。我們需要一種能支持這些技術的.NET版本。目前我們的立場還是可控的:我們會隔離“遺留”(實際上也就是依賴具體平臺的)依賴項,將其隔離在符合net461規范的專有組件內。如果某個業務應用依賴這些功能,則可以針對Netfx建立依賴項。雖然我設想以后的應用很少需要這樣做,但我不覺得可以徹底避免這種做法。
有關csproj和SDK的這一切做法都是因為互操作實在太重要了。ASP.NET Core是大家希望實現互操作的誘因,我覺得取消這一點是不合理的。當然,“雖然可以單向加載引用,但最終很可能在運行時失敗”這種做法絕對算不得互操作。
Tim Miller進一步補充說:
我們目前的Web應用中還用到了OData和SignalR,在可以升級前必須繼續使用ASP.NET Core。然而我最不希望遇到的情況就是,由于對ASP.NET Core 1.x的支持被削弱而導致我們陷于其中,并且因為目前使用的框架部件不被支持,我們還無法進行遷移。我認為ASP.NET Core最終將全面取代ASP.NET,也許前路還很長,但終究有一天會實現的。因此我很不希望現在用ASP.NET MVC 5重寫我們的UI(少量內容雖已重寫,但主要是因為規模小,所以過程簡單而已),而僅僅幾年后當ASP.NET壽終正寢后又使用ASP.NET Core再次重寫。
大家關注的另一個重點是Entity Framework。雖然有EF Core,但很少有開發者會用它而不使用EF 6,因為EF Core僅支持老版本所具備的部分功能。實際上Reddit等論壇上對此有一種普遍意見:ASP.NET Core應當用于新的項目,但在變得更穩定之前,開發者應避免使用.NET Core和EF Core。
對Louis Lewis來說,最大的障礙在于硬件的檢測:
從你的這個清單來看,我們目前正在使用但尚未移植的就是system.management DLL了。具體來說,我們需要使用硬件標識符,這是為了在Azure服務總線和我們的全部許可服務器和客戶端程序包之間自動建立鏈接。我不禁在想,這些東西已經不再是API了,是否會對我們造成某些嚴重的問題?
Christian Weiss補充說:
當然了,Azure Service Fabric庫也不支持.NET Core,對我們來說這也是個障礙。
修正方案
為了回應所有這些批評,Damian Edwards已經公布了一個修正方案。
在.NET Framework上對ASP.NET Core 1.x的支持將至少再延長一年(直到2019年7月)。我們每年還會再次考慮這一時限,并保證會在ASP.NET Core 1.x支持終止前12個月發布通知(也就是說,我們會在2018年7月宣布是否繼續延長一年至2020年7月)。(題外話:現在就考慮2020年的事情,有沒有人被嚇著?沒有?好吧,那看來只有我了)。
新發布的SignalR將以ASP.NET Core 1.x為目標并為其提供完整支持(今年底發布)。
我們將繼續更新ASP.NET Core 1.x,以便支持新的語言版本或其他特性,這一做法與System.Web的處理方式無異。
運行于.NET Core 1.x的ASP.NET Core 1.x,其支持截止期限為2018年7月(無變化)。
運行于.NET Core 2+的ASP.NET Core 1.x,其支持期限與運行于.NET Framework的ASP.NET Core 1.x維持一致。這是為了確保受支持的ASP.NET Core與受支持的.NET Core之間始終有相互重疊的部分,同時還支持運行于.NET Framework,這樣客戶就可以陸續將自己的代碼移植到可支持的技術中。
.NET Core 1.x(作為運行時)的支持無變化,將于2018年7月結束。使用ASP.NET Core 1.x的客戶需要在那之前遷移至.NET Core 2.0或.NET Framework(或遷移至運行于.NET Core 2.0的ASP.NET Core 2.0)。
今年我們會將System.DirectoryServices和System.Drawing移植至.NET Core(完整支持、跨平臺,今年夏季至少提供Windows預覽版)。
在這之后還要將ServiceBase移植至.NET Core(用于支持.NET Core Windows Services)。目前沒有具體時間安排,不過已經確定了這是后續要做的工作(隨著工作的進展,時間安排無疑才能更精確)。我們還會根據客戶反饋調整后續工作安排。
目前我們并無將System.ServiceModel(服務器端WCF)移植至.NET Core的計劃。但可能會進一步完善WCF for .NET Core,并根據用戶反饋添加新的功能,例如HTTP消息加密。
如果能早點公布這些信息,也許大家的抱怨會少一些,David Fowler已經提到了微軟希望從.NET Standard中抽身的原因。
我們已經確認會將“字符串”作為.NET Core需要繼續完善的主要目標,大家提出了五花八門的想法,其中之一提到默認使用UTF8格式的字符串(兼容性問題還有很多,且聽我一一道來)。
我們打算解決的另一個問題是:能夠使用任何連續內存創建更低開銷的數組/字符串切片(Slice)。我們已經增添了Span,并在努力實現對應的Buffer。這也許意味著String和Array所實現的新接口使得我們可以創建完全無需分配的切片。
這就為String提供了新方法,可在無需每次都分配數組的情況下進行拆分。
但這會對Int、UInt等(TryParse)接受Span和Span的內容造成負擔。
這還會產生可以接受Span的全新編碼例程。
Buffer和Span可以讓我們用統一的方式呈現內存,我們還希望對網絡棧進行升級,借此傳遞可以接受Span或Buffer的Pre-pinned buffer。
Kestrel將在2.x版本期間(目前目標為2.1版)實現HTTP2,這就要求需要通過SSL流的新API來處理ALPN。
運行于.NET Core的HttpClient支持雙工流(Duplex streaming),借此將可以通過SignalR以HTTP的方式用一個非WebScoket的HTTP請求實現流端點。
我們還通過HttpClient和System.NET.Http為頭解析器的實現創建了分支,并更改了名稱,這樣就可以改進使其同時支持.NET Framework和.NET Core。.NET Core已經包含這些改進的副本,但并未投入使用,因為其實并不需要改進(未獲使用)。
與線程有關的很多新原語(Primitive)需要新的API,借此可以塑造全新的適用場景,不過這些只是我的個人看法。
雖然這些原因可以安撫一些人,但Stefan Olson也歸納了大部分開發者的想法:
在我看來,似乎ASP.NET Core將運行于.NET Core而非.NET Standard?那么我依然納悶.NET Standard價值何在?是否在誕生的那一天就注定了它最終會被拋棄?
我覺得更合理的做法是,ASP.NET Core需要依賴.NET Standard 2.1,因為該框架目前還不具備用戶需要的某些功能。那么我們只能繼續等待完整的.NET Framework支持這些額外的功能,隨后才能使用最新版ASP.NET Core。這樣是可行并且合理的。
但他們竟然拋棄了Standard,使其完全發揮不出作用(不知道我對目前這種混亂的局面理解是否正確)。
目前.NET Standard面臨的局面還不是那么悲催,它依然是一種向第三方庫同時提供.NET Framework和.NET Core能力的好方法。
挫敗感還在繼續
Stack Overflow的Nick Craver通過實例論證了很多團隊可能產生的沮喪。在花了大量時間將他們的代碼移植到ASP.NET Core + .NET Framework之后,他們覺得自己的努力做了無用功:
基本功能方面依然存在差距。移植到1.x的工作基本上完全就是一種旁側(Lateral)項目,可供我們使用的功能極為有限。2.x版在某種程度上來說還算值得進行升級,但我們也無法保證最終一定就會這么做。有很大可能我們花費大量時間、成本以及精力移植到1.x版的努力最終會擱淺,因為隨后還需要依賴完整的Framework。我不希望自己公司在這方面打賭碰運氣。最終我們能得到的支持可能遠遠比不上目前使用的ASP.NET 4.x。
除非這一點能有所改變,否則我們的應用不會移植到ASP.NET Core,而我們所有的庫可能會面臨比缺乏內部測試更糟糕的麻煩。
真心希望你們能重新考慮這個決定。希望有朝一日可以讓Stack Overflow充分利用我們貢獻出來的數千小時個人時間,幫助.NET Core平臺更上一層樓。
Quentin對此表示了贊同:
沒錯,具體原因我很理解,真希望我能說“早就猜到有這樣的一天”,但不事先通知就放棄,這一點真的讓人很不爽。
和其他廠商類似,我們也有應用生態,有誕生于十幾年前甚至更早之前的庫,有很多MVC 3、4、5應用,有控制臺應用,有Windows服務,有成百上千行代碼。相比其他一些技術,情況完全沒有糟糕到必須要進行升級的地步。
最近我們使用ASP.NET Core 1.1開發了幾個新的Web應用,這就必然要以完整的4.6.2版Framework為目標。這些應用大量運用了我們現有的共享庫。我們已經將大量開發工作時間用于處理project.json,隨后是新出現的.csproj,這么做只是為了在同一個解決方案中混合使用新老.csproj,回退至VS15將只能使用古老的.csproj類型,破碎的System.Dependencies,冗煩的程序集綁定問題,構建和發布問題……等等等等。
而現在我們已經展翅高飛進入到一個死胡同里。是否就這樣放棄數個人月的開發工作,或投入更多時間來查明哪些代碼可用哪些又不可用,然后想方設法進行升級,接下來才能知道這樣的做法到底可不可行。
不能說我完全不贊同目前的方向和必要性,只不過希望能提前通知一下大家。
秘密的意圖
這一系列意見的關鍵在于,微軟對這次的改動已經“蓄謀已久”了,只不過他們沒有公開而已。David Fowler認為:
這也是1.1版ASP.NET Core的生命周期被延長(雖然還是會結束)的主要原因。我們需要確保SignalR可以正常使用,因為那是我們選擇使用ASP.NET Core 2.0的重要原因。于此同時,歸根結底這并不是ASP.NET Core的目標,它們的目的始終在于作為統一的.NET Core平臺的一個組成部分發布給用戶。
對此Scott Sauber回應說:
我是真正見證了每一版ASP.NET的發展過程(包括Hanselman和Glenn對Docker進行的3小時排錯……因為我就是個技術宅),我會閱讀博客,我隨時刷Twitter,我每年參加兩次以上的技術會議,我會參加用戶組,我會參與各種活動,但我從未見過有人針對ASP.NET Core的發展規劃進行過此類討論。相反,我只聽到每個人都在說“它可以跨平臺運行”,沒錯,感覺就像你想坐下時有人把椅子挪走了。我甚至做過有關ASP.NET Core的演講,并且自己也說過“它可以在每個平臺上運行”這樣的話,現在感覺自己打了自己的臉。我認為,像是ITT那些游走在技術前沿的人也許能接受這樣的消息,而這肯定會招致不少抵制。感覺當更多無法快速適應的開發者以及他們的經理,也就是比ITT更為保守的那群人聽說了這個消息后,情況可能會變得更糟糕。
有關.NET Framework的其他顧慮
這個討論還談到了.NET Framework。David Fowler認為:
Span本身有一個可以運行在各種平臺的可移植版本,但我不確定.NET Framework上的實現是否是其中速度最快的。這些API即將加入.NET Framework,它們可以充分利用Span,但可能會比Span本身慢一些,畢竟范圍非常大。我們上一次在.NET Framework中更改字符串和數組又是什么時候呢?
問題不在于Span本身,而在于.NET Framework造成的影響,以及它和其他有關.NET Core的改進是否能夠順利實現。Matt Nischan認為:
我們一直認為,要在可行的情況下盡可能使用各種新穎的庫(例如Kestrel),但依然要繼續等待.NET Core變得更穩定(很高興我們耐心等待了,而原因僅僅在于這工具自身的變化),或者等待有更酷的Core版本最終融入到Framework中。我認為大部分人會假設,Corefx的各種改進,就算不是全部,只是大部分被最終納入Framework vNext或vNext+1,那結果也是極好的。然而(從超過3萬的瀏覽量)看起來,圍繞Framework的各種改變并不能塑造一個面向未來的平臺。
Frans Bouma補充說:
確實是個好問題:關于將.NET Core的功能向后移植到完整版.NET的計劃,到底還剩下些什么?看到這里我發現,完整版.NET真是太脆弱了,代碼的移植需要投入大量時間(它的改進實在是太慢),甚至可能隨時中斷(有這種可能,只是不知道具體會有多棘手),因此我認為這種情況應該不會經常發生。
這就可能產生兩個結果:或者向后移植到完整版.NET是可行的,只不過發布頻率沒那么高(例如每六個月或者每年);或者整個過程非常復雜容易出錯。如果是前一種情況,只要按照步調進行就好,不過這不能讓用戶買單,并且別再使用后者作為借口。如果是后一種情況,那么說Netstandard是“異端邪說”就是最合理的結論了,畢竟未來最重要的還是.NET Core的API不是嗎?
閱讀英文原文:ASP.NET Core Drops Support for .NET