Check dirty form

Question: Nên chọn cách quan lý dirty form nào?

C1) Chủ động: model sẽ tự kiểm tra và gọi kiểm tra trạng thái dirty của các thuộc tính con. Ưu: cài đặt đơn giản.
Khuyết: quá trình kiểm tra có thể lâu.

C2) Bị động: Các properties sẽ publish, và root sẽ subscribe các event đó.
Ưu: quá trình kiểm tra nhanh.
Khuyết: cài đặt phức tạp.

 

 

Lấy dữ liệu lên bao nhiêu là đủ?

Bài toán: Dạng master-detail, detail cho phép update. Vậy thông tin detail chứa bao nhiêu là đủ tốt: tất cả thông tin hay chỉ cần key là được?

Đề nghị:

C1: Thường theo lý thuyết sẽ chỉ cần key – thông tin detail sẽ load lên khi được chọn. Cách này được gì: load master tốn ít băng thông và nhanh. Mất gì: người dùng phải ngồi đợi load detail.

C2: Trong quá trình load master thì với mỗi detail, ngoài load key cần load thêm các thông tin cần thiết để cho phép cập nhật. Cách này giải quyết được các yếu điểm cách trên, nhưng cũng gây ra các hạn chế mà cách trên đã giải quyết.

Vậy dùng cách nào? Mình sẽ chọn cách 2 để cung cấp trãi nghiệm tốt hơn cho người dùng. Và có thể cải việc load master bằng cách:

  • Load và cache những thông tin chung (cache ở BE và FE).
  • Phân trang load master.

Cũng có thể chọn cách 1 nếu bạn phân tích được hành vi người dùng để dự đoán và load trước thông tin người dùng có thể sử dụng, đi đến. Đây là một bài toán đòi hỏi chi phí cao: nếu giải được bài toán này thì cách 1 vẫn tốt hơn so với cách 2.

[Dev Tip] Creating an Application with Yeoman aspnet generators

1) Visual Studio Code

Get Visual Studio Code from http://code.visualstudio.com

2) Homebrew

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

3) DNVM, Node, Yo, Generator-aspnet, and Bower

On OSX, run bellow statements in the Terminal

$ brew tap aspnet/dnx
$ brew update
$ brew install dnvm
$ source dnvm.sh
$ dnvm upgrade -u
$ brew install node
$ sudo npm install -g yo
$ npm install -g generator-aspnet
$ npm install -g bower grunt-cli gulp-cli

4) Move to your intented application folder to create new app with a chose template
$ yo aspnet
Choose a template project

$ dnu restore
$ dnu build
$ dnx . run for console projects
$ dnx . kestrel or $ dnx . web for web projects

[Dev Tip] Create new instant of Xamarin App on Mac

For some reason, you want to open some Xamarin solutions at same time. By default you can do that. There is a work around using applescript.

1) Open AppleScript Editor

2) write this sample statement

do shell script "open -n /Applications/Xamarin\\ Studio.app/"

3) Save it with type format is application.

4) run this file you will get a new Xamarin instant.

[Dev Tip] WIF SessionAuthenticationModule cookies across sub-domains

Sometime, you need support SSO among sub-domains. Beside set up WIF on each applications, using same machine key. But those apps still cannot use same cookie.

There is a solution for it: specify domain name before write session token to cookie:

var sessionToken = new SessionSecurityToken(principal);
FederatedAuthentication.SessionAuthenticationModule.CookieHandler.Domain = "domain.com";
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);

[Dev Tip] Remote debug

Sometime, you need to debug a program on a server or something like that and it doesn’t have an installed Visual Studio. Then how to debug that program?

1) On target machine

1.1) Install Remote Tools for Microsoft Visual Studio XXX with XXX is version of your VS.

1.2) run Remote Debugger

server

Note: It opens port 4018.

2) On you machine

2.1) Attach debug process

client1Note: 192.168.16.254 is target’s IP.

Choose your process which you want to debug. At here i debug IIS.

client2

Attach that process and debug. 🙂

Note: Modules windows, Load symbol

or

set up debug 1

[Dev Tip] Claim-based notes

#1) Set IsAuthenticated = true

The IIdentity interface has the IsAuthenticated property. This is typically set to true whenever you deal with implementations of that interface, e.g as soon as you set the Nameproperty of GenericIdentity, IsAuthenticated is automatically set to true. IIRC in WIF, as soon as a ClaimsIdentity had a claim, IsAuthenticated was set to true.

This has changed in .NET 4.5. It is now possible to create a ClaimsIdentity that has claims, but having IsAuthenticated set to false. Actually this is the default now, when you new upClaimsIdentity like this:

var id = new ClaimsIdentity(claims);

To have IsAuthenticated set to true, you need to specify an authentication type in the ctor:

var id = new ClaimsIdentity(claims, “Custom”);

#2) Claims principal

You don’t need to set the Thread.CurrentPrincipal because the session module will do this for you. You will need to access it through the HttpContext.Current.User because the Thread.Principal is usually set on a different thread than the one accessing your service because it is two different modules in IIS.

[Dev Tip] Tạo máy ảo từ máy ảo khác trên VMWare

Đôi khi có những trường hợp bạn muốn setup hệ thống để test một function hay solution gì đó. Và bạn quyết định dùng các máy ảo để triển khai và dùng VMWare. Vấn đề là chuẩn bị các máy ảo.

1) Cài mới tất cả các máy? Đôi khi nếu yêu cầu là các hệ điều hành giống nhau thì việc này là công việc trâu bò và tốt nhiều thời gian để ngồi cài từng máy một.

2) Vậy sao không cài một máy cơ sở rồi copy nó ra thành nhiều máy khác – dạng như copy/paste một file ra nhiều phiên bản. Cũng hay, nhưng có vẻ cơ bắp quá, và đôi khi bạn gặp hạn chế về dung lượng ổ cứng.

3) Có một cách hay hơn cách 2 – cũng clone nhưng ít tốn dung lượng bộ nhớ – linked clone.

Step 1) Cài một máy cơ sở – chứa tất cả các thành phần cần thiết của tất cả các máy.

Step 2) Tạo một snapshot cho nó

snapshotXong, tới đây mình đã hoàn tất các bước chuẩn bị.

Step 3) Tạo một máy mới dựa trên máy cơ sở đã tạo

Step 3.1) Chọn snapshot trên máy cơ sở > Clone

Step 3.2) Clone dạng linked

linked[Note] các thao tác không được nhắc đến là những thao tác cơ bản như chọn nơi lưu trữ, tên máy ảo mới,.. bạn tự làm. 🙂

Đến đây mình đã tạo được một máy ảo mới dạng linked tới máy ảo cơ sở. Mọi thay đổi trên máy ảo mới không có tác động gì đến máy ảo cơ sở. Xóa máy ảo cơ sở thì xem như những máy ảo kế thừa cũng không chạy được.

[Dev Tip] Compare two objects

Sometime, you need to compare objects. Beside of override the Equal(), GetHashCode() methods, which are for some domain rules.

If you must compare all properties of the object, then I suggest another way to get it done: using JSON.

You can serialize those objects and compare JSON results.


public static void AreEqualByJson(object expected, object actual, string message = "")
{
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.All
};

var expectedJson = JsonConvert.SerializeObject(expected, settings);
var actualJson = JsonConvert.SerializeObject(actual, settings);
Assert.AreEqual(expectedJson, actualJson, message);
}

[Dev Tip] The GetHashCode() and Equals() in the implemented IEqualityComparer interface

When you compare two objects using an EqualityComparer then the IEqualityComparer.Equals and IEqualityComparer.GetHashCode methods are used instead of the methods on the Key objects.

# Recall

Every object in .NET has an Equals method and a GetHashCode method.

The Equals method is used to compare one object with another object – to see if the two objects are equivalent.

The GetHashCode method generates a 32-bit integer representation of the object. Since there is no limit to how much information an object can contain, certain hash codes are shared by multiple objects – so the hash code is not necessarily unique.

A dictionary is a really cool data structure that trades a higher memory footprint in return for (more or less) constant costs for Add/Remove/Get operations. It is a poor choice for iterating over though. Internally, a dictionary contains an array of buckets, where values can be stored. When you add a Key and Value to a dictionary, the GetHashCode method is called on the Key. The hashcode returned is used to determine the index of the bucket in which the Key/Value pair should be stored.

When you want to access the Value, you pass in the Key again. The GetHashCode method is called on the Key, and the bucket containing the Value is located.

# Example

BoxEqualityComparer boxEqC = new BoxEqualityComparer(); 

Dictionary<Box, String> boxes = new Dictionary<Box, string>(boxEqC); 

Box redBox = new Box(100, 100, 25);
Box blueBox = new Box(1000, 1000, 25);

boxes.Add(redBox, "red"); 
boxes.Add(blueBox, "blue");