# dotnet

.NET 是開放原始碼開發平臺，只是說它是語言和程式庫的集合，可以一起建置所有類型的應用程式！

# Installation

- [在 Linux 發行版本上安裝 .NET - .NET | Microsoft Learn](https://learn.microsoft.com/zh-tw/dotnet/core/install/linux)
- [How To Install Microsoft .NET Core SDK On Linux](https://ostechnix.com/how-to-install-microsoft-net-core-sdk-on-linux/)

#### RedHat 8

- [https://docs.microsoft.com/zh-tw/dotnet/core/install/linux-rhel](https://docs.microsoft.com/zh-tw/dotnet/core/install/linux-rhel)
- [https://access.redhat.com/documentation/en-us/net/6.0/html/getting\_started\_with\_.net\_on\_rhel\_8/index](https://access.redhat.com/documentation/en-us/net/6.0/html/getting_started_with_.net_on_rhel_8/index)

.NET 6.0 已經包含在官方的 AppStream 套件庫裡。

安裝 SDK 開發環境

```shell
sudo yum install dotnet-sdk-6.0 -y
```

安裝 runtime 執行環境

```shell
sudo dnf install aspnetcore-runtime-6.0
```

檢查版本

```shell
dotnet --list-sdks
dotnet --list-runtimes
```

#### Ubuntu 22.04

- [.NET 6 is now in Ubuntu 22.04](https://devblogs.microsoft.com/dotnet/dotnet-6-is-now-in-ubuntu-2204/)

#### Ubuntu 20.04

- [Getting started with cross-platform development using .NET on Ubuntu on WSL | Ubuntu](https://ubuntu.com/blog/creating-cross-platform-applications-with-net-on-ubuntu-on-wsl)

# Linux 上的開發

##### Create new project

```bash
dotnet new console --output my-app
dotnet run --project my-app
```

##### Add Package from NuGet

```bash
# The internet is required
cd /path/to/your/project
dotnet add package MySql.Data

# Without the internet
# Download the package from https://www.nuget.org/
dotnet add package MySql.Data --source <path-to-package>

# Verify the package installer
dotnet list package
```

##### Publishing Applications

```bash
# Publish the framework-dependent application
dotnet publish my-app.csproj -f net6.0 -c Release

# Optional: If the application is for RHEL only, trim out the dependencies needed for other platforms
# Replace architecture based on the platform you are using
#   - For Intel: x64
#   - For IBM Z and LinuxONE: s390x
#   - For 64-bit Arm: arm64
dotnet publish my-app -f net6.0 -c Release -r rhel.8-architecture --self-contained false
```

# NuGet

- [裝載您自己的 NuGet 摘要概觀 | Microsoft Learn](https://learn.microsoft.com/zh-tw/nuget/hosting-packages/overview)

NuGet Server

- [NuGet Server](https://nugetserver.net/)
- [Running a NuGet Server on Docker | dotnetthoughts](https://dotnetthoughts.net/running-a-nuget-server-on-docker/)

##### Porting NuGet Package

- [.NET Core NuGet Package Offline Restore(離線還原)](https://dotblogs.com.tw/LigiJog/2022/04/07/dotnet-restore-nuget-offline)
- [.NET Core NuGet Package Offline Restore(離線還原) - 續](https://dotblogs.com.tw/LigiJog/2022/04/16/dotnet-restore-nuget-offline-2)

NuGet Export

```bash
# 1. 確定 Internet 是可用的
# 2. 將目錄 packages 複製到離線的 dotnet 環境
cd <project-root>
mkdir packages
dotnet restore --packages ./packages
```

NuGet Import

- 因為是離線環境，建議關閉內建的 nuget.org
- 如果是複製整個 project 目錄至另一個離線環境，nuget package 只要做完 restore 就可以編譯/執行程式碼；假使不小心將 package 移除，也可以使用 `add package` 將它加回來。

```bash
# 不需要 Internet
cd <project-root>
tar xzf packages.tar.gz
dotnet restore -s ./packages

# 關閉內建的 nuget.org
dotnet nuget list source
dotnet nuget disable source "nuget.org"

# 離線安裝 package
# 必須指定原有的版本號
dotnet add package MySql.Data --version 8.0.32
```

# Sample Codes

##### MySQL Test

```c#
using System;
using System.Data;
using MySql.Data.MySqlClient;

namespace MySQL_test
{
    class Program
    {
        static void Main(string[] args)
        {
            string connstring = @"server=example.com;userid=example_user;password=example_password;database=example_database";

            MySqlConnection conn = null;
            
            try
            {
                conn = new MySqlConnection(connstring);
                conn.Open();

                string query = "SELECT * FROM table_name;";
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                DataSet ds = new DataSet();
                da.Fill(ds, "table_name");
                DataTable dt = ds.Tables["table_name"];

                foreach (DataRow row in dt.Rows)
                {
                    foreach (DataColumn col in dt.Columns)
                    {
                        Console.Write(row[col] + "\t");
                    }

                    Console.Write("\n");                  
                }           
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.ToString());
            }
            finally
            {
                if (conn != null)
                {
                    conn.Close();
                }
            }
        }
    }
}
```

##### Console App 的多重參數

- [GitHub - jpdillingham/Utility.CommandLine.Arguments](https://github.com/jpdillingham/Utility.CommandLine.Arguments)

Program.cs:

```c#
using System;
using System.Collections.Generic;
using System.Linq;
using Utility.CommandLine;

namespace Console_RabbitMQ
{
    class Program
    {
        [Argument('n', "hostname", "Host Names or IPs")]
        private static string _hostName { get; set; }

        [Argument('P', "Port", "Server Port")]
        private static int _port { get; set; }

        [Argument('u', "username", "Username")]
        private static string _userName { get; set; }

        [Argument('p', "password", "Password")]
        private static string _passWord { get; set; }

        [Argument('v', "virtualhost", "Virtualhost")]
        private static string _virtualHost { get; set; }

        [Argument('c', "queueCNT", "Queue Counts.")]
        public static int _queueCNT { get; set; }

        [Argument('q', "queueName", "Queue Name.")]
        public static string _queueName { get; set; }

        [Argument('t', "queueType", "Queue Type.")]
        public static string _queueType { get; set; }

        [Argument('m', "mqType", "MQ Type.")]
        public static string _rabbitMQType { get; set; }

        [Argument('h', "help", "Show the help.")]
        public static bool Help { get; set; }
      
      static void Main(string[] args)
        {
            Arguments.Populate();
            if (Help)
            {
                ShowHelp();

                // It guarantees that you will not proceed because you asked to show help.
                return;
            }
            Console.WriteLine("==================================");
            Console.WriteLine("Hostname: " + _hostName);
            Console.WriteLine("Port: " + _port);
            Console.WriteLine("Username: " + _userName);
            Console.WriteLine("Password: " + _passWord);
            Console.WriteLine("Virtualhost: " + _virtualHost);
            Console.WriteLine("QueueCNT: " + _queueCNT);
            Console.WriteLine("Queuename: " + _queueName);
            Console.WriteLine("Queuetype: " + _queueType);
            Console.WriteLine("RabbitMQType: " + _rabbitMQType);
            Console.WriteLine("==================================");

        private static void ShowHelp()
        {
            var helpAttributes = Arguments.GetArgumentInfo(typeof(Program));

            Console.WriteLine("Short\tLong\tFunction");
            Console.WriteLine("-----\t------\t--------");

            foreach (var item in helpAttributes)
            {
                var result = "-" + item.ShortName + "\t" + "--" + item.LongName + "\t" + item.HelpText;
                Console.WriteLine(result);
            }
        }

```