2018年7月21日 星期六

依據組態 Debug 或 Release 設定 App.config

 安裝「擴充功能與更新」的 「 Configuration Transform」
























在 「App.config」 按下右鍵,選取「Add Config Transforms」




































會依據組態產生 App.config







App.config 新增一組 appSettings
<appSettings>
      <add key="VER" value=""/>
</appSettings>

App.Debug.config 新增一組 appSettings

<appSettings>
      <add key="VER" value="DEBUG" xdt:Locator="Match(key)" xdt:Transform="Replace" />
</appSettings>

App.Release.config 新增一組 appSettings

<appSettings>
      <add key="VER" value="RELEASE" xdt:Locator="Match(key)" xdt:Transform="Replace" />
</appSettings>

VER 就會依據對應的組態設定 value 的值

PS.後面加了兩個設定:

Locator 限制條件,透過設定 Match(key) 來要求置換目標的 key 值必須相同才會執行轉換
Transform 轉換方法,透過設定 Replace 來將置換目標的 value 值換成來源值

2018年7月17日 星期二

讀取 App.config 中的內容

在 App.config 中新增一筆資料

<appSettings>
  <add key="KEY" value="VALUE"/>
</appSettings>

將「System.Configuration」加入參考
加入:using System.Configuration;

利用下列程式碼,就能取出 App.config 中的內容
string Value_ = ConfigurationManager.AppSettings["KEY"];
執行後,Value_ 的值將會是 VALUE

2018年7月3日 星期二

讓 Visual Studio Code 可以開啟 sln 檔案

安裝擴充功能 vscode-solution-explorer
資料來源參考網址: https://github.com/fernandoescolar/vscode-solution-explorer https://hackmd.io/@chiisen/rkvLrbX2p

2018年6月4日 星期一

2018年5月7日 星期一

DI—Dependency Injection 依賴注入 超超簡單說明

 一般是用來解決「耦合性(相依)過高」的問題
通常都會搭配介面 interface 進行注入
讓程式保留彈性
便於在新的需求發生時
能便於抽換
下面我舉個例子




    /// 
    /// Logger 的介面
    /// 
    public interface ILogger
    {
        void Print(string msg, Color color);
    }

    /// 
    /// 預設的 Console Logger
    /// 
    public class ConsoleLogger : ILogger
    {
        public void Print(string msg, Color color)
        {
            System.Console.WriteLine(msg);
        }
    }


這種繼承同一介面 interface 的手法,就叫做注入 這種手法可以簡單的利用繼承同一介面 實做自己須要的程式內容 一般都會透過 DI Container 集中註冊方式 統一管理所有DI元件 例如:Autofac 想瞭解 Autofac 可以到看看這個網頁:超簡單一分鐘學會 DI 框架 AutoFac

超簡單一分鐘學會 DI 框架 AutoFac

DI—Dependency Injection 依賴注入

安裝 AutoFac 的 NuGet 套件


static void Main(string[] args)
{
    // 註冊繼承 interface 的子類別
    var builder_ = new ContainerBuilder();
    builder_.RegisterType<Mylogger>().As<Ilogger>();
                         
    // 取得繼承 interface 的子類別
    var container_ = builder_.Build();
    var logger = container_.Resolve<Ilogger>();
}


整理一下,簡單的說:

1. ContainerBuilder.Register 註冊繼承 interface 的子類別
 2. Container.Resolve 取得繼承 interface 的子類別 

AutoFac 功能非常強大,上面程式碼只是入門

2018年3月16日 星期五

超簡單的公開發行我的 NuGet 套件 *.nupkg 檔案讓別人安裝使用

在你製作好自己 NuGet 的 檔案
先連線到 nuget 網站




















點選右上角的「Sign In」
如果沒註冊過,請先註冊















點擊「Upload」再點選「Browse....」
把你的 *.nupkg 檔案上傳到網站上
記得點擊最下方的「Submit」按鈕
才會開始上傳




















上傳完畢等待一下狀態改變後,就算發行成功,大家都能抓到你的 NuGet 套件了



















安裝你的 NuGet 套件同一般 NuGet 安裝方式,這邊就不累述了。

想自己發行 NuGet 套件,可參考這篇:Visual Studio 2017 上 .NET Standard 超級簡單產生 NuGet 的 *.nupkg 檔案方式

Visual Studio 2017 超級簡單的安裝本地端 NuGet 或自己製作的 *.nupkg 檔案

點選「工具」的「選項」功能






















點選「NuGet 套件管理員」選擇「套件來源」功能
按下右方綠色加號,產生可套用的來源
填入「名稱」與「來源」就可讀取本地端 *.nupkg 檔案了。

如果要安裝本地端 *.nupkg 檔案
























點選「工具」「NuGet 套件管理員」「管理方案的 NuGet 套件」









點選右方展開鈕
選擇本地端的 nupkg 檔案選項
選擇前記得把自己的 *.nupkg 放到剛剛指定存放的目錄裡
等看到自己的 NuGet 專案,便可同一般 NuGet 安裝方式安裝到自己的專案內

如何自己製作 NuGet 的 *.nupkg 檔案可參考這篇:Visual Studio 2017 上 .NET Standard 超級簡單產生 NuGet 的 *.nupkg 檔案方式

Visual Studio 2017 上 .NET Standard 超級簡單產生 NuGet 的 *.nupkg 檔案方式

點擊「偵錯」的「屬性」選項
開啟專案屬性頁

















勾選「套件」選項的「建置時產生 NuGet 套件」,如上圖:
並填寫一些基本資料,每次「建置」就會同時產生 *.nupkg 檔案了。

2018年3月1日 星期四

Windows Server 2016 開機自動啟動程式

把程式的捷徑放在下列目錄內:

C:\Users\使用者帳號\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

每次開機便會自動開啟你的程式

2018年1月1日 星期一

簡單介紹 C# 的 yield return

情境:
找出 1 到 n 的整數中被 x 整除的數

第一版 C# 程式碼

private static void OutputFor1(int max, int divisible)
{
 for (int currentNum = 1; currentNum <= max; currentNum++)
 {
  if (currentNum % divisible != 0)
  {
   continue;
  }
  System.Console.Write($"{currentNum} ");
 }
 System.Console.WriteLine();
}

第一版修改原因:
1.每行顯示一個數字
2.邏輯改成被 x 乘於二整除的數



private static void OutputFor2(int max, int divisible)
{
 //
 // 某數的2倍整除 & 顯示由上而下
 //
 #region 說明
 // 改變顯示方式及運算邏輯時都改動這段程式碼
 // 違反「單一職責」
 #endregion 說明
 int numMultiplyByTwo_ = divisible * 2;
 for (int currentNum = 1; currentNum <= max; currentNum++)
 {
  //if (currentNum % num != 0)
  if (currentNum % numMultiplyByTwo_ != 0)
  {
   continue;
  }
  //System.Console.Write($"{currentNum} ");
  System.Console.WriteLine($"{currentNum} ");
 }
 System.Console.WriteLine();
}


針對違反「單一責任」對程式碼進行優化



private static void OutputForeachList(int max, int divisible)
{
 foreach (int item in EnumerableList(max, divisible))
 {
  System.Console.WriteLine($"{item} ");
 }
 System.Console.WriteLine();
}

private static IEnumerable EnumerableList(int max, int divisible)
{
 List result_ = new List();

 for (int currentNum = 1; currentNum <= max; currentNum++)
 {
  System.Console.WriteLine($"讀取{currentNum} ");
  if (currentNum % divisible != 0)
  {
   continue;
  }
  result_.Add(currentNum);
 }
 return result_;
}



























雖然執行結果正確,但是會發現一個效能問題。
EnumerableList(50, 2) 會無條件跑完 1 到 50
OutputForeachList 會跑 2,4,6...50
但是 OutputFor2(50, 2) 最多只會跑 50 次
雖然提升了維護性
為了效能
只好再對程式碼再進行一次優化



private static void OutputForeachList2(int max, int divisible)
{
 foreach (int item in EnumerableYield(max, divisible))
 {
  System.Console.WriteLine($"{item}");
 }
 System.Console.WriteLine();
}

private static IEnumerable EnumerableYield(int max, int divisible)
{
 for (int currentNum = 1; currentNum <= max; currentNum++)
 {
  System.Console.WriteLine($"讀取:{currentNum} ");
  if (currentNum % divisible != 0)
  {
   continue;
  }
  yield return currentNum;
 }
}




























程式碼在遇到 yield return
會暫時停止 EnumerableYield 的執行
並把 currentNum 回傳到 OutputForeachList2 函式
等 OutputForeachList2 結束一個迴圈
會再次回到 EnumerableYield 函式
繼續之前的執行 EnumerableYield 函式

總結:
一般程式碼會執行到函式結束才回到上一層的函式呼叫層
yield return 能打破這個限制
暫時交出執行權
並回傳資料到上一層















Visual Studio 2017/2019 推薦的擴充功能與更新

參考文章: 覺得 Google 的 Blogger 不太順手?透過 HTML 的 iframe 移花接木 HackMD