Basic Angular Directive

นอกจาก Angular Expression แล้ว เรายังสามารถใช้ Angular Directive สำหรับการผูกข้อมูล (binding) โดย directive ที่ใช้ทั่วไป มีดังนี้

ng-init

สำหรับการกำหนดค่าเริ่มต้นให้กับตัวแปร


1
2
3
4
5
6
7
<div ng-init="price=50;qty=25">

    <p>Amount: {{ price * qty }}</p>
    <p>Amount: {{ price * qty | currency }}</p>
    <p>Amount: {{ price * qty | currency:'THB' }}</p>

</div>

ตัวอย่างจะเป็นการกำหนดค่าตัวแปร price กับ qty

ng-model

เป็นการผูกค่าตัวแปรกับ input tag ใน HTML

1
2
<input type="text" ng-model="name">
<p>Name: {{ name }}</p>

ในตัวอย่างเป็นการผูก input text กับตัวแปรชื่อ name ซึ่งในการผูกค่า อาจจะใช้เป็นตัวแปรแบบ primitive หรือว่า object ก็ได้

หรืออีกตัวอย่างหนึ่ง เป็นการผูกค่าตัวแปร like กับ input radio

1
2
3
4
5
<div ng-init="like='Yes'">
    <input type="radio" value="Yes" ng-model="like">I like
    <input type="radio" value="No" ng-model="like">I don't like
    <p>Answer: {{ like }}</p>
</div>


หรือ ผูกค่ากับ select tag

1
2
3
4
5
6
7
<select ng-model="food">
    <option value="Rice">Rice</option>
    <option value="Noodle">Noodle</option>
    <option value="Soup">Soup</option>
</select>

Your Order: {{ food }}

ng-click

เนื่องจากใน javascript ตัวแปรนอกจากจะเก็บค่าต่างๆ หรือว่าใช้เก็บเป็น object ของ property (ซึ่งก็เป็นการเก็บค่าอยู่ดี) ได้แล้ว ยังสามารถกำหนดให้ตัวแปรมีค่าเก็บ function ได้ด้วย เสมือนกับ function เป็นค่าๆ หนึ่ง ดังนั้นเราจึงใช้คุณสมบัตินี้มากำหนดพฤติกรรมของการทำงานในเอกสาร HTML ได้

ตัวอย่างกำหนดการคำนวณให้กับปุ่ม


1
2
<button ng-click="counter=counter+1">Count</button>
<p>Counter: {{ counter }}</p>

ng-if

เป็น directive ที่ใช้กำหนดเงื่อนใขให้กับ HTML

ตัวอย่างกำหนดให้แสดงหรือไม่แสดงข้อความ (รวมถึงสีพื้น)

1
2
3
4
5
6
<div ng-init="show=true">
    <p ng-if="show" style="background-color: red;">Red</p>
    <p ng-if="!show" style="background-color: green;">Green</p>

    <button ng-click="show=!show">Toggle</button>
</div>

นอกจากนี้ยังมี

  • ng-repeat
  • ng-app
  • ng-controller


พื้นฐานของ Angular Directive ก็จะมีประมาณนี้ เอาไว้ค่อยมาต่อกันนะค่ะ

Reference:
ng Directive

Angular Expression

Angular สามารถเขียน code ลงไปได้ 2 รูปแบบ คือ Angular Expression และ Angular Directive ซึ่งสำหรับ Angular Expression จะมีลักษณะคล้ายๆ การเขียน JavaScript ลงไปยัง {{ script }}

ซึ่งตัวอย่างที่สามารถเขียนลงไปได้ก็อย่างเช่น

  • {{ 'Hello World' }} - แสดงข้อความ
  • {{ 1 + 2 }} - คำนวณค่าคงที่
  • {{ a + b }} - คำนวณค่าจากตัวแปร
  • {{ user.name }} - แสดงค่า property จาก object
  • {{ items[index] }} - แสดงค่าจาก array
แต่จะแตกต่างจาก JavaScript คือ
  • JavaScript อ้างอิงจาก ตัวแปร window แต่ Angular จะใช้ $scope object
  • ตัวแปรไหนที่ไม่อยู่ใน scope หรือไม่เคยกำหนดค่ามาก่อน Angular จะใส่ให้เป็น null หรือเริ่มต้น เช่น ถ้าเป็นตัวเลขก็จะใส่เป็นค่า 0 เป็นต้น
  • ไม่สามารถใส่ Control Flow ได้ เช่น loop, if
  • ไม่สามารถสร้าง function ได้
ไว้โอกาสหน้าจะมาต่อกันเรื่อง Directive

Reference:

AngularJS 101

AngularJS เป็น lib ของ javascript ที่จะช่วยให้การเขียนได้ง่ายขึ้น (เข้าใจว่า) ดังนั้นการเขียน Angular JS จึงเหมือน javascript ทั่วๆ ไป แต่อาจจะมีการรูปแบบการเขียน (syntax) ที่แตกต่างออกไป

การจะเริ่มเขียน AngularJS สามารถเขียนได้บนไฟล์ .html ทั่วๆ ไป โดยเพิ่มการอ้างอิง AngularJS lib และใส่ module เข้าไป


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html ng-app>
    <head>
        <meta charset="utf-8">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <title>test</title>
    </head>
    <body>
        {{ 'Hello World '}}
    </body>
</html>

ส่วนที่เพิ่มเข้าไปคือ "ng-app" ใน html tag และ script ที่อ้างไปยัง AngularJS lib เพียงเท่านี้ก็เป็นอันเสร็จ คือไฟล์ html นี้สามารถเพิ่ม code ส่วนที่เป็น Angular เข้าไปได้แล้ว ซึ่งในตัวอย่างจะเป็นการแสดงข้อความ 'Hello World' ผ่านทาง AngularJS

เอาหอมปากหอมคอแค่นี้ก่อน ไว้มาดูตอนต่อไป


ติดตั้ง Sublime และ Package Control

Sublime เป็น text editor ตัวหนึ่งคล้ายๆ กับ Notepad++ แต่ว่าเป็นโปรแกรมที่มีอยู่ทั้งใน Windows, MacOS ก็เลยทำให้หลายคนใช้กัน เพราะว่าจะได้สภาพแวดล้อมที่คล้ายกันทั้งใน PC และ Mac

การติดตั้ง Sublime ก็ไม่ได้ยุ่งยากอะไร Search มาแล้วก็สามารถเลือกติดตั้งกันได้เลยทั้ง Windows, Mac แต่การจะใช้ Sublime ให้เป็นประโยชน์จะไม่ได้สิ้นสุดแค่นั้น จะต้องหา package อื่นๆ มาติดตั้งเพิ่มเติม เพื่อให้ Sublime สามารถทำงานได้มีประสิทธิภาพมากขึ้น ดังนั้นเมื่อติดตั้ง Sublime แล้ว สิ่งที่ควรติดตั้งตามมาคือ Package Control เพื่อให้สามารถติดตั้ง package อื่นๆ ต่อไปได้ ซึ่งวิธีติดตั้งสามารถเข้าไปดูจาก https://packagecontrol.io/installation ได้ค่ะ แต่สั้นๆ ก็คือไปที่เมนู View > Show Console แล้ว copy text จากในหน้าเวปนั้น ไปใส่กด enter เป็นอันเสร็จค่ะ 

หลังจากนั้นสามารถกด Ctrl + Shift + p เพื่อติดตั้ง package อื่นๆ ต่อไป ซึ่ง package อื่นๆ ก็อย่างเช่น
  • Emmet เป็นตัวช่วยให้การเขียนโปรแกรมง่ายขึ้น เช่น สามารถเขียน table>tr>td แล้วก็กด tab ได้เลย มันก็จะขึ้นมาเป็น tag table ทั้งหมดให้เรียบร้อย
  • HTML5 เข้าใจว่าเป็นตัวที่ทำให้ Sublime รู้จัก tag HTML5 จะได้แสดงสีอย่างสวยงาม
  • SublimeCodeIntel ใช้สำหรับ autocomplete code โดยเมื่อพิมพ์เข้าไปแล้วจะแสดงเป็น pop up มาให้เลือก
นอกจากนี้ยังมี package สำหรับแต่ละภาษาเช่น Python เพื่อให้แสดงสีตามแต่ละภาษาด้วย 

ก็สรุปจบการแนะนำ Sublime พร้อมการติดตั้งไว้เท่านี้

การเปลี่ยนแปลงจนถึง Java8

เป็นการสรุปที่อบรมมาค่ะ เอาแบบสั้นมากๆ

Java5

  • Fast Loop
for (int x : list)
  • Variable Argument 
public void doSomething (int... listInt)
  • Format (printf)
  • Enumeration ที่เป็น type safe
  • Autoboxing
  • Generic type
  • Annotation
  • Document annotation
  • Static import package
import static java.lang.math.*;

Java6

  • Script engine สามารถ run javascript ใน java ได้ ผ่าน class javax.script.ScriptEngine
  • String pool คือมีการรวมค่าของ string ที่เป็นค่าเดียวกันไว้ด้วยกัน (แต่ไม่ใช่ค่า string ตอน runtime)
String s1 = "Hello";
String s2 = "Hello"; // s1 = s2

String s3 = new String("Hello"); // s1 <> s3
String s4 = s3.intern(); // s1 == s4

Java7

  • String switcher คือใช้ string ในการเลือก case ได้
  • Literal underscore สามารถเพิ่ม _ เพื่อให้อ่านง่าย
long a = 127_777;
byte x = 0b0111_1111;
  • DiamondOp คือสามารถละ type ที่กำหนดใน generic class ได้
List b = new ArrayList<>();
  • Null safe มี java.util.Objects ที่เป็น utility สำหรับจัดการค่าที่สามารถเป็น null ได้ เช่น equals(), toString()
  • Multi-catch
try {
...
} catch (IndexOutOfBoundsException | NumberFormatException | ArithmeticException ex) {
    System.out.println(ex.getClass());
}

  • Try resource block
try (
/* create auto-closeable resource object (class that implements AutoCloseable interface) */
) {
...
} catch (Exception ex) {
...
}
  • Walk โดยการเพิ่ม FileVisitor ใช้กับ Files.walkFileTree
  • Watch โดยมี WatchService 
WatchService ws = FileSystems.getDefault().newWatchService();
Path p = Paths.get("temp");
p.register(ws, StandardWatchEventKinds.ENTRY_DELETE);

Java8

  • Interface สามารถสร้าง static method โดยจะต้องเป็น concrete method และเรียกผ่าน Interface ไม่ใช่เรียกที่ class
  • Interface สามารถสร้าง default method ที่เป็น concrete method ได้
  • Lambda ซึ่งจะถูกสร้างเป็น private method ใน class นั้นๆ (แม้ว่าจะคล้าย anonymous class) โดยใช้ annotation @FunctionalInterface เพื่อให้ compiler เช็คว่า interface เป็น SAM (Single Abstract Method) หรือเปล่า หรือจะใช้ predefined functional type (java.util.function.*) ก็ได้
  • Optional ซึ่งเป็น class ใหม่ เพื่อไม่ให้เกิด NullPointerException แต่ต้องใช้คู่กับ method orElse, orElseGet, orElseThrow หรือ ifPresent (ทั้งนี้จะใช้ Optional ก็จะต้องรู้เรื่อง Lambda ก่อน เพราะว่าหลาย method จะต้องใช้ความสามารถนี้)
  • Stream เป็น class ใหม่ และเพิ่ม method steam() ใน Collection และ Arrays เพื่อใช้ในการสร้าง stream หรือใช้ method of ของ Stream และเพิ่มค่าใน Stream โดย method add
Stream ss = Arrays.stream(array);

Stream sa = Stream.of(array);

Stream sd = Stream.generate(Math::random).limit(3); // สร้างค่าสุ่ม 3 ค่า

Stream sf = Files.lines(Paths.get("test.txt")); // สามารถอ่านจาก IO Stream ได้ด้วย

  • Parallel โดยสามารถใช้ได้บน Stream โดยแค่กำหนดเป็น Stream.parallel()
  • Parallel โดยใช้ class CompletableFuture

Port Exhaustion

ตามที่ได้เคย blog ไว้ว่า บังเอิญได้มาเกี่ยวข้องกับการทดสอบประสิทธิภาพของระบบซึ่งเป็น Window-base และได้เห็นปัญหาในการได้มาของ software จึงอยากจะจดบันทึกไว้เตือนตัวเอง และเผื่อจะเป็นประโยชน์กับคนอื่นได้บ้าง

ซึ่งจากการทดสอบระบบ เราพบว่า web application ที่ได้ทดสอบมีปัญหา เมื่อต้องรองรับผู้ใช้จำนวนมากๆ และจากผู้รู้หลายคนช่วยกันตรวจสอบจึงรู้ว่า อาการนี้เรียกว่า port exhaustion ซึ่งก็คือ application มีการใช้ dynamic port จนเต็ม ซึ่ง port ที่ใช้จะเป็น outbound connection (เพราะถ้าเป็น inbound มันจะมีอยู่ port เดียวอ่ะนะ)

ซึ่งวิธีการที่จะตรวจสอบการใช้ คือการใช้ netstat

> netstat -nao

ซึ่งจะแสดง connection ทั้งหมด และ pid เราจะต้องมองหา connection ที่ผิดปกติเอง ซึ่งโดยปกติถ้ามีอาการของ port exhaustion แสดงว่าจะต้องมีการใช้ port จำนวนมากจาก application หนึ่ง ซึ่งอาจจะดูได้จาก application ที่มี pid เดียวกัน และมีการใช้ port เป็นจำนวนมาก

ทีนี้หาได้แล้วทำไง ซึ่งจากเอกสารที่อ่านมา ที่ทำได้คือแจ้งเจ้าของ application ให้มาดูและแก้ไข หรือไม่ในฐานะของผู้พัฒนา application ก็คือจะต้องตรวจสอบ application ของเราเองว่ามีการใช้ connection เยอะเกินไปหรือไม่ แต่สำหรับบาง application ที่มาไกลเกินว่าจะแก้ไข วิธีที่จะแก้ไขได้ก็คือ

  1. เพิ่ม dynamic port ซึ่งแต่เดิม Windows Server 2012 จะมีการกำหนดค่า MaxUserPort ไว้ใน Windows Registry โดยสามารถกำหนได้สูงสุดคือค่า 65534 (แต่ port 1024 แรก จะกันไว้สำหรับ application บางตัวอยู่แล้ว)
  2. กำหนด connection timeout ของ port ให้ลดลง เนื่องจาก หลังจากที่ application ได้มีการปิด port ไปแล้ว port นั้นๆ จะยังใช้ไม่ได้จนกว่า 4 นาทีต่อมา ซึ่งจะต้องไปแก้ไขค่า TcpTimedWaitDelay ใน Windows Registry (แต่อยากให้ลองหาข้อมูลเพิ่มเติมกันนะค่ะ ว่าทำไมมันถึงต้องกันไว้ 4 นาที เพื่อสวัสดิภาพของระบบโดยแท้จริง) 

ทั้งนี้วิธีแก้ไข Port หรืออาการของ Port โดยละเอียด ดูได้จาก reference ข้างท้ายนะค่ะ (งานใหม่ๆ ไม่ได้มาพร้อมความลำบากเพียงอย่างเดียว มันมาพร้อมความรู้ใหม่ๆ เสมอ - เหรียญมี 2 ด้านเสมอเช่นเดียวกัน)

Reference:
Port Exhaustion
Avoiding TCP/IP Port Exhaustion
TcpTimedWaitDelay
MaxFreeTcbs

Thailand SPIN 2015


- เน้น business value สำหรับแต่ละ feature
- gap between business and technical make agile stuck.
- อะไรที่เกี่ยวกับ budget เป็นหน้าที่ของ pm.
- cost of quality มีจริง (including agile)
- การได้ cert มาง่าย การรักษาให้ quality of process คงอยู่ยาก
- agile ต้องทำทุกระดับในองค์กร
- agile เป็นแค่ tools เลือกใช้ให้ถูก

ติดตั้ง Git เชื่อมต่อกับ GitHub

1. สมัคร GitHub ที่ https://github.com/
เมื่อสมัครแล้ว GitHub จะส่งเมล์มา verify email ที่เราใส่ไป เพราะจะใช้เป็น email ในการส่งการเปลี่ยนแปลงของ project ที่เราเข้าร่วมมาให้ ให้เราทำการ verify ให้เรียบร้อย

2. download โปรแกรมจาก http://git-scm.com/

3. double click เพื่อติดตั้ง

4. สร้าง ssh key สำหรับเชื่อมต่อกับ GitHub ในการ push, pull ไฟล์
โดยการ คลิ๊กขวาที่ directory ใดๆ เลือก Git Bash



เมื่อเข้าหน้า command ให้ใช้คำสั่ง

$ ssh-keygen

ซึ่ง git จะไปสร้าง key file ใน home directory\.ssh ของ user ซึ่งสำหรับ Windows จะอยู่ที่ C:\Users\[username]\.ssh

ซึ่งไฟล์จะประกอบด้วย

  • known_hosts เป็น ip และ public key ของ GitHub
  • id_rsa ซึ่งเป็น private key
  • id_rsa.pub เป็น public key

5. add public key ใน GitHub
โดย login เข้า GitHub
เลือก Setting
เลือก SSH Keys
กดปุ่ม Add SSH Key


ตั้งชื่อ title ซึ่งเป็นอะไรก็ได้
copy content ของ id_rsa.pub ใส่ใน key

โดย 1 user จะสามารถมี key ที่เครื่องใดๆ ได้ 1 key เท่านั้น แต่ถ้า 1 user มีหลายเครื่องก็จะต้องสร้าง key สำหรับแต่ละเครื่องในการติดต่อกับ GitHub

6. ตั้งค่า user name, email
ใน Git Bash

$ git config --global user.name "xxx"
$ git config --global user.email "xxx@xxx"


เท่านี้ก็น่าจะเสร็จเรียบร้อยสำหรับการติดตั้งค่ะ





สรุปคำสั่ง run Robot Framework

สำหรับการทำงานพื้นฐานเลย คือสั่งให้ script ทำงานธรรมดา

> pybot [filename.txt]

สำหรับการกำหนดตำแหน่งที่เก็บไฟล์ที่ได้จากการทำงานของ script

> pybot --output [folder] [filename.txt]
> pybot --log [folder] [filename.txt]
> pybot --report [folder] [filename.txt]

หรือถ้าต้องการเก็บทั้งหมดไว้ใน folder เดียวกัน 
> pybot --outputdir [folder] [filename.txt]
> pybot -d [folder] [filename.txt]

และถ้าต้องการให้ไฟล์ที่ได้มีการใส่วันเวลาต่อท้าย เพื่อไม่ให้ทับไฟล์เก่า
> pybot --timestampoutputs [filename.txt]
> pybot -T [filename.txt]


หรือในกรณีต้องการกำหนดค่าตัวแปรที่จะใส่เข้าไปใน script

> pybot --variable [name]:[value]

หรือกำหนดประเภทการทำงานซึ่งได้แก่ ExitOnFailure, random:test, random:suit, randam:all

> pybot --runmode [mode] [filename.txt]










ติดตั้ง Sublime สำหรับ Robot Framework

Sublime เป็น text editor ตัวหนึ่งเท่านั้นเองค่ะ แต่ว่ามันมี package เสริมสำหรับเขียน Robot Framework script

วิธีการติดตั้ง
1. download โปรแกรมกันได้ที่ http://www.sublimetext.com/
สำหรับเราเลือก download เป็น portable ค่ะ

2. extract ตัว .zip ก็เป็นอันเสร็จเลย

3. ติดตั้ง package control ของ sublime โดย copy คำสั่งใน https://packagecontrol.io/installation#st2
ไปที่ sublime console (เมนู View > Show Console) แล้ว enter เลย

4. ติดตั้ง Robot Framework package
ไปที่เมนู Tools > Command Palette...
พิมพ์และเลือก "Package Control : Install Package"
พิมพ์ Robot เลือกติดตั้ง Robot Framework 2 package


เสร็จแล้วค่า... ต่อไปก็เริ่มเขียนได้เลย


ติดตั้ง Robot Framework

ก่อนจะติดตั้ง Robot Framework กรุณาติดต้้ง Python ก่อนนะค่ะ
หลังจากติดตั้ง Python เสร็จแล้ว ก็ติดตั้ง Robot Framework จาก pip เลยค่ะ

1. ติดตั้ง Robot Framework โดย run command

> pip install robotframework

จากนั้นให้ลอง run command

> pybot 

จะได้ดังนี้



2. ติดตั้ง Selenium บน Robot Framework เพื่อใช้ในการทดสอบ web application

> pip install robotframework-selenium2library


แค่นี้เสร็จแล้วค่ะ

ติดตั้ง Python และ pip

เริ่มมาจากไปเรียน Robot Framework ซึ่งเป็น Tools สำหรับทำการทดสอบโปรแกรม และตัว Robot Framework มันเป็น Python ค่ะ ก็เลยต้องติดตั้ง ก็เลยเอามาฝากเล่นๆ


1. download Python ก่อนค่ะ ที่นี่ https://www.python.org/downloads/ ซึ่งสำหรับ Robot Framework จะต้องใช้ version 2 เพราะเหมือนยังมีปัญหากับ version 3 ก็ download version 2.7.9 มาค่ะ เป็น file .msi สำหรับการติดตั้งบน Windows

2. ก็ double click ที่ตัว .msi ที่ได้มา แล้วอย่าลืมเลือก "Add python.exe to Path" ด้วยนะค่ะ จะได้ไม่ต้องมา add เองทีหลัง

แต่ถ้าใครลืม ก็สามารถเพิ่ม PYTHON_HOME ไปยัง directory ที่ติดตั้ง ลงในตัวแปร PATH ใน environment variable ที่หลังได้ค่ะ

ทดสอบโดยการพิมพ์ python ที่หน้า command


ถ้าได้ฉะนี้ ก็แปลว่า ลง Python เรียบร้อย

3. จากนั้น ติดตั้ง pip ซึ่งเป็นตัวจัดการ package สำหรับ Python (Package Installation for Python)
โดยการ download get-pip.py จากหน้า http://www.pip-installer.org/en/latest/installing.html

4. แล้ว run command
> python get-pip.py
5. เพิ่ม %PYTHONE_HOME%/Scripts ในตัวแปร PATH เพื่อให้สามารถ run pip ได้

เมื่อลงเสร็จแล้ว เราสามารถลบตัว get-pip.py ออกไปได้เลยค่ะ

Cloud (สรุปอย่างย่อ)

Cloud Computing Definition - Key Character


  • On-demand self-service
  • Ubiquitous network access
  • Location independent resource polling
  • Rapid elasticity
  • Pay per use

Cloud Delivery Model

Traditional Model
  • Software as a Service (SaaS)
  • Platforms as a Service (PaaS)
  • Infrastructure as a Service (Iaas)
Latest Model
  • Process as a Service คือ Traditional Model ที่ความสามารถ Business Process Management, Service Oriented Architecture, Social Software

Cloud Technology's Type

  • Cloud 1.0 : IaaS - ทดแทน Hosting Service
  • Cloud 2.0 : Iaas + Mobile App - จัดการพวก non-sql data, non-structure data (Hadoop)
  • Cloud 3.0 : IaaS, PaaS, HPC, Big Data Analysis

Cloud Computing Standard Recommendation

  • ISO 27001 (Security Foundation)
  • ISO 22301 (BCM)
  • CSA Star Cert (Cloud, Governance)
  • ISO 50000 (Energy Management)
  • ISO 14001 (Environmental)
  • ISO 14064 (Greenhouse Gas)

Big Data's Type

  • 1.0 (Transaction Data, Structure Data) - ข้อมูลจากในองค์กร ex. ERP ใช้ Data Mining
  • 2.0 (Non-structure Data) - เพิ่มข้อมูลจาก Social Nework ใช้ Grid Computing (Hadoop)
  • 3.0 (Huge, Very Large Data) - เพิ่มข้อมูลจาก IoT ใช้ HPC ไม่เน้น Hadoop

.Net constants, Settings.settings, Resources.resx

ไม่รู้คนอื่นเป็นหรือเปล่า แต่เรามีความสับสนในการกำหนดค่าต่างๆ ในโปรแกรม ไม่รู้ว่าควรจะกำหนดยังไงดี

  • กำหนดเป็นค่าคงที่ใน Code
  • กำหนดใน Settings.settings
  • กำหนดใน Resources.resx
ก็ไปอ่านเจอบทความหนึ่ง ซึ่งรู้สึกว่าอ่านแล้วกระจ่างมาก เลยแปลมาให้กัน สำหรับใครที่อยากอ่านต้นฉบับดูที่ที่ลิงค์ท้ายบทความค่ะ

เค้าบอกว่าเกณฑ์ในการเลือกว่าควรจะกำหนดค่าอะไรไว้ยังไงมีดังนี้
  1. ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข และเกี่ยวข้องกับ class ใด class หนึ่งโดยเฉพาะ ให้กำหนดเป็นค่าคงที่ใน class นั้นๆ
  2. ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข แต่เกี่ยวข้องกับหลาย class ให้กำหนดเป็นค่าคงที่ใน class กลางของโปรเจค
  3. ถ้าเป็นค่าที่ให้ผู้ใช้แก้ไขได้ ให้กำหนดใน Settings.settings.
  4. ถ้าเป็นค่าที่ต้องแก้ไขโดยขึ้นกับ locale ให้กำหนดใน Resources.resx
  5. ถ้าเป็นค่าที่ต้องเปลี่ยนแปลงตามกลุ่ม (เข้าใจว่า เช่นค่าที่กำหนดสำหรับแต่ละหน้าจอ เหมือนที่เรากำหนด label ในหน้าจอ) ก็ให้กำหนดใน Resource.resx ตามโฟลเดอร์
และในบทความก็สรุปว่า Resources.resx จะกำหนดได้ก่อน build เท่านั้น ผู้ใช้ไม่สามารถเปลี่ยนค่าได้ ในขณะที่ Settings.settings สามารถแก้ได้โดยผู้ใช้ แต่ Settings.settings จะไม่เปลี่ยนตาม locale เหมือนกับ Resources.resx

References:

การ Generate Entity class จาก Entity Framework

ที่เราใช้อยู่ขณะนี้เป็น EF 6 นะค่ะ

1. คลิ๊ก Add > New Item... ที่โปรเจค


2. เลือก ADO.NET Entity Data Model และตั้งชื่อ ซึ่งจะเป็นชื่อของ .edmx ไฟล์


3. เลือกวิธีที่จะได้ diagram มา ซึ่งเราเลือกเป็น Empty EF Designer model ซึ่งจะได้ diagram เปล่าๆ มาแล้วมาใส่ entity ต่างๆ เองค่ะ


4. จากนั้นก็สร้าง Entity โดยใช้ Toolbox ด้านข้าง
5. หลังจากนั้นก็ถึงวิธีการ generate Entity โดยคลิ๊กขวาที่ diagram เลือก Generate Database from Model...


6. ถ้าเป็นการ generate ครั้งแรก VS จะขึ้นหน้าต่างมาให้เราสร้าง Connection string โดยเราจะต้องเลือกฐานข้อมูลที่เราต้องการจะให้สร้าง Entity (ทั้งนี้มันจะไม่ได้ไปสร้าง table หรืออะไรในฐานข้อมูลนั้นๆ หรอกนะค่ะ แค่เลือกเพื่อเอาไปสร้าง Connection string เฉยๆ เราจะต้องไปสร้าง table เองค่ะ)

เมื่อเสร็จแล้ว มันจะให้เรายืนยันว่าจะให้บันทึก password ของฐานข้อมูลใน Connection string หรือเปล่า ซึ่งเราจะให้มันบันทึกหรือไม่ก็ได้ค่ะ

7. เราจะได้

  • file .sql มา สำหรับไป execute ในฐานข้อมูล
  • ได้ Entity Container .cs 
  • ได้ Entity .cs 
เป็นอันเสร็จค่ะ

หมายเหตุ
- ใน Entity Framework ไม่สามารถสร้าง unique key ที่ไม่ใช่ primary ได้ค่ะ ตามลิงก์

การเปลี่ยน edmx file ใน .Net

คราวที่แล้ว พูดถึงการเปลี่ยนชื่อโปรเจค คร่าวนี้มาถึงตาที่เราอยากจะแก้ชื่อ edmx หรือ entity data model ที่เป็นไฟล์ XML กันบ้าง ซึ่งโดยปกติ edmx นี้จะสร้างมาจากการ add item ADO.NET Entity Data Model และเมื่อเราสร้างแล้ว เราสามารถให้ VS มันสร้าง file entity .cs ได้ ซึ่งมันก็จะสร้าง 


  • Model Context.tt
  • Model Context.cs
  • Model .tt
ขึ้นมาด้วย ซึ่งชื่อของไฟล์ทั้งหมดก็จะมาจากชื่อของ file .edmx นั่นเอง แต่ถ้าเราจะเปลี่ยนชื่อของ .edmx ก็จะเป็นเรื่องใหญ่ ที่เดียว แต่ก็ไม่ใช่ว่าทำไม่ได้ โดยเรา

1. rename file .edmx 
โดยคลิ๊กขวา ที่ file .edmx แล้วเลือก rename 

2. ลบ ไฟล์ที่เป็น .Context.tt และ .tt ออก
3. สร้างไฟล์ .Context.tt และ .tt ใหม่ โดยคลิ๊กขวาที่ Diagram และ คลิ๊ก "Add Code Generation Item..."


เสร็จแล้ว เลือก version ของ Entity Framework ที่ใช้ ตั้งชื่อไฟล์ .tt กด Add


เสร็จแล้ว ก็อย่าลืมลอง Generate database from model ใหม่อีกทีนะค่ะได้เลยคะ





การเปลี่ยน namespace & project folder ใน .Net

จากความที่เคยเขียน java มา พอมาใช้ .Net รู้สึกถึงความไม่คุ้นอย่างมาก อย่างแรกเลย คือ folder ของ .Net ไม่ได้เกี่ยวอะไรกับ namespace เลยสักนิดเดียว คือจริงๆ จะตั้งตรงกันหรือไม่ตรงกันก็ได้ (ซึ่งก็ไม่รู้ว่าจะไม่ตรงกันทำไม ใครมีความรู้มาบอกบ้างก็ดีนะค่ะ) และ namespace ก็ไม่จำเป็นต้องตรงกับชื่อไฟล์ project ที่เป็น .csproj แปลว่ามีชื่ออยู่ 3 ส่วนด้วยกัน คือ

  1. ชื่อ folder ของ project
  2. ชื่อ project หรือ file .csproj
  3. ชื่อ namespace 


ซึ่งไม่จำเป็นจะต้องเป็นชื่อเดียวกัน แต่ถ้าใครอยากจะแก้ให้ชื่อทั้งสามเป็นชื่อเดียวกัน ก็มีวิธีที่ไม่ได้ยากเย็นอะไร แต่ต้องเข้าใจ ดังนี้

1. แก้ชื่อ folder

วิธีคือ จะต้องแก้ชื่อ folder ตรงๆ เหมือนที่เราแก้ชื่อ folder ทั่วๆ ไป แต่...หลังจากที่เราแก้แล้ว ใน solution จะหา project นั้น ไม่เจอ แล้วมันจะยอมให้เราแก้ไข property project folder ซึ่งโดยปกติ มันจะไม่ให้เราแก้ไข เราก็แค่เลือก folder ที่เราแก้ไขชื่อให้ถูกต้องก็เป็นอันเสร็จ



2. แก้ไขชื่อ project หรือ file .csproj

ทั้งนี้ ชื่อ project ที่แสดงใน solution มันเหมือนจะดึงมาจากชื่อไฟล์ .csproj นั่นเอง ซึ่งอันนี้แก้ได้ง่ายๆ โดย click ขวาที่ชื่อ project แล้วก็เลือก rename ใส่ชื่อที่ต้องการก็เป็นอันเสร็จ


3. แก้ชื่อ namespace

คลิ๊กขวาที่ชื่อ project แล้วเลือก Properties ซึ่งจะแสดงหน้าต่างอีกอันหนึ่ง (ซึ่งไม่เข้าใจเหมือนกันว่า ทำไมไม่เป็นอันเดียวกับ properties windows แล้วแก้ไข Default namespace กันได้ (ทั้งนี้ปกติเราก็จะแก้ไข Assembly name ไปด้วย โดยเข้าใจว่า assembly name คือชื่อของ file .dll ที่เราจะได้ และก็จะแก้ไขเข้าไปถึง Assembly Information ด้วย)


ก็เป็นอันเสร็จเรียบร้อย

ปกติคุ้นกับ Eclipse ที่ rename ปุ๊บ มันแก้ทุกอย่างให้หมดเลย ทั้งนี้ .Net มันคงต้องการให้ยืดหยุ่นที่จะสามารถตั้งชื่อทุกอย่างแยกจากกันได้อ่ะมั้ง (กำลังพยายามเข้าใจมัน)

จบจ้า


TPSE 2014

เป็นอีกปีที่ไปมาค่ะ ปีนี้อาจจะไม่ประทับใจเท่าปีที่แล้ว เพราะว่าหลายเรื่องเราก็ติดตามผ่าน facebook และ blog อยู่บ้างแล้ว เลยเริ่มไม่ตื่นเต้นล่ะ

ปีนี้มี session ที่ได้ไปฟังมาวันแรกดังนี้

Agile Outsource

ซึ่งเป็นการทำ outsource แบบ Agile คือใกล้ชิดกันมากขึ้น และปรับการทำงานให้เป็น Agile นะเอง

Technical Debt

เมื่อก่อนเรางงคำนี้นะ ฟังครั้งแรกไม่ get แต่ในงานก็มีการแสดงตัวอย่างการใช้หนี้ได้ชัดเจนค่ะ แต่ถ้าใครอยากรู้จักแบบเริ่มต้น เราแนะนำ หนี้ทางเทคนิค Technical Debt มากกว่า


Case study, How to apply agile practice in government TOR design


เป็น session ที่เราได้เห็น Agile ในภาครัฐได้ดีมากขึ้น ฟังแล้วรู้เลยว่าผู้บรรยายมีประสบการณ์ตรง ประสบการณ์จริง โดยแนะนำให้เริ่มสร้าง TOR ด้วยการใช้ User Story + คะแนนความยากง่าย (ซึ่งจริงๆ เราว่าตอนประเมินความยากง่ายนี่คงตบตีกันแทบแย่เหมือนกัน แต่ก็อาจจะช่วยให้เจ้าของงานได้มองเห็นความจริง และช่วยแตก Story ได้ละเอียดขึ้น)


Test-Driven Development 101


เป็นการแนะนำการทำ TDD ค่ะ ซึ่งผู้บรรยาย blog ไว้ด้วย สรุปการแบ่งปันเรื่อง Test Driven Development ในงาน TPSE 2014



วันที่สอง

Measurement in an agile company

ผู้ถึงการวัดผลใน Agile ว่าจะวัดได้อย่างไร (อันนี้ไม่ค่อยตั้งใจฟังเท่าไรอ่ะ เพราะคิดว่ายังไงก็ยังไม่ได้ใช้หรอก เลยฟังผ่านๆ)

Project Manager Deadly Sins

เข้าใจว่าคนฟัง ตั้งใจพูดให้ PM ฟัง เผื่อให้รู้ตัวว่าตัวเองทำบาปอะไร ที่ทำให้เกิดผลกับงานบ้าง แต่คนฟังน่าจะ 70% เป็น dev อ่านะ PM ที่หนายจะมาฟัง

Wrong reasons to automate! 

เป็นความเข้าใจผิดของการนำ Automate (Test) มาใช้ ซึ่งฟังๆ แล้วสำหรับงานโปรเจคแบบ 1-2 ปี ที่คนทำงานมีอยู่ 4-5 คน ดูจะไม่ค่อยคุ้มทุนในการทำเท่าไร


ก็คร่าวๆ ก็ประมาณนี้ เรื่องที่ฟังส่วนใหญ่เป็นเรื่องที่เคยได้ยินจากที่ไหนสักแห่งมาแล้ว แต่ก็คิดว่าเป็นงานที่คุ้มที่จะไปอยู่ดี ก็ไปฟังชิวๆ หรือได้ถามเรื่องที่อยากถามทันที ก็ถือว่าคุ้มล่ะนะ

Reference:
TPSE 2014


.net unable to cast of type dbquery`1 [] to type objectquery

ช่วงนี้กำลังศึกษา .Net Entity Framework อยู่ค่ะ

แล้วก็เลยลองทำ ADO.Net Entity Framwork Quick Start ดูค่ะ

ก็ทำตามไปเรื่อยๆ แต่มาสะดุดเอาตรง (เราใช้ EF 6.1 ค่ะ ตามที่ได้ Nuget ออกมา)

this.departmentList.DataSource = ((ObjectQuery)departmentQuery).Execute(MergeOption.AppendOnly);


ซึ่งมี Exception ตอน runtime ค่ะ ซึ่งตามชื่อหัวข้อเลยค่ะ มัน cast จาก DbQuery ไป ObjectQuery ไม่ได้ ก็หาอยู่นานค่ะ เพราะก็เพิ่งจะอ่าน Quick Start อ่ะเน้อะ จะไปรู้เรื่องอะไร

สรุปเลยละกันค่ะ คือมัน cast ไม่ได้ค่ะ ถูกแล้ว เพราะ edmx มันสร้างเป็น DbSet ซึ่ง query ที่ได้จะเป็น DbQuery ก็ต้องใช้มันทั้งแบบนั้นค่ะ แต่แล้วใช้แบบนั้นมันใช้ยังไงฟร่ะ ก็หากันต่อไปค่ะ ก็มามั่วเองจนได้ ซึ่งที่ถูกควรจะเป็น

this.departmentList.DataSource = departmentQuery.ToList();

จึงแจ้งมาเผื่อใครจะเป็นเหมือนกัน

Reference:
ADO.Net Entity Framwork Quick Start

Entity Framework 4.1: Unable to cast from DbQuery to ObjectQuery

C# Format Item Syntax

สำหรับคนที่เพิ่งมาเรียนรู้ C# ใหม่ๆ เวลาเห็นคำสั่ง Console.Write หรือ Console.WriteLine (ซึ่งเราใช้มากสำหรับการทดสอบระบบ) อาจจะเห็น string แปลกๆ ที่อยู่ใน { } ซึ่งจะเขียน Format Item Syntax ซึ่งมี syntax ง่ายๆ คือ

{ index[,alignment][:formatString]}

index เป็น ลำดับของตัวแปรที่เป็น parameter ต่อท้ายมา
alignment ถ้าเป็น ค่าบวก คือชิดขวา ค่าลบ ชิดซ้าย
formatString ก็คือเป็น format ที่จะให้แสดงออกมานั้นเอง 

ตัวอย่าง


Console.Write("Name = {0}, hours = {1,1:hh}", myName, DateTime.Now);

{0} ก็จะแสดงเป็นค่าของ myName
{1:hh} จะแสดงเป็นค่า DateTime.Now โดยแสดงเป็น ชั่วโมง ชิดขวา

Reference:
Composite Formatting