三年增15萬個 北京2016年電動車搖號指標將占四成

26日北京市人大常委會會議表示,北京將逐步提高北京市小客車搖號指標中電動車的數量,未來三年分別新增3萬、6萬、6萬輛。到2016年電動車指標將占所有搖號指標的40%。   2011年起,北京開始實施小客車總量調控政策,將每年新增指標控制在24萬輛。2014年,這一數位進一步壓縮到15萬輛。目前,北京市機動車保有量已經超過500萬輛。北京市提出,將在每年15萬輛小客車新增指標內逐步提高電動車的數量。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

面試官:你剛說你喜歡研究新技術,那麼請說說你對 Blazor 的了解

閱讀本文大概需要 1.5 分鐘。

最近在幾個微信 .NET 交流群里大家討論比較頻繁的話題就是這幾天自己的面試經歷。

面試官:“你剛說你喜歡研究新技術,那麼你對 Blazor 了解多少?”。

作為一位專註於 .NET 開發的軟件工程師,你好意思說你對 Blazor 一點也不解嗎?.NET 新技術也就是那麼幾個,連微軟最近在逛推的 Blazor 你都不了解,你好意思說你喜歡研究新技術?

講真,確實有很多童鞋對 Blazor 還不了解,平時埋頭寫代碼改 Bug,哪有時間去研究 Blazor,再說這種玩意兒公司會不會採用還是個很大疑問呢。是這個理,但如果等你的公司(國內使用了.NET 技術的公司)都開始使用 Blazor 了,Blazor 還能算是新技術嗎?出於真正對技術的興趣和熱愛,對於新技術,有人會主動地去了解(不一定要研究得很深),而不是等到需要用的時候再去了解。至少他們會知道新技術有哪些優點,在公司技術選型上就可以給到自己的意見甚至推廣新技術的使用,這可能就是他們和普通程序員拉開差距的原因之一。

不管你是真對 Blazor 感興趣,還是只是為了應付面試,作為 .NET 開發者,你沒用過 Blazor,至少應該了解一下吧,哪怕是花個一兩分鐘看看這篇文章的介紹。

使用 C# 實現 Web 交互式 UI

Blazor 允許你使用 C# 來實現 Web 交互式 UI,而不需要使用 JavaScript。儘管 JavaScript 的生態很強大,但這種弱類型語言在業務邏輯比較複雜的大型 Web 開發上還是存在較大的缺陷。當然,經過幾年的發展 JavaScript 的弱類型問題可以通過工程手段來解決,甚至使用 TypeScript 來替代,但在實現可重用組件上還是有諸多的不理想。

Blazor 應用可以使用 C#、HTML 和 CSS 實現可重用 Web UI 組件,客戶端和服務器代碼都用 C# 編寫的,允許你共享代碼和庫。Blazor 是 ASP.NET Core 的一個新特性,所以可以很好的集成到 ASP.NET Core MVC/Razor Pages 應用中。

下面是一段來自於模板的 Blazor 代碼:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

在 WebAssembly 或服務器端運行

Blazor 支持兩種運行方式,一是在客戶端使用 WebAssembly 運行,二是在服務器端運行直接渲染到瀏覽器。

Blazor 可以使用 WebAssembly 直接在瀏覽器中運行客戶端 C# 代碼,正因為它是運行在 WebAssembly 上的 .NET 程序,所以客戶端也可以重用服務器端的代碼和庫。

即使不使用 WebAssembly,Blazor 也可以在服務器端運行客戶端的業務邏輯。客戶端 UI 事件使用實時消息框架 SignalR 發送回服務器,一旦執行完成,所需的 UI 更改將發送到客戶端渲染到 DOM 中。

目前主流開發單頁應用(SPA)使用 Vue 或 React 的很多,但要實現服務器端渲染(SSR),還是挺麻煩的,儘管有現成的像 Next.js 或 Nuxt.js 這樣的框架可以使用,但由於它們更新迭代比較快,依賴的 npm 包多而雜,後期維護和升級成本也很高。所以從 SSR 支持這一點來講,Blazor 應用還是有明顯優勢的。

基於開放的 Web 標準

通常是為了使用統一的編程語言或使用統一的標準,常見的做法是將一種編程語言編寫的代碼轉換為另一種編程語言,比如將 TypeScript 編寫代碼轉換成 JavaScript 以便在瀏覽器中運行。而 Blazor 使用的是開放的 Web 標準,不需要額外的插件或代碼語言轉換。Blazor 可以在所有主流的 Web 瀏覽器中工作,包括移動端瀏覽器。

在客戶端運行 Blazor 代碼和 JavaScript 框架一樣是在安全的沙箱中執行的,在基於開放的 Web 標準基礎上,Blazor 具有服務器端代碼的靈活性,比如直接連接數據庫。

和 JavaScript 交互

在 Blazor 應用中,你可以在 C# 代碼中調用 JavaScript 代碼,也可以在 JavaScript 代碼中調用 C# 代碼,兩者可以很容易實現交互操作。好處是,在使用 C# 編寫業務代碼時,你依然可以繼續使用現有龐大的 JavaScript 庫生態系統。當使用服務器端運行代碼時,Blazor 會負責在客戶端使用 JavaScript 無縫調用 C# 代碼。

下面是一個 JavaScrit 調用 C# 的示例[2]

先使用 JSInvokable 特性標註一個 C# 方法為允許 JavaScript 調用:

<button type="button" class="btn btn-primary"
        onclick="exampleJsFunctions.returnArrayAsyncJs()">
    Trigger .NET static method ReturnArrayAsync
</button>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

然後在 JavaScript 代碼中調用 C# 代碼:

window.exampleJsFunctions = {
  ...
  returnArrayAsyncJs: function () {
    DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
      .then(data => {
        data.push(4);
          console.log(data);
      });
  },
  ...
};

其它

對我來說 Blazor 最吸引的優點是前後端代碼的共用以及組件的重用。通過 nuget 管理包不僅比 npm 方便,而且體積也小很多。

Blazor 的生態也正逐步發展起來了,雖然還沒有聽說哪個大公司在用,但 Blazor 的理念是未來趨勢,值得你花點時間了解和研究一下。

參考:

[1]. http://dwz.win/EU4
[2]. http://dwz.win/EU3

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

擴張的撒哈拉沙漠 破碎的家庭和暴力

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

三菱插電式混動新技術 可為家庭供電

日前,日本三菱汽車公司宣佈,其歐藍德插電式混合動力汽車(PHEV)將配置V2H電動汽車家庭供電系統,其電池儲存的電量可以支援家庭供電的不時之需。此前V2H供電系統僅用於類似i-MIEV之類的純電動汽車。據悉,歐藍德PHEV搭載2.0升汽油發動機與一台電動馬達,可以以60英里每小時的速度行駛30英里,總續航里程可達540英里。

三菱的V2H系統在自然災害或停電的時候,可以作為100伏特(日本規格)的家用供電電源使用,運用1500瓦的交流電源,滿足家用需求。僅電池電量可以滿足普通家庭一天的用電需求。如果加滿汽油,其總電量或將滿足一個普通家庭將近10天的用電需求。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

python高級-閉包-裝飾器

閉包內容:

  1. 匿名函數:能夠完成簡單的功能,傳遞這個函數的引用,只有功能

  2. 普通函數:能夠完成複雜的功能,傳遞這個函數的引用,只有功能

  3. 閉包:能夠完成較為複雜的功能,傳遞這個閉包中的函數以及數據,因此傳遞是功能+數據

  4. 對象:能夠完成最複雜的功能,傳遞很多數據+很多功能,因此傳遞的是數據+功能

———————————————————

  1. 對全局函數進行修改:在函數當中加global,在閉包中外邊中的變量加nonlocal

  2. 閉包定義:有兩個函數嵌套使用,裏面的函數可以使用外面函數所傳輸的參數,最後可傳遞的是裏面函數的結構與數據(個人理解)。

  3. 最後閉包可以在python中引申出裝飾器 ———————————————————

 1 def closure():
 2     # 在函數內部再定義一個函數,
 3     # 並且這個函數用到了外邊函數的變量,那麼將這個函數以及用到的一些變量稱之為閉包
 4     def closure_in(x):
 5         print('---------我是打不死的%s--------' %x)
 6     return closure_in
 7  8 x = closure()
 9 x('小強')
10 11 print('*'*20)
12 # -----加餐---------
13 def closure_1(a,b,c):
14     def closure_on(x):
15         print('-----%s加餐-------' %b)
16         print(a*x + c)
17     return closure_on
18 19 demo = closure_1(2,'小強',3) #傳closure_1函數
20 demo(4) #傳clsure_on函數
21 22 #注:函數不加括號,調用的是函數本身【function】;函數加括號,調用的是函數的return結果。

 

裝飾器內容:

代碼要遵守‘開放封閉’原則;對已經寫好的函數遵守封閉,對功能擴展遵守開放;

 1 # 裝飾器的作用:為了對原來的代碼上進行擴展
 2 def decoration(func):
 3     def call_func():
 4         print('-------正在裝飾 -------' )
 5         func()
 6     return call_func
 7  8 #@decoration     #--->demo_new = decoration(demo)
 9 def demo():
10    print('demo----')
11 12 demo_new = decoration(demo)
13 demo_new()

 

使用裝飾器來測試一個函數的運行時:

 1 import time
 2 def set_func(func):
 3     def call_func():
 4         start_time = time.time()
 5         func()
 6         stop_func = time.time()
 7         print(‘alltimes is %f’ %(stop_func-start_fun))
 8     return call_func
 9 @set_func
10 def test1():
11     print(‘——-test1———’)    
12 test1()
13 14 #等價於:
15 @set_func==test1 = set_func(test1)
16

 

1. 沒有參數,沒有返回值的函數進行裝飾:
 1 def set_func(func):
 2     def call_func():
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func()
 6     return call_func
 7     
 8 @set_func
 9 def test1():
10     print(‘——test1——-   ’)

 

2. 對有參數無返回值的函數進行裝飾:
 1 def set_func(func):
 2     def call_func(a):  #
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func(a) #
 6     return call_func
 7     
 8 @set_func
 9 def test1(num):
10     print(‘——test1——- %d    ’ %num)
11 12 test1(100) —->call_func(100)
13 test1(200)——>call_func(200)

 

復現裝飾器原理:

————————————————————————-

只要遇到@函數 裝飾器(這句話),在程序中就已經執行了!!
3. 不定長參數的函數裝飾:
 1 def set_func(func):
 2     def call_func(*args,**kwargs):  #
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func(*args,**kwargs) #(拆包)將元祖拆開,每個進行傳輸;
 6         #func(args,kwargs)—>不行,相當於傳遞了兩個參數:一個元祖,一個字典。
 7     return call_func
 8     
 9 @set_func
10 def test1(num,*args,**kwargs):
11     print(‘——test1——- %d    ’ %num)
12     print(‘——test1——-   ’ , args)
13     print(‘——test1——- ’ ,kwargs )
14     
15 test1(100)  
16 test1(100,200)
17 test1(100,200,300,mm=100)

注意:*args保存不定長參數,以元祖保存,**kwargs保存字典形式(mm=…)

4.對應的返回值參數進行裝飾、通用裝飾器:
 1 #通用裝飾器
 2 def set_func(func):
 3     print(“開始進行裝飾———-”)
 4     def call_func(*args,**kwargs):  #
 5         print(‘———test2——-’)
 6         print(‘———-test3——’)
 7         return func(*args,**kwargs) #(拆包)將元祖拆開,每個進行傳輸;如果沒有return ret返回none。
 8         #func(args,kwargs)—>不行,相當於傳遞了兩個參數:一個元祖,一個字典。
 9     return call_func
10     
11 @set_func
12 def test1(num,*args,**kwargs):
13     print(‘——test1——- %d    ’ %num)
14     print(‘——test1——-   ’ , args)
15     print(‘——test1——- ’ ,kwargs )
16     return ‘ok’    #—-返回給上面的func(),然後return func—ret
17     
18 ret = test1(100)
19

 

5. 多個裝飾器對同一個函數進行裝飾:
 1 def add_qx(func):
 2     print(“——開始進行裝飾權限1———-”)
 3     def call_func(*args,**kwargs):  #
 4         print(‘這是權限驗證1’)
 5         return func(*args,**kwargs)
 6     return call_func
 7     
 8  9 def add_xx(func):
10     print(“——開始進行裝飾xx功能———-”)
11     def call_func(*args,**kwargs):  #
12         print(‘這是xx權限驗證’)
13         return func(*args,**kwargs)
14     return call_func
15     
16 @add_qx
17 @add_xx
18 def test1():
19     print(‘——test1——-’) 
20 21 test1()
22

 

首先執行第一個,但是第一個裝飾器下面不是函數(裝飾器原則:下面必須是函數,否則不執行),所以第一個函數先等待,等第二個裝飾器執行后形成函數在交給第一個裝飾器;所以運行結果是:

  1. 開始進行裝飾xx的功能,

  2. 開始進行裝飾權限1,

  3. 這是權限驗證1,

  4. 這是xx權限驗證,

  5. ——-test1——-,

——————裝飾器練習—————- 輸出格式:<td><h1>haha</h1></td>

 1 def set_func_1(func):
 2     def call_func():
 3         return ‘<h1>’ + func() + ’</h1> 4     return call_func
 5     
 6  7 def set_func_2(func):
 8     def call_func():
 9         return ‘<td>’ + func() + ’</td>10     return call_func
11     
12 @set_func_1()
13 @set_func_2()
14 def get_str():
15     return ‘haha’
16     
17 print(get_str()) 

18 最後執行的效果: <h1><td>haha</td></h1>
6. 用類對函數進行裝飾(了解):
 1 class Test(object):
 2     def __init__(self,func):
 3         self.func = fun
 4         
 5     def __call__(self):
 6         print(‘這裡是裝飾器的功能。。。。’)
 7         return self.func()
 8         
 9 @Test
10 def get_str():
11     return ‘haha’
12     
13 print(get_str())

 

以上就是裝飾器與閉包的全部內容,希望有所收穫,如果有錯誤,希望指出,感謝!!

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

高雄鼓勵換電動機車 最高補助額達 2.3 萬

高雄市機車總數達 201 萬輛,成為都市的污染源之一,為了鼓勵機車族更換電動機車,高雄市政府環保局推動補助政策,換車最高可獲得 2.3 萬元的補助。   高雄市政府環境保護局空噪科長鄭嵐 26 日下午表示,根據交通部機動車輛統計資料,高雄市截至 103 年 12 月底掛牌的使用中機車,總數約 201 萬輛,為鼓勵民眾汰舊換購電動車輛,高雄市環保局持續推動淘汰補助方案,除了經濟部工業局補助純購電動機車,機車族可獲得補助 7,200 元到 10,000 元外,若搭配汰舊二行程機車,再加碼補助至 17,400 元到 23,000 元。   他表示,同時,為了提升友善充電環境,高雄環保局近年來也積極推動充電站架設,除了原有公用及私有充電站,103 年完成社區大樓與電動機車經銷商等 25 座,共有充電站 217 站,讓高雄市騎乘電動車市民處處皆有電可充,建構低碳生活圈。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

發展電動車 梅克爾盼德國2030年前設百萬充電站

摘錄自2019年11月3日中央通訊社德國報導

德國總理梅克爾4日將與本國汽車工業代表會商,討論如何加速發展低碳排的電池驅動交通工具。她3日透過影片表示,德國在2030年前應設置100萬座電動車充電站。

德國境內目前僅有約2萬座電動車公共充電站。梅克爾指出:「為達此(發展電動車)目的,我們想在2030年前設置100萬座充電站,而產業界將必須加入相關計畫。我們要談的就是這個。」

路透社報導,預定明天在總理府舉行的會議,將是為相關議題舉辦的第二場,涉及儘速採取行動,以期交通運輸產業為德國達成國家碳排減量目標做出貢獻。會議將聚焦於汽油和柴油的替代方案,其中包括氫燃料和電池,以及政府和業界如何分攤給予消費者的補助,以刺激相關產品買氣。

梅克爾表示,政府也將致力於保障就業機會。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

無人駕駛電動車?傳蘋果正在研發車類產品

  據知情人士透露,蘋果公司早在一年前就成立了汽車研發團隊,目前該團隊共有 100 多名員工,正在研發一款代號為 Titan 的電動車,同時蘋果公司與汽車產業中無人駕駛方面的資深人士互動頻繁,研發方向很有可能是一款無人駕駛的電動車。   蘋果公司對於汽車類產品和服務的研發計劃不僅僅局限在軟體系統,而是以打造整車為目標。在研發方面蘋果並沒有與傳統汽車廠商建立太多聯繫,據知情人士透露蘋果正在與汽車零組件廠商諮詢,主要是電力和車聯網方面的公司,這些諮詢並沒有涉及合作的部分。   蘋果公司已經招募了不少汽車產業的資深人士,包括前 Benz 北美研發中心的總裁 Johann Jungwirth,他在 2014 年 9 月加入蘋果四,此前曾負責 Benz 的自動駕駛、用戶界面設計、產品風格設計等工作。     本文全文授權轉載自《科技新報》─〈〉

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

使用 nuget server 的 API 來實現搜索安裝 nuget 包

使用 nuget server 的 API 來實現搜索安裝 nuget 包

Intro

nuget 現在幾乎是 dotnet 開發不可缺少的一部分了,還沒有用過 nuget 的就有點落後時代了,還不快用起來

nuget 是 dotnet 里的包管理機制,類似於前端的 npm ,php 的 composer,java 里的 maven …

nuget 定義了一套關於 nuget server 的規範,使得用戶可以自己實現一個 nuget server

也正是這些規範,使得我們可以根據這些規範來實現 nuget server 的包管理的功能,今天主要介紹一下,根據 nuget server 的 api 規範使用原始的 HTTP 請求來實現 nuget 包的搜索和使用 nuget 提供的客戶端 SDK 來實現 nuget 包的搜索和下載

Nuget Server Api

Nuget 協議介紹

nuget 的協議有好幾個版本,目前主要用的是 v3,開源的 nuget server Baget 也實現了基於 nuget protocal v3 的規範

我們添加 nuget 源的時候會指定一個 source url,類似 https://api.nuget.org/v3/index.json 這樣的,着通常被稱為 Service Index,是一個 nuget 源的入口,有點類似於 Identity Server 里的發現文檔,通過這個地址可以獲取到一系列的資源的地址

有一些資源是協議規範里定義的必須要實現的,有一些是可選的,具體參考官方文檔,以後隨着版本變化,可能會有差異,目前 nuget.org 提供的資源如下:

Nuget.org 提供了兩種搜索的方式,

一個是 SearchQuery,會根據包名稱、 tag、description 等信息去匹配關鍵詞,

一個是 SearchAutocomplete 根據包名稱的前綴去匹配包的名稱

獲取某個 nuget 包的版本信息,可以使用 PackageBaseAddress 來獲取

ServiceIndex 返回的信息示例如下:

返回的信息會有一個 resources 的數組,會包含各種不同類型的資源,對應的 @id 就是調用這種類型的API要用到的地址,下面來看一個搜索的示例

在每個 API 的文檔頁面可以看到會使用的 @type,調用這個 API 的時候應該使用這些 @type 對應的資源

這裏的 @id 就是上面的 resource 對應的 @id

參數說明:

q 搜索時所用的關鍵詞,

skip/take 用來分頁显示查詢結果,

prelease 用來指定是否限制預覽版的 package,true 包含預覽版的 nuget 包,false 只包含已經正式發布的 nuget 包

semVerLevel 是用來指定包的語義版本

The semVerLevel query parameter is used to opt-in to SemVer 2.0.0 packages. If this query parameter is excluded, only packages with SemVer 1.0.0 compatible versions will be returned (with the standard NuGet versioning caveats, such as version strings with 4 integer pieces). If semVerLevel=2.0.0 is provided, both SemVer 1.0.0 and SemVer 2.0.0 compatible packages will be returned. See the SemVer 2.0.0 support for nuget.org for more information

packageType 用來指定 nuget 包的類型,目前支持的類型包括 Dependency(默認)項目依賴項,DotnetTool(dotnetcore 2.1 引入的 dotnet cli tool),Template (dotnet new 用) 自定義的項目模板

其他的 API 可以自行參考官方文檔:https://docs.microsoft.com/en-us/nuget/api/service-index

Packages

SearchQuery 返回的信息比較多而且可能並不準確,適用於不清楚包的名稱的時候使用,如果知道 nuget 包的名稱(PackageId) ,可以使用 SearchAutocomplete 來搜索,這樣更精準,返回的信息也更簡單,只有匹配的 package 名稱

通過原始 api 調用的方式實現 nuget 包的搜索

using var httpClient = new HttpClient(new NoProxyHttpClientHandler());
// loadServiceIndex
var serviceIndexResponse = await httpClient.GetStringAsync(NugetServiceIndex);
var serviceIndexObject = JObject.Parse(serviceIndexResponse);

var keyword = "weihanli";

//https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource
var queryEndpoint = serviceIndexObject["resources"]
    .First(x => x["@type"].Value<string>() == "SearchQueryService")["@id"]
    .Value<string>();
var queryUrl = $"{queryEndpoint}?q={keyword}&skip=0&take=5&prerelease=false&semVerLevel=2.0.0";
var queryResponse = await httpClient.GetStringAsync(queryUrl);
Console.WriteLine($"formatted queryResponse:");
Console.WriteLine($"{JObject.Parse(queryResponse).ToString(Formatting.Indented)}");

// https://docs.microsoft.com/en-us/nuget/api/search-autocomplete-service-resource
var autoCompleteQueryEndpoint = serviceIndexObject["resources"]
    .First(x => x["@type"].Value<string>() == "SearchAutocompleteService")["@id"]
    .Value<string>();
var autoCompleteQueryUrl = $"{autoCompleteQueryEndpoint}?q={keyword}&skip=0&take=5&prerelease=false&semVerLevel=2.0.0";
var autoCompleteQueryResponse = await httpClient.GetStringAsync(autoCompleteQueryUrl);
Console.WriteLine($"formatted autoCompleteQueryResponse:");
Console.WriteLine($"{JObject.Parse(autoCompleteQueryResponse).ToString(Formatting.Indented)}");

output 示例:

Query 返回示例

Autocomplete 返回結果

從上面我們可以看到 Query 接口返回了很多的信息,Autocomplete 接口只返回了 package 的名稱,返回的信息更為簡潔,所以如果可以使用 Autocomplete 的方式就盡可能使用 Autocomplete 的方式

Package Versions

前面我們提到了可以使用 PackageBaseAddress 來查詢某個 nuget 包的版本信息,文檔地址:https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource,來看一下示例:

using (var httpClient = new HttpClient(new NoProxyHttpClientHandler()))
{
    // loadServiceIndex
    var serviceIndexResponse = await httpClient.GetStringAsync(NugetServiceIndex);
    var serviceIndexObject = JObject.Parse(serviceIndexResponse);

    // https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource
    var packageVersionsEndpoint = serviceIndexObject["resources"]
        .First(x => x["@type"].Value<string>() == "PackageBaseAddress/3.0.0")["@id"]
        .Value<string>();

    var packageVersionsQueryUrl = $"{packageVersionsEndpoint}/dbtool.core/index.json";
    var packageVersionsQueryResponse = await httpClient.GetStringAsync(packageVersionsQueryUrl);
    Console.WriteLine("DbTool.Core versions:");
    Console.WriteLine(JObject.Parse(packageVersionsQueryResponse)
                      .ToString(Formatting.Indented));
}

output 示例:

注:api 地址中的 packageId 要轉小寫

Nuget Client SDK

除了上面的根據 api 自己調用,我們還可以使用 nuget 提供的客戶端 sdk 實現上述功能,這裏就不詳細介紹了,有需要可能查閱官方文檔:https://docs.microsoft.com/en-us/nuget/reference/nuget-client-sdk

下面給出一個使用示例:

var packageId = "WeihanLi.Common";
var packageVersion = new NuGetVersion("1.0.38");

var logger = NullLogger.Instance;
var cache = new SourceCacheContext();
// 在 SDK 的概念里,每一個 nuget 源是一個 repository
var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");

// SearchQuery
{
    var resource = await repository.GetResourceAsync<PackageSearchResource>();
    var searchFilter = new SearchFilter(includePrerelease: false);

    var results = await resource.SearchAsync(
        "weihanli",
        searchFilter,
        skip: 0,
        take: 20,
        logger,
        CancellationToken.None);
    foreach (var result in results)
    {
        Console.WriteLine($"Found package {result.Identity.Id} {result.Identity.Version}");
    }
}
// SearchAutoComplete
{
    var autoCompleteResource = await repository.GetResourceAsync<AutoCompleteResource>();
    var packages =
        await autoCompleteResource.IdStartsWith("WeihanLi", false, logger, CancellationToken.None);
    foreach (var package in packages)
    {
        Console.WriteLine($"Found Package {package}");
    }
}
//
{
    // get package versions
    var findPackageByIdResource = await repository.GetResourceAsync<FindPackageByIdResource>();
    var versions = await findPackageByIdResource.GetAllVersionsAsync(
        packageId,
        cache,
        logger,
        CancellationToken.None);

    foreach (var version in versions)
    {
        Console.WriteLine($"Found version {version}");
    }
}

More

你可以使用 nuget sdk 方便的實現 nuget 包的下載安裝,內部實現了簽名校驗等,這樣就可以把本地不存在的 nuget 包下載到本地了,

實現示例:

{
    var pkgDownloadContext = new PackageDownloadContext(cache);
    var downloadRes = await repository.GetResourceAsync<DownloadResource>();

    var downloadResult = await RetryHelper.TryInvokeAsync(async () =>
        await downloadRes.GetDownloadResourceResultAsync(
            new PackageIdentity(packageId, packageVersion),
            pkgDownloadContext,
            @"C:\Users\liweihan\.nuget\packages", // nuget globalPackagesFolder
            logger,
            CancellationToken.None), r => true);
    Console.WriteLine(downloadResult.Status.ToString());
}

最後提供一個解析 nuget globalPackagesFolder 的兩種思路:

一個是前面有篇文章介紹的,有個默認的配置文件,然後就是默認的配置,寫了一個解析的方法示例,支持 Windows/Linux/Mac:

{
    var packagesFolder = Environment.GetEnvironmentVariable("NUGET_PACKAGES");

    if (string.IsNullOrEmpty(packagesFolder))
    {
        // Nuget globalPackagesFolder resolve
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            var defaultConfigFilePath =
                $@"{Environment.GetEnvironmentVariable("APPDATA")}\NuGet\NuGet.Config";
            if (File.Exists(defaultConfigFilePath))
            {
                var doc = new XmlDocument();
                doc.Load(defaultConfigFilePath);
                var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                if (node != null)
                {
                    packagesFolder = node.Attributes["value"]?.Value;
                }
            }

            if (string.IsNullOrEmpty(packagesFolder))
            {
                packagesFolder = $@"{Environment.GetEnvironmentVariable("USERPROFILE")}\.nuget\packages";
            }
        }
        else
        {
            var defaultConfigFilePath =
                $@"{Environment.GetEnvironmentVariable("HOME")}/.config/NuGet/NuGet.Config";
            if (File.Exists(defaultConfigFilePath))
            {
                var doc = new XmlDocument();
                doc.Load(defaultConfigFilePath);
                var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                if (node != null)
                {
                    packagesFolder = node.Attributes["value"]?.Value;
                }
            }

            if (string.IsNullOrEmpty(packagesFolder))
            {
                defaultConfigFilePath = $@"{Environment.GetEnvironmentVariable("HOME")}/.nuget/NuGet/NuGet.Config";
                if (File.Exists(defaultConfigFilePath))
                {
                    var doc = new XmlDocument();
                    doc.Load(defaultConfigFilePath);
                    var node = doc.SelectSingleNode("/configuration/config/add[@key='globalPackagesFolder']");
                    if (node != null)
                    {
                        packagesFolder = node.Value;
                    }
                }
            }

            if (string.IsNullOrEmpty(packagesFolder))
            {
                packagesFolder = $@"{Environment.GetEnvironmentVariable("HOME")}/.nuget/packages";
            }
        }
    }

    Console.WriteLine($"globalPackagesFolder: {packagesFolder}");
}

另一個是可以根據 nuget 提供的一個命令查詢 nuget locals global-packages -l,通過命令輸出獲取

Reference

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/NugetSample/RawApiSample.cs
  • https://github.com/WeihanLi/SamplesInPractice/blob/master/NugetSample/NugetClientSdkSample.cs
  • https://docs.microsoft.com/en-us/nuget/reference/nuget-client-sdk
  • https://docs.microsoft.com/en-us/nuget/create-packages/set-package-type
  • https://docs.microsoft.com/en-us/nuget/api/overview
  • https://docs.microsoft.com/en-us/nuget/api/search-autocomplete-service-resource

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

台灣團隊以《海洋危機》出席全球最大桌遊展

摘錄自2019年11月4日自由時報報導

全球最大桌上遊戲大會「德國埃森桌遊展(SPIEL)」上月下旬開展時,台灣業者獨闖,靠實力獲邀參與官方論壇主講「環境友善」議題,直接正名Taiwan登上官網與活動介紹,不是以China(中國)或Chinese Taipei(中華台北)名稱參與,更透過桌遊,將台灣文化輸出全世界。

獨立遊戲出版業者「綿羊犬百寶箱」公司負責人林啟維表示,SPIEL桌遊展是全球最大,展期是上月24至27日,今年便8月收到該展邀請,希望出席大會在上月26日舉辦的官方論壇活動,主講「環境友善」議題,便將今年開發的《海洋危機》獲台灣逾600間學校使用的經驗,到場分享。

林啟維說,論壇中看見德國遊戲市場與亞洲新興市場的差異,永續話題也在當場彼此交鋒,但結束後卻有不少德國、荷蘭等地學校老師、環境工作者現身,指定購買台灣桌遊,另外過去也開發台灣內容的《史前歷險紀》,不少外國人玩完才發現是台灣史前文化,同樣把台灣文化輸出海外。

林啟維認為,「用熱情、專業將自己手邊的事情做好,當機會來臨,我們就會被看見。」而桌遊設計領域,一直由自由派的創作者們領導著,而台灣在遊戲設計與市場成熟度,也大大領先中國,因此這次論壇無任何政治干預,讓自已不僅代表台灣,也更代表東亞桌遊開發與應用的精神,未來將繼續努力,持續在國際舞台綻放。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?