2018年4月21日 星期六

RRDTools 的基本概念與在 Windows 下使用 RRDTools

下載 Windows 使用的 RRDTools 工具

  • 請打開置個網頁 RRD for Windows ,下載取得 rrdtool-1.2.15-cygwin-1.5.20.zip 檔案
  • 這個壓縮檔案內有下圖的檔案
    RRDTools for Windows

建立 RRD 資料庫

現在,讓我們來產生一個 RRD 資料庫,在這裡,我們使用了 rrdtool create 這個命令,下達底下指令,用來產生 RRD 資料庫。我們建立一個資料來源 Data Source,其名字為 speed 且該資料來源的類型是 COUNTER,接著,設定兩個 RRA,第一個是會儲存 24 筆,每五分鐘的紀錄,也就是會記錄下 24 x 5 = 144 分鐘 的紀錄,另外一個是會儲存 10筆,每 6 x 5 = 30 分鐘的紀錄,因此,在這裡將可以看到 30 x 10 = 300 分鐘 = 5 小時的紀錄
Console
rrdtool create test.rrd --start 920804400 DS:speed:COUNTER:600:U:U RRA:AVERAGE:0.5:1:24 RRA:AVERAGE:0.5:6:10

更新 RRD 資料庫的資料

現在,我們使用 rrdtool update 指令,來進行 RRD 資料庫的更新作業,詳細指令,可以參考底下指令,再進行資料更新的時候,我們需要取得現在時間之 Unix 的秒數。
Console
rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423

查詢 RRD 資料庫內的資料

我們可以使用 rrdtool fetch 指令取得 RRD 資料庫內的資料
Console
rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200
這是輸出結果內容
 920804700: nan
 920805000: 4.0000000000e-02
 920805300: 2.0000000000e-02
 920805600: 0.0000000000e+00
 920805900: 0.0000000000e+00
 920806200: 1.4316516463e+07
 920806500: 4.0000000000e-02
 920806800: 1.3333333333e-02
 920807100: 3.6666666667e-02
 920807400: 6.6666666667e-03
 920807700: 1.6666666667e-02
 920808000: 1.2333333333e-01
 920808300: 1.0000000000e-02
 920808600: 1.6666666667e-02
 920808900: 4.6666666667e-02
 920809200: nan
 920809500: nan

產生圖片

要產生 RRD 資料庫內的資料,可以使用底下指令來產生出來
Console
rrdtool graph speed.png --start 920804400 --end 920808000 DEF:myspeed=test.rrd:speed:AVERAGE LINE2:myspeed#FF0000 --font DEFAULT:9:D:\Vulcan\Projects\2\Roman.ttf
這是 RRDTool 產生出來的圖片
RRDTool

2018年4月18日 星期三

Unity Part 3 : Unity Container 容器的使用自動註冊

在上一篇 Unity Part 2 : Unity Container 容器的使用 XML 註冊 文章中,我們透過 App.Config 這個 XML 系統組態檔案,進行 Unity 容器所需要用到型別註冊,雖然這個方法可以讓我們不用使用程式碼的方式來進行型別註冊,再不重新編譯程式碼與產生新的組件情況之下,我們可以透過系統組態檔案進行重新調整型別對應的關係,這樣的操作也是相當具有彈性。在這篇文章之中,我們將來說明第三種的 Unity 容器之型別註冊方法,那就是使用自動掃描組件內的所有型別,自動產生 Unity 容器所需用到的型別註冊,在這裡,我們也可以稱為這樣的註冊方式為抽象型別的慣例註冊,關於更多 慣例註冊或者自動註冊的說明,可以參考 Registration by Convention.aspx)
在這裡,我們將要延續上一篇的專案,來進行使用自動註冊的方式,宣告相依性注入的對應關係
本篇文章的專案範例原始碼,可以從 UnityAutoRegistration 取得

建立練習專案

  • 點選 Visual Studio 2017 功能表 [檔案] > [新增] > [專案]
  • 當出現 [新增專案] 對話窗,點選 [已安裝] > [Visual C#] > [主控台應用程式] ,並且在最下方 [名稱] 欄位處,輸入 UnityAutoRegistration ,作為此練習的開發專案名稱。
Unity Dependency Injection
  • 使用滑鼠右擊該專案節點,選擇 [管理 NuGet 套件] ,點選 [瀏覽] 標籤頁次,在搜尋文字輸入盒中,輸入 Unity 關鍵字。
  • 當出現 Unity NuGet 套件之後,選擇這個套件,安裝到這個練習專案中
Manage NuGet for Unity Dependency Injection
  • 滑鼠雙擊 [Program.cs] 這個節點檔案,使用底下程式碼將其替換
  • 在這裡,我們定義了兩個介面合約 IEmployee , ICompany
  • 另外,我們實作 IEmployee 的具體類別 Employee,在這裡類別中,我們分別展示如何使用建構式注入、屬性注入、方法注入,因此,我們在這個實作類別中,定義了三個屬性 PropertyInjectionCompany , ConstructorInjectionCompany , MethodInjectionCompany
  • 我們也實作 ICompany 的具體類別 Company,在這個類別的建構式內,我們將會顯示出當時產生物件的雜湊碼,透過了雜湊碼我們就可以區分出,再透過不同相依性注入而得到的物件,究竟是不是同一個執行個體。
  • 當我們建立起一個 UnityContainer 執行個體之後,我們使用擴充方法 UnityContainer.RegisterTypes 這個擴充方法,來進行抽象型別與具體實作型別的自動註冊。。
C Sharp / C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Attributes;
using Unity.RegistrationByConvention;

namespace UnityAutoRegistration
{
    public interface IEmployee
    {
        void DisplaySalary();
    }
    public class Employee : IEmployee
    {
        [Dependency]
        public ICompany PropertyInjectionCompany { get; set; }
        public ICompany ConstructorInjectionCompany { get; set; }
        public ICompany MethodInjectionCompany { get; set; }

        [InjectionConstructor]
        public Employee(ICompany tmpCompany)
        {
            ConstructorInjectionCompany = tmpCompany;
        }

        [InjectionMethod]
        public void Initialize(ICompany tmpCompany)
        {
            MethodInjectionCompany = tmpCompany;
        }
        public void DisplaySalary()
        {
            PropertyInjectionCompany.ShowSalary();
            ConstructorInjectionCompany.ShowSalary();
            MethodInjectionCompany.ShowSalary();

            Console.WriteLine($"Property Injection Object Hash Code is {PropertyInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Constructor Injection Object Hash Code is {ConstructorInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Method Injection Object Hash Code is {MethodInjectionCompany.GetHashCode()}");
        }
    }

    public interface ICompany
    {
        void ShowSalary();
    }
    public class Company : ICompany
    {
        public Company()
        {
            Console.WriteLine($"Company Object Hash Code = {this.GetHashCode()}");
        }
        public void ShowSalary()
        {
            Console.WriteLine("你的薪水是 22 K");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            container.RegisterTypes(
                AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default,
                WithLifetime.ContainerControlled);

            IEmployee emp = container.Resolve<IEmployee>();
            emp.DisplaySalary();

            Console.WriteLine("Press any key for continuing...");
            Console.ReadKey();

        }
    }
}

進行測試

  • 我們可以開始執行這個專案,您將會得到底下的內容
  • 我們的主程式一開始將會建立一個 UnityContainer 物件
  • 接著透過這個敘述 container.RegisterTypes(AllClasses.FromLoadedAssemblies(),WithMappings.FromMatchingInterface,WithName.Default,WithLifetime.ContainerControlled); 就會自動掃描組件內的所有型別,並且進行註冊的動作。
  • 我們將會透過 IUnityContainer.Resolve 方法,解析出 IEmployee 介面的具體實作物件出來
  • 透過解析出來的具體實作物件,我們將會呼叫該具體實作物件的 DisplaySalary 方法
Console
Company Object Hash Code = 42750725
Company Object Hash Code = 49212206
Company Object Hash Code = 40256670
你的薪水是 22 K
你的薪水是 22 K
你的薪水是 22 K
Property Injection Object Hash Code is 49212206
Constructor Injection Object Hash Code is 42750725
Method Injection Object Hash Code is 40256670
Press any key for continuing...

進階閱讀

其他相關文章

更多關於 Xamarin / Xamarin.Forms 教學、技術分享、用法文章,請參考 I ♥ Xamarin

2018年4月17日 星期二

Unity Part 2 : Unity Container 容器的使用 XML 註冊

在上一篇 Unity Part 1 : 使用 Unity 容器進行各種相依性注入的操作的練習 文章中,我們實際進行 Unity 容器的註冊與解析操作,不過,在這個練習中,我們是將介面與具體實作類別的對應關係,使用程式碼的方式,註冊到容器中,在這篇文章中,我們將會使用 App.config 組態檔定檔案來進行相依性注入的註冊動作,關於 組態檔定檔案 的相關說明,可以參考 逐步解說:使用組態檔定義資料來源
在這裡,我們將要延續上一篇的專案,來進行使用 XML 組態設定檔案的方式,宣告相依性注入的對應關係
本篇文章的專案範例原始碼,可以從 UnityConfigurationXML 取得

建立練習專案

  • 點選 Visual Studio 2017 功能表 [檔案] > [新增] > [專案]
  • 當出現 [新增專案] 對話窗,點選 [已安裝] > [Visual C#] > [主控台應用程式] ,並且在最下方 [名稱] 欄位處,輸入 UnityConfigurationXML ,作為此練習的開發專案名稱。
Unity Dependency Injection
  • 使用滑鼠右擊該專案節點,選擇 [管理 NuGet 套件] ,點選 [瀏覽] 標籤頁次,在搜尋文字輸入盒中,輸入 Unity 關鍵字。
  • 當出現 Unity NuGet 套件之後,選擇這個套件,安裝到這個練習專案中
Manage NuGet for Unity Dependency Injection
  • 使用滑鼠右擊該專案節點,選擇 [管理 NuGet 套件] ,點選 [瀏覽] 標籤頁次,在搜尋文字輸入盒中,輸入 Unity 關鍵字。
  • 當出現 Unity.Configuration NuGet 套件之後,選擇這個套件,安裝到這個練習專案中
Manage NuGet for Unity Dependency Injection
  • 滑鼠雙擊 [Program.cs] 這個節點檔案,使用底下程式碼將其替換
  • 在這裡,我們定義了兩個介面合約 IEmployee , ICompany
  • 另外,我們實作 IEmployee 的具體類別 Employee,在這裡類別中,我們分別展示如何使用建構式注入、屬性注入、方法注入,因此,我們在這個實作類別中,定義了三個屬性 PropertyInjectionCompany , ConstructorInjectionCompany , MethodInjectionCompany
  • 我們也實作 ICompany 的具體類別 Company,在這個類別的建構式內,我們將會顯示出當時產生物件的雜湊碼,透過了雜湊碼我們就可以區分出,再透過不同相依性注入而得到的物件,究竟是不是同一個執行個體。
  • 當我們建立起一個 UnityContainer 執行個體之後,我們使用這樣的敘述 var container = new UnityContainer().LoadConfiguration(); ,接著呼叫 LoadConfiguration 方法,讀取系統組態檔案中的設定內容,以便進行相關的介面與具體實作類別的對應註冊行為。
C Sharp / C#
using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Attributes;

namespace UnityConfigurationXML
{
    public interface IEmployee
    {
        void DisplaySalary();
    }
    public class Employee : IEmployee
    {
        [Dependency]
        public ICompany PropertyInjectionCompany { get; set; }
        public ICompany ConstructorInjectionCompany { get; set; }
        public ICompany MethodInjectionCompany { get; set; }

        [InjectionConstructor]
        public Employee(ICompany tmpCompany)
        {
            ConstructorInjectionCompany = tmpCompany;
        }

        [InjectionMethod]
        public void Initialize(ICompany tmpCompany)
        {
            MethodInjectionCompany = tmpCompany;
        }
        public void DisplaySalary()
        {
            PropertyInjectionCompany.ShowSalary();
            ConstructorInjectionCompany.ShowSalary();
            MethodInjectionCompany.ShowSalary();

            Console.WriteLine($"Property Injection Object Hash Code is {PropertyInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Constructor Injection Object Hash Code is {ConstructorInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Method Injection Object Hash Code is {MethodInjectionCompany.GetHashCode()}");
        }
    }

    public interface ICompany
    {
        void ShowSalary();
    }
    public class Company : ICompany
    {
        public Company()
        {
            Console.WriteLine($"Company Object Hash Code = {this.GetHashCode()}");
        }
        public void ShowSalary()
        {
            Console.WriteLine("你的薪水是 22 K");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer().LoadConfiguration();

            IEmployee emp = container.Resolve<IEmployee>();
            emp.DisplaySalary();

            Console.WriteLine("Press any key for continuing...");
            Console.ReadKey();

        }
    }
}
  • 使用滑鼠雙擊 App.config 這個節點檔案,將底下 XML 內容將其予以替換掉
  • 我們在 container 段落中,進行了介面與具體實作類別的對應宣告
  • 更多關於如何使用系統組態檔案進行其他的 Unity 相依性注入的設定,可以參考 The Unity Configuration Schema.aspx)
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!--<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>-->
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <namespace name="UnityConfigurationXML" />
    <assembly name="UnityConfigurationXML" />

    <container>
      <register type="IEmployee" mapTo="Employee" />
      <register type="ICompany" mapTo="Company" />
    </container>
  </unity>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
</configuration>

進行測試

  • 我們可以開始執行這個專案,您將會得到底下的內容
  • 我們的主程式一開始將會建立一個 UnityContainer 物件,接著呼叫 LoadConfiguration 方法,讀取系統組態檔案,進行相依性注入的註冊,最後,我們將會得到 UnityContainer 類別的執行個體
  • 我們將會透過 IUnityContainer.Resolve 方法,解析出 IEmployee 介面的具體實作物件出來
  • 透過解析出來的具體實作物件,我們將會呼叫該具體實作物件的 DisplaySalary 方法
Console
Company Object Hash Code = 42750725
Company Object Hash Code = 49212206
Company Object Hash Code = 40256670
你的薪水是 22 K
你的薪水是 22 K
你的薪水是 22 K
Property Injection Object Hash Code is 49212206
Constructor Injection Object Hash Code is 42750725
Method Injection Object Hash Code is 40256670
Press any key for continuing... 

進階閱讀

其他相關文章

更多關於 Xamarin / Xamarin.Forms 教學、技術分享、用法文章,請參考 I ♥ Xamarin

Unity Part 1 : 使用 Unity 容器進行各種相依性注入的操作的練習

Unity Container 容器是一個輕量級,可擴展的相依性注入容器,這個相依性注入容器工具集現在已經開源了,若您想要更清楚了解 Unity 更多功能,可以參考 Unity Container on Github
在這裡,我們將要來了解,如何透過 Unity 來實踐相依性注入的三種注入實作物件的方法:
  • 建構式注入 Constructor Injection
  • 屬性注入 Property Injection
  • 方法注入 Method Injection
本篇文章的專案範例原始碼,可以從 https://github.com/vulcanlee/CSharpNotes2018/tree/master/UnityDI取得

建立練習專案

  • 點選 Visual Studio 2017 功能表 [檔案] > [新增] > [專案]
  • 當出現 [新增專案] 對話窗,點選 [已安裝] > [Visual C#] > [主控台應用程式] ,並且在最下方 [名稱] 欄位處,輸入 UnityDI ,作為此練習的開發專案名稱。
Unity Dependency Injection
  • 使用滑鼠右擊該專案節點,選擇 [管理 NuGet 套件] ,點選 [瀏覽] 標籤頁次,在搜尋文字輸入盒中,輸入 Unity 關鍵字。
  • 當出現 Unity NuGet 套件之後,選擇這個套件,安裝到這個練習專案中
Manage NuGet for Unity Dependency Injection
  • 滑鼠雙擊 [Program.cs] 這個節點檔案,使用底下程式碼將其替換
  • 在這裡,我們定義了兩個介面合約 IEmployee , ICompany
  • 另外,我們實作 IEmployee 的具體類別 Employee,在這裡類別中,我們分別展示如何使用建構式注入、屬性注入、方法注入,因此,我們在這個實作類別中,定義了三個屬性 PropertyInjectionCompany , ConstructorInjectionCompany , MethodInjectionCompany
  • 我們也實作 ICompany 的具體類別 Company,在這個類別的建構式內,我們將會顯示出當時產生物件的雜湊碼,透過了雜湊碼我們就可以區分出,再透過不同相依性注入而得到的物件,究竟是不是同一個執行個體。
C Sharp / C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Attributes;

namespace UnityDI
{
    public interface IEmployee
    {
        void DisplaySalary();
    }
    public class Employee : IEmployee
    {
        [Dependency]
        public ICompany PropertyInjectionCompany { get; set; }
        public ICompany ConstructorInjectionCompany { get; set; }
        public ICompany MethodInjectionCompany { get; set; }

        [InjectionConstructor]
        public Employee(ICompany tmpCompany)
        {
            ConstructorInjectionCompany = tmpCompany;
        }

        [InjectionMethod]
        public void Initialize(ICompany tmpCompany)
        {
            MethodInjectionCompany = tmpCompany;
        }
        public void DisplaySalary()
        {
            PropertyInjectionCompany.ShowSalary();
            ConstructorInjectionCompany.ShowSalary();
            MethodInjectionCompany.ShowSalary();

            Console.WriteLine($"Property Injection Object Hash Code is {PropertyInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Constructor Injection Object Hash Code is {ConstructorInjectionCompany.GetHashCode()}");
            Console.WriteLine($"Method Injection Object Hash Code is {MethodInjectionCompany.GetHashCode()}");
        }
    }

    public interface ICompany
    {
        void ShowSalary();
    }
    public class Company : ICompany
    {
        public Company()
        {
            Console.WriteLine($"Company Object Hash Code = {this.GetHashCode()}");
        }
        public void ShowSalary()
        {
            Console.WriteLine("你的薪水是 22 K");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer unitycontainer = new UnityContainer();
            unitycontainer.RegisterType<ICompany, Company>();
            unitycontainer.RegisterType<IEmployee, Employee>();

            IEmployee emp = unitycontainer.Resolve<IEmployee>();
            emp.DisplaySalary();


            Console.WriteLine("Press any key for continuing...");
            Console.ReadKey();

        }
    }
}

建構式注入 Constructor Injection 的使用方式

在這裡,我們將我們所需要注入的物件介面,宣告成為該建構式的參數,例如 public Employee(ICompany tmpCompany) 在這裡,將會由 Unity Container 容器中,幫助我們自動產生出一個 ICompany 的實作物件,該注入的物件將會設定到 ConstructorInjectionCompany 屬性(當然,也可以是欄位 Field)中

屬性注入 Property Injection 的使用方式

想要使用這個屬性注入的機制,我們需要在該類別中宣告這個介面屬性成員,例如 public ICompany PropertyInjectionCompany { get; set; },在這裡 PropertyInjectionCompany 這個屬性的型別就是 ICompany 這個介面;而為了要能夠讓 Unity Container 容器幫助我們自動注入 ICompany 的具體實作執行個體,所以,我們需要在這該屬性前面,使用 [Dependency] 屬性 (Attribute) 來標示出來,這樣,當這個物件被 Unity 解析與產生之後,該屬性也就會注入 ICompany 的實作類別之執行個體。

方法注入 Method Injection 的使用方式

現在,我們宣告了一個方法 public void Initialize(ICompany tmpCompany) 在這方法需要一個 ICompany 參數,為了要能夠讓 Unity Container 容器知道要透過這個方法,幫助我們注入 ICompany 介面之具體實作類別的執行個體,我們可以在該方法前面,使用 [InjectionMethod] 這個 C# 屬性 (Attribute),這樣,就可以做到方法注入的功能了。

進行測試

  • 我們可以開始執行這個專案,您將會得到底下的內容
  • 我們的主程式一開始將會建立一個 IUnityContainer 物件,在這裡,我們是建立出 UnityContainer 類別的執行個體
  • 接著,我們透過了 IUnityContainer.RegisterType 方法,將介面與具體實作類別的型別名稱進行註冊的動作,這樣,Unity Container 容器,當要進行解析動作的時候,就會知道,甚麼樣的介面、型別,需要使用哪個具體型別來建立出實際的執行個體來使用。
  • 當註冊完成之後,我們將會透過 IUnityContainer.Resolve 方法,解析出 IEmployee 介面的具體實作物件出來
  • 透過解析出來的具體實作物件,我們將會呼叫該具體實作物件的 DisplaySalary 方法
Console
Company Object Hash Code = 42750725
Company Object Hash Code = 49212206
Company Object Hash Code = 40256670
你的薪水是 22 K
你的薪水是 22 K
你的薪水是 22 K
Property Injection Object Hash Code is 49212206
Constructor Injection Object Hash Code is 42750725
Method Injection Object Hash Code is 40256670
Press any key for continuing...

進階閱讀

其他相關文章

更多關於 Xamarin / Xamarin.Forms 教學、技術分享、用法文章,請參考 I ♥ Xamarin