最近需要做一個小工具去整理出指定資料夾所有使用的第三方套件版本,同時去查詢nuget最新版本號。
拆解步驟大概就是兩個

  • 掃出使用套件清單
  • 以這個清單查尋nuget最新版本

透過以下語法找出所有 .csproj 檔名的檔案,並找到第三方套件的內容。
我們找一個 csproj 範例如下:

1
2
3
4
5
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>
</Project>

透過以下語法找到檔案並解析內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//找出所有 .csproj 檔案
var allFiles = Directory.GetFiles(arg, "*.csproj", SearchOption.AllDirectories);
//依序以 XDocument 載入並解析出第三方套件的名稱與版本號
foreach (var file in allFiles)
{
var projDefinition = XDocument.Load(file);
var elements = projDefinition.Element("Project")?.Element("ItemGroup")?.Elements("PackageReference");

if (elements == null)
continue;
if (!elements.Any())
continue;
var pkgRefs = elements.ToDictionary(x => x.Attribute("Include")?.Value, x => x.Attribute("Version")?.Value);
}

剩下的功能就是查詢 Nuget 取得版本號碼。
由於大部分人的使用都是直接使用 IDE 或 VS 的 package management console 來安裝,幾乎沒有使用 api 去呼叫的需求,這類型的資訊在網路上很少;若是哪天要整理的內容變很多時,手動就感覺特別的沒有效率。 我絕對不會承認官方文件看好久還是看不懂

透過 Package 名稱去查詢版本號碼其實並不太難,在 v3 api 中格式如下:

1
https://api.nuget.org/v3-flatcontainer/{PackageName}/index.json

只要把{PackageName}替換成套件名稱即可。而 Nuget 會回傳一個 json 格式資料,我們以查詢 Newtonsoft.Json 套件為例。
Url example:

閱讀全文 »

「欸這功能效能很差,每次用都速度很慢。」
這是一個很常見的「感覺」形容。每個人對於速度的快慢定義不同,有些人覺得這速度很OK,而有些人覺得效能真的太差。

在工作上我們需要盡量避免這樣的形容詞,除了不夠精確之外,還需要花費更多、額外的時間來校正雙方的度量尺,這時候就需要一個公正、客觀的數據來協助探討是否這個功能真的很慢。

今天介紹的工具就是免費、開源的 BenchmarkDotNet
這個工具能夠協助你快速完成速度的測試,不需要再像以前一樣寫滿StopWatch、手動整理跑完的數據,最後再把計時用的程式碼還原。
透過這個工具,只需要短短幾個步驟就可以取得對照的結果。

首先需要下載、安裝這個套件。

1
Install-Package BenchmarkDotNet

在本文為了我們建立一個Console專案,然後將要進行的測試內容寫在另一個新開的類別裡面。最基本的使用方式就是將測試目標函式給予 [Benchmark]Attribute即可如下。

1
2
3
4
5
6
7
8
9
10
11
public class BenchmarkSampleTestClass
{
[Benchmark]
public void TestMethod1()
{
}
[Benchmark]
public void TestMethod2()
{
}
}

在 main 方法就可以直接呼叫該class進行benchmark評測。
務必在進行benchmark時使用 Release 建置。

1
2
3
4
5
6
7
8
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<BenchmarkSampleTestClass>();
Console.ReadLine();
}
}

接著在terminal就可以看到花費時間的比較表。

閱讀全文 »

這篇文章主要是介紹以C#強型別使用Mongodb driver連線的CRUD語法,一些MongoDB的名詞就不會多著墨。

情境

我們要建立一個 hellomongodb 的資料庫,裡面有 users 的 collection,存放 user 的相關資訊。
以下範例都會使用非同步的方式,若有需要同步執行的,可以自行移除async看看,大致上都是這樣。

先打開shell模式建立DB與collection

1
2
3
4
//切換至 hellomongodb 資料庫
use hellomongodb
//建立名為 users 的 collection
db.createCollection("users")

建立連線

1
2
3
4
5
6
const string MongoAddress = "mongodb://localhost:27017";
const string HelloDatabase = "hellomongodb";
const string UserCollection = "users";

var client = new MongoClient(MongoAddress);
var collection = client.GetDatabase(HelloDatabase).GetCollection<UserEntity>(UserCollection);

Create

剛開始肯定沒有資料的,所以我們會先建立幾筆資料做為測試

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//建立一筆資料
private static async void CreateUser()
{
await GetUsersCollection().InsertOneAsync(
new UserEntity{ Name = "Shaka", Country = "Unknown", City = "Zodiac Temple"}
);
}
//一次建立多筆資料
private static async void CreateMultiUsers()
{
await GetUsersCollection().InsertManyAsync(new List<UserEntity>
{
new UserEntity{ Name = "Jack", Country = "Taiwan", City = "Taipei"},
new UserEntity{ Name = "Sion", Country = "Unknown", City = "Underworld"},
new UserEntity{ Name = "Saga", Country = "Unknown", City = "Zodiac Temple"}
}
);
}
閱讀全文 »

這邊提幾個基本的查詢容易犯得錯,之後再追加比較進階的部分。

  • 只是要確認存在,讓DB只回覆 _id,不需要整個回覆

常見的

1
2
3
4
db.users.findOne({
'username' : 'pattri'
'pwd' : 'iampass123'
})

其實只要回覆 _id,這樣可以提高傳輸效率

1
2
3
4
db.users.findOne({
'username' : 'pattri'
'pwd' : 'iampass123'
}, { '_id':1 } )
  • 重複用運算子搜索同一個欄位

1
2
3
4
db.users.find({
{ 'age': {'$gte': 30} ,
{ 'age': {'$lte': 40} ,
} )

正確的應該是

1
2
3
db.users.find({
'age': {'$gte': 30, '$lte': 40}
} )
閱讀全文 »

最近在使用 docker-compose 加入 mongodb 時遇到一個地雷。由於近日來的挫折感,不免還是問一下專家,專家馬上說道:「對呀!應該要一樣的!」接著馬上解釋原因。是這樣啦~我真的有看過官方文件以及手上的書,也許我沒看得很仔細所以忽略掉吧!

當初在debug時很認真搜尋網路,發現沒找到相關問題,有提到的只有一個網頁,我想這問題應該在本機開發或者只做demo都不會遇到,不過進到產品階段肯定會碰到。

通常我們在本機開發都會用的yml設定如下:

1
2
3
4
5
6
7
8
version: '3'

services:
mongo:
image: mongo
container_name: mongo_container
ports:
- "27017:27017"

啟動後就能很開心的用GUI或cmd連進mongo進行開發。

問題發生在..
開發階段時,我們將mongo綁定了url(當然在hostfile也加了),如下

1
2
3
4
5
6
7
8
version: '3'
services:
database:
image: mongo
container_name: Mongo_DkrCmps_Test
ports:
- "27117:27017"
entrypoint: [ "/usr/bin/mongod","--bind_ip", "localhost,mongo-local-test.com"]

當很開心的啟動後,就發現用任何方式都無法連線到mongo囉!即使docker-compose ps 也可以看到他在listen的狀態,那麼問題是出在哪?

answer

關鍵就是出在 yml 的 service 名稱,這個命名需要和你設定entrypoint 所bind的內容一樣,所以我們來調整一下..

閱讀全文 »

macOS的使用者應該都使用過vs code,加上各種plugin做起事來更是如虎添翼。

今天要介紹的工具是Open In Code,此程式的功能就是在Finder上增加一個”使用vs code開啟”的功能,讓你在使用Finder瀏覽時,隨時都能夠使用vs code開啟當前目錄,不需要再辛苦得再選定資料夾開啟。

那馬上就使用Brew cask來安裝吧!

1
brew cask install open-in-code

alt

下載完後會告訴你安裝好了以及相關位置。

  1. 去應用程式裡面找到 Open In Code.app
  2. 點選 Open In Code.app
  3. 按住 cmd拖移到 Finder 上方工具列,出現綠色+號即可。
    這樣就大功告成囉! 以後使用Finder瀏覽時,就能隨時隨地以 vs code 開啟這個目錄了。

alt

閱讀全文 »

原本要寫個用 docker compose 來起 MongoDB container 的文章,發現整個弄完不到三分鐘,好像有點過於簡單。
就順便用這個為範本來討論一下port的功能與expose的差異,在剛開始接觸的時候被搞混了一下。

攥寫yml檔案

docker compose的檔案是用yml寫的,如果不知道什麼是 yml,可以參考一下連結,基本上就是比json更高可視化、更簡潔(更小)的設定檔。

將以下內容存成 docker-compose.yml 檔案即可

1
2
3
4
5
6
7
version: '3'
services:
database:
image: mongo
container_name: Mongo_DkrCmps_Test
ports:
- "27117:27017"

執行

下面兩個指令分別就是啟動與關閉這份 docker-compose

1
2
docker-compose up    //啟動
docker-compose down //關閉

alt

上圖就是寫好yml後執行,如果沒有MongoDB的image就會從網路上下載,下載好後就可以看到MongoDB的container已經在運行。

閱讀全文 »

嗯..這篇文章筆記性質很重,因為工作上需要就順便記錄一下流程以及可能遇到的問題。

安裝

1
brew install mongodb

真的就這樣!
好吧!我有先安裝 HomeBrew 這個套件,相信 macOS 使用者應該都知道,這個套件能處理相依性的問題,若有使用linux like 的應該很能體會各種套件相依性的難搞。
BTW,不需要特別先 brew update,因為使用 brew 就會先執行 update 指令囉。

啟動mongodb前準備

MongoDB預設的DB路徑是 /data/db,所以要先配合建立這個資料夾,並賦予權限。

1
2
3
sudo mkdir -p /data/db
sudo chown pattrichou /data/db //pattrichou請自行替換成你的使用者名字
mongod //啟動

小提醒:你可以使用 whoami 指令來查詢使用者名稱

如果你不是想使用預設的路徑,可以透過 –dbpath 參數來指定DB路徑

1
mongod --dbpath <your own path>
閱讀全文 »

軟體架構圖是讓人理解系統非常重要的,而用於表現、體現軟體架構的圖有非常多種,這邊談到的是C4模型。

圖勝表、表勝文

大家都知道圖的重要性,繪製一張好的圖需要很多次的來回討論與修改,儘管花費很多時間,一但完成能夠大幅縮短後人了解系統的時間。

好啊!那來畫UML吧

UML並不是不好,而是有一些限制在,簡單列一下我的感受:

  • 觀看高度不夠。如果是想讓人快速了解系統或是要跟老闆報告,這些圖都不太適合,通常需要其他圖片來輔助。
  • 外行看不懂。圖片畫出來就是要與人溝通的,如果門檻過高讓人看不懂無異於無字天書,如果你的對象是工程師,那我想應該不會有太大問題。
  • 你真的懂UML?UML包含了各種類型的圖,除非有認真學習過怎麼繪製,否則裡面的每個細節可能會被誤用,一但誤用,就是誤會的開始了..
    例如循序圖的 Component/Entity是什麼?何時該用虛線何時該用實線…等等
  • 到底要多詳細?同樣一張圖片,無法有明確的規範到底該畫到多詳細,有的人認為寫出描述即可,有的人需要畫出實作的方法名稱

說了一些點,本篇不是討論UML的,不過我依然認為他還是個對溝通有用的圖,如果真的有寫文件的話,甚至如果真的有人看的話。

C4 Model

最近接觸到C4 Model架構,用來描述軟體架構的概念,當然相同的工具、做法有很多種,這邊就先寫一篇心得來記錄一下。
作者將架構圖的視野由高至低分為四個等級,第一等級是最上層也是最粗略的。

以下圖片街擷取自官網

閱讀全文 »