在從前,要在 GNU/Linux 下寫 .NET 程式,會使用 Mono 平台。然而,使用 Mono 平台,程式設計師要和大大小小的不相容奮戰,有時候會想乾脆去寫 Java 好了。不過,隨著 .Net 平台開始支援非 Windows 的作業系統,以及 Microsoft 開始協助 Mono 專案,上述的情形應該會逐漸改觀;對於喜歡 C# 的朋友來說,應該也是樂見其成。
註:目前 GNU/Linux 平台上的 .NET 開發環境,已加強了對數個主流發行版的原生環境支援,本文使用 Docker 的方法,僅供參考。
目前 Microsoft 對 .NET 在 GNU/Linux 上的支援有以下數項:
- .NET Core:終端應用程式
- ASP.NET Core:網頁應用程式
- Visual Studio Code:跨平台的程式編輯器
而透過 Mono 在 GNU/Linux 上的支援有以下數項:
- 終端應用程式
- GTK#:圖形應用程式
- ASP.NET:網頁應用程式
- 函式庫開發
- MonoDevelop:整合式開發環境
本文會介紹 Microsoft 提供的 .NET 平台。
其中 .Net Core 目前支援終端應用程式,而且,也支援 native binary,也就昰說,我們又多了一個可以開發命令列工具的語言 (灑花)。但是,目前 .Net Core 在 GNU/Linux 安裝不甚方便,只有提供給 Ubuntu 使用的 repo,其他的 GNU/Linux 發行版則要使用 Docker。使用 Docker 的好處是不用處理軟體相依性問題,不過, 透過 Docker container 操作命令列軟體相對較不方便。我們希望 Microsoft 能夠將 .Net 平台像 Java 平台一般,提供方便安裝的 repo,這對於推廣 .NET 平台會更有助益。
而 ASP.NET Core 則是用來執行網頁應用程式。目前可在 Ubuntu、Debian、CentOS 等發行版安裝,然而,安裝過程仍然相對繁複,希望 Microsoft 早日提供懶人包,造福大家。另外,目前 Microsoft 暫時將 .NET Core 和 ASP.NET Core 的開發環境分開,可視需要開發的程式種類自行選擇。不過,筆者倒是覺得使用 Docker 開發 ASP.NET 程式是一個不錯的選擇,因為網頁應用程式是在背景執行,而不太需要在命令列進行互動式操作,Docker 應用程式剛好也可以用背景執行的方式運行。等日後開發完成後,還可以自行撰寫 Dockerfile 將整個程式包裝成 Docker image 的形式。
Visual Studio Code 則是 Microsoft 提供的程式編輯器,功能比較偏向 editor,不過,提供部分類似 IDE 的功能,剛好可以用來撰寫 C# 程式。另外,MonoDevelop 目前不支援新形態的 .NET 和 ASP.NET 專案,可能還是需要用到 VSCode。如果自己有其他習慣的編輯器,也可以搭配 Omnisharp,加強對這些編譯器對 C# 的支援。
安裝 Docker
在開始開發 .NET Core 和 ASP.NET Core 程式前,要先安裝 Docker;安裝 Docker 相當簡單,只要以下列命令列操作即可:
# curl -fsSL https://get.docker.com/ | sh
這個 script 會偵測幾個主流的 GNU/Linux 發行版,並自動呼叫相關的套件管理程式以安裝 Docker。如果使用這個 script 出問題,請參考此處進行手動安裝。
由於 Docker 需要設定權限才能使用,除了使用 root 帳號外,比較好的方式昰將一般使用者加入 docker 群組:
# usermod -aG docker your-user
註:將 your-user 代換成真正的使用者帳號。
.NET Core 環境
安裝完 Docker 後,即可啟動 Docker container,Microsoft 已經幫我們配置好 Docker image,可直接使用。參考以下指令啟動一個 Docker container:
$ docker run -v /path/to/host/dir:/path/to/container/dir -w /path/to/container/dir --rm -it microsoft/dotnet:latest
其中 -v
設置 volume。由於 Docker container 是小型的虛擬機器,如果要和 host 的檔案溝通,要設置 volume,透過設置 volume,我們可以用 host 的軟體編輯 volume 內的專案,再由 container 內的 .NET 環境編譯軟體。-w
是指自動移動到指定的工作目錄。--rm
是指在離開 container 後,自動將 container 清除。-i
是指開啟互動性操作環境,-t
則是配置 TTY,通常 -it
會一起設定。
透過以上指令,Docker 會自動下載 .NET Core 的 image,以及啟動 container;我們就會進入 .NET 環境。會看到類似命令列提示:
root@2309a7144ab8:~#
在 Docker 中,預設都是使用 root 帳號。不過,這個虛擬機器只是給自己使用,也不太需要另創帳號。
Microsoft 指供了一個 dotnet
指令,可用來管理 .NET Core 專案。首先,先建立一個專案:
$ mkdir hello_world
$ cd hello_world
$ dotnet new
然後,安裝相關套件,這會花一些些時間:
$ dotnet restore
然後,執行該專案,會一併編譯及執行程式:
$ dotnet run
也可以編譯成執行檔:
$ dotnet build --native
要注意的是,由於在 container 內是使用 root 帳號,會導致檔案權限不足,無法開啟,要修改權限:
$ chown -R 1000:1000 .
註:根據你原來 host 上實際的使用者帳號的 uid 修改權限。
這裡另外提示一個小技巧,我們可以幫 dotnet
指令新增子命令。建立一個新的 Bash 命令稿,內容如下:
#!/bin/bash
chown -R $1:$1 .
將檔案存成 dotnet-chown
,再將檔案轉為系統指令:
$ chmod +x dotnet-chown
$ mv dotnet-chown /usr/local/bin
以後,我們就可以直接呼叫該命令:
$ dotnet chown 1000
還可以新增一個 dotnet-clean
指令。建立 Bash 命令稿,內容如下:
#!/bin/bash
rm -rf bin/ obj/
同樣地,將命令稿轉為系統指令:
$ chmod +x dotnet-clean
$ mv dotnet-clean /usr/local/bin
以後,我們就可以呼叫該命令,清除編譯的檔案:
$ dotnet clean
最後,別忘了將更動過的環境存起來,下次可以直接呼叫。可參考以下指令:
$ docker ps
$ docker commit 2e94c8ef28e2 dotnet
註:請將版本號依實際情形替換。
原來的 microsoft/dotnet image 可以刪除,以節省空間:
$ docker rmi -f microsoft/dotnet
ASP.NET Core 環境
除了用 .NET Core 開發終端機程式,另一個亮點就是 ASP.NET Core,之後,也可以在 GNU/Linux 上開發 ASP 應用程式了。不過,ASP.NET Core 內沒有內建 ASP.NET 專案的工具,Microsoft 另外發布以 Yeoman 為基礎的專案產生工具,這套工具不需使用 Docker,只要支援 Node.js 的環境就可以使用。
請先安裝 Node.js,然後,安裝相關套件:
$ npm install -g yo
$ npm install -g generator-aspnet
之後,使用 Yeoman 產生 ASP.NET 專案:
$ yo aspnet
這是一個互動式的工具,會詢問使用者幾個問題,之後就會建立一個 ASP.NET 專案。
要開發 ASP.NET 程式時,利用 Docker 建立 ASP.NET 的開發環境:
$ docker run -v /path/to/host/dir:/path/to/container/dir -p 5000:5000 -w /path/to/container/dir -it microsoft/aspnet:latest
要注意的是,使用 -p
設定要開放的 port,之後才能從 host 呼叫。同樣地,也要設定 volume,才能從 host 端編輯。
移動到專案所在資料夾:
$ cd /path/to/project/dir
用 dnu
指令安裝相關套件:
$ dnu restore
要注意的是,由於 Docker container 是一個隔離的環境,要設定非 localhost 的 IP,才能從 host 端開啟。在該專案中建立 hosting.json 檔案,並加入以下內容:
{
"server.urls": "http://0.0.0.0:5000"
}
然後,用 dnx
指令啟動該 ASP.NET 專案:
$ dnx web
在 host 端,開啟 http://localhost:5000/
,如果可以看到網頁,即表示成功開啟 ASP.NET 專案。另外,也是可以將更動後的 image 存起來,下次就不用重新調整環境。
待開發完成後,要將程式上線時,可將這些步驟寫成 Dockerfile,將啟動程式的過程自動化。例如,以 ASP.NET 內附的 Dockerfile 為例:
FROM microsoft/aspnet:1.0.0-rc1-update1
RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list
RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/*
COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]
EXPOSE 5000/tcp
ENTRYPOINT ["dnx", "-p", "project.json", "web"]
然後,再用 Apache 或 Nginx 等網頁伺服器,透過 reverse proxy 的方式呼叫該網頁應用程式即可。
後記
經由 .NET Core 和 ASP.NET Core 等專案,開發者可在 Mac 或 GNU/Linux 上以 C# 開發不同類型的應用程式。目前這些專案仍在早期狀態,能開發的項目相對有限;我們期待 Microsoft 能夠持續耕耘這些專案,讓 C# 能夠像 Java 一樣,成為實質的跨平台程式語言。