Thursday, October 25, 2007

Javascript Random Text

Following javascript is to create some mock contacts for UI testing purpose:
    function createMockContacts(contactNumber) {
        var contacts = new Array();
        for (var i = 0; i < contactNumber; i++) {
            var contact = new Object();
            contact.Name = randomText(8);
            contact.Company = randomText(16);
            contact.Phone = randomText(9, "phone");
            contact.Email = randomText(9, "email");
            contact.Address = randomText(20);
            contacts.push(contact);
        }
        return contacts;
    }
    function randomText(length, type) {
        if ( type == "phone") 
            var chars = "1234567890";
        else 
            var chars = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var text = "";
        for (var i = 0; i < length; i++) {
            text += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        if (type == "email" && text.length > 3)
            text = text.slice(0, 3) + "@" + text.slice(3) + ".com";

        return text;
    }
Return is an array of javascript objects:
 contacts[0].Name = "7k15zlQQ"
 contacts[0].Company = "sTOX2EVFhsBXJFIn"
 contacts[0].Phone = "881414055"
 contacts[0].Email = "3Ic@Adu2N3.com"
 contacts[0].Address = "lN3kSwJCJC3m7gC8zdZy" 
 contacts[1].Name = "IZYkS3gI"
 ...

Thursday, October 11, 2007

.NET Repository Pattern

Domain Driven Design (DDD) attracts quite a lot of attentions in recent years. Repository pattern is one important pattern in DDD. It mediates between the domain and data mapping layers, or a simple delegation of responsibility away from the domain objects.

Consider reading GeoCode from database, we may have following code:
public class GeoCode
{
public double Latitude;
public double Longitude;
public GeoCode(double lat, double lon)
{
Latitude = lat;
Longitude = lon;
}

public GeoCode GetByPostalCode(string postalCode)
{
GeoCode gc = null;
string connectionString = "....";
string sqlQuery = "SELECT Latitude, Longitude FROM GeoCode WHERE PostalCode = @PostalCode";
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand DBCommand = new SqlCommand(sqlQuery, connection);
DBCommand.Parameters.AddWithValue("@PostalCode", postalCode);
using (SqlDataReader reader = DBCommand.ExecuteReader())
{
if (reader.HasRows)
{
gc = new GeoCode(Convert.ToDouble(reader["Latitude"]), Convert.ToDouble(reader["Longitude"]));
}
}
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
return gc;
}
}
Such code works but it's not flexible and it has direct dependency to the backend store. With repository pattern we need to declare an interface and have a separate implementation:
public class GeoCode
{
public double Latitude;
public double Longitude;
public GeoCode(double lat, double lon)
{
Latitude = lat;
Longitude = lon;
}
}

public interface IGeoCodeRepository
{
GeoCode GetByPostalCode(string postalCode);
}

public class SQLServerGeoCodeRepository : IGeoCodeRepository
{
private string ConnectionString;
public SQLServerGeoCodeRepository()
{
ConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
}
public SQLServerGeoCodeRepository(string connectionString)
{
ConnectionString = connectionString;
}

public GeoCode GetByPostalCode(string postalCode)
{
GeoCode gc = null;
string sqlQuery = "SELECT Latitude, Longitude FROM GeoCode WHERE PostalCode = @PostalCode";
try
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand DBCommand = new SqlCommand(sqlQuery, connection);
DBCommand.Parameters.AddWithValue("@PostalCode", postalCode);
using (SqlDataReader reader = DBCommand.ExecuteReader())
{
if (reader.HasRows)
{
gc = new GeoCode(Convert.ToDouble(reader["Latitude"]), Convert.ToDouble(reader["Longitude"]));
}
}
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
return gc;
}
}
A wrapper class in service layer exposes all related functions:
public class GeoCodeService
{
private IGeoCodeRepository _repository;
public GeoCodeService(IGeoCodeRepository repository)
{
_repository = repository;
}

public GeoCode GetByPostalCode(string postalCode)
{
return _repository.GetByPostalCode(postalCode);
}
}

class Program
{
static void Main(string[] args)
{
IGeoCodeRepository repository = new SQLServerGeoCodeRepository();
GeoCodeService service = new GeoCodeService(repository);
GeoCode gc = service.GetByPostalCode("A1A1A1");
}
}
With repository pattern we can easily extend current implementation. For example, if we need to use web service to get the geo code, we can simply add a new implementation without changing any existing code:
public class WebServiceGeoCodeRepository : IGeoCodeRepository
{
private string WebServiceUrl;
public WebServiceGeoCodeRepository()
{
WebServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"];
}
public WebServiceGeoCodeRepository(string webServiceUrl)
{
WebServiceUrl = webServiceUrl;
}

public GeoCode GetByPostalCode(string postalCode)
{
GeoCode gc = null;
//Get GeoCode by web service
return gc;
}
}

public class Program
{
static void Main(string[] args)
{
IGeoCodeRepository repository = new WebServiceGeoCodeRepository();
GeoCodeService service = new GeoCodeService(repository);
GeoCode gc = service.GetByPostalCode("A1A1A1");
}
}
The other advantage of using repository pattern is the testability. For example we can create a fake data repository:
public class FakeGeoCodeRepository : IGeoCodeRepository
{
public GeoCode GetByPostalCode(string postalCode)
{
GeoCode gc = null;
double fakeCode = 111.111;
if (postalCode.StartsWith("A", StringComparison.InvariantCultureIgnoreCase))
fakeCode = 123.123;
gc = new GeoCode(fakeCode, fakeCode);
return gc;
}
}
The unit test becomes simple:
 [TestMethod()]
public void GetByPostalCodeTest()
{
IGeoCodeRepository repository = new FakeGeoCodeRepository();
GeoCodeService target = new GeoCodeService(repository);
string postalCode = "M1M1M1";
double expected = 111.111;
GeoCode actual;
actual = target.GetByPostalCode(postalCode);
Assert.AreEqual(expected, actual.Latitude);
Assert.AreEqual(expected, actual.Longitude);

postalCode = "A1A1A1";
expected = 123.123;
actual = target.GetByPostalCode(postalCode);
Assert.AreEqual(expected, actual.Latitude);
Assert.AreEqual(expected, actual.Longitude);
}
Related topics:
http://martinfowler.com/eaaCatalog/repository.html
http://martinfowler.com/articles/injection.html

Wednesday, September 26, 2007

ASP.NET Impersonate Application Pool Account To Access Database

In an ASP.NET web application, we use a fixed account to connect to SQL server. Although we could encrypt the user name and password in the connection string, admin still suggested to use Windows Authentication so that there's no any user credential information stored in the file system.

One simple way to achieve that is create an application pool for the web app with a service account, and grant the permission for that service account inside the SQL server, then wrap all ADO.NET code inside a System.Web.Hosting.HostingEnvironment.Impersonate() block:
    using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
using (SqlConnection connection = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(spStoredProcedureName, connection);
//... other ADO.NET code
}
}

Thursday, August 02, 2007

Array.ConvertAll and List.ConvertAll

Just noticed this handy method:
using System;
using System.Collections.Generic;

class Test
{
static void Main()
{
int[] numbers = new int[] { 65, 66, 67 };
char[] chars = Array.ConvertAll(numbers, delegate(int number)
{ return (char)number; });

//Print "ABC"
Array.ForEach(chars, delegate(char ch) { Console.Write(ch); });

Console.WriteLine();
List<int> numberList = new List<int>(numbers);
List<char> charList = numberList.ConvertAll(delegate(int number)
{ return (char)number; });

//Print "ABC"
charList.ForEach(delegate(char ch) { Console.Write(ch); });

Console.Read();
}
}

Saturday, July 07, 2007

Singleton Pattern - A Logger Example

The idea of a singleton is to have a class that has only one instance and a global point of access to the instance. Following code is a simple singleton C# implementation:
public class Singleton
{
private static Singleton instance = new Singleton();

private Singleton() { }

public static Singleton GetInstance()
{
return instance;
}
}
The above implementation creates a new static instance during the class initialization. The singleton instance is retrieved by a static GetInstance method. An alternative is expose the singleton object by read-only property without a setter. The code needs a little bit change if a lazy creation is required:
public class Singleton
{
private static volatile Singleton instance;
private static object syncObj = new Object();

private Singleton() {}

public static Singleton GetInstance()
{
if (instance == null)
{
lock (syncObj)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
SyncLock in above code is for thread-safe consideration. In addition, the singleton class could be sealed if you don't like people to inherit from it and break the singleton principle.

Singleton pattern is very useful in some use cases. Here's a real life example. I needed a file logger for a simple web service application used in a small company. Enterprise library, logging application block, and even log4Net are just too heavy for such small application. In addition, the client is rejective to third-party tools.

I decided to write a file logger by myself. A stream writer was used, but I don't want multiple instances of stream writers being created and used at the same time. The IO is expensive and multiple accesses to a single file is not safe. Singleton came to play and only one instance of logger and one stream writer is created:
using System;
using System.IO;
using System.Configuration;
using System.Diagnostics;

class Program
{
static void Main(string[] args)
{
Logger.WriteLog("Jus a test.");
Logger.WriteLog(LogSeverity.Info, "Another test.");
Console.Read();
}
}

// A helper static class to get access the logger
public static class Logger
{
private static readonly FileLogger _logger = FileLogger.GetInstance();

public static void WriteLog(String log)
{
_logger.Write(log);
}
public static void WriteLog(LogSeverity logLevel, String log)
{
_logger.Write(logLevel, log);
}
}

// Enumeration for log severity
public enum LogSeverity { Error, Warning, Info, Debug };

// FileLogger class with Singleton pattern
internal sealed class FileLogger : IDisposable
{
private static FileLogger _instance = null; // Singleton object
private static object _syncLock = new object(); // Sync lock

internal StreamWriter _writer; // Stream writer writting to the log file
internal string _path = "C:\\Logs"; // Default folder
internal string _absolutePath; // C:\Logs\MachineName.log
internal string _fileName; // MachineName.log
internal int _logFileSize = 2; // New log file when its size bigger than 2 MB
internal LogSeverity _defaultSeverity = LogSeverity.Error; // Default severity

// Private constructor
private FileLogger()
{
GetConfigSettings();

_fileName = string.IsNullOrEmpty(Environment.MachineName) ?
"LogFile.log" : Environment.MachineName + ".log";
_absolutePath = _path + "\\" + _fileName;

if (!Directory.Exists(_path))
{
Directory.CreateDirectory(_path);
}

_writer = new StreamWriter(_absolutePath, true);
}

// Public static method to get Singleton object
public static FileLogger GetInstance()
{
if (_instance == null)
{
lock (_syncLock)
{
if (_instance == null)
{
_instance = new FileLogger();
}
}
}
return _instance;
}

// Check if the log file exceeds the maximum size
private void CheckFileSize()
{
if (_writer.BaseStream.Length >= (_logFileSize * 1024 * 1024))
{
this.Dispose();
string backupFile = string.Format("{0}\\{1}-{2}.log",
_path, Environment.MachineName, DateTime.Now.ToString("yyyyMMdd-HHmmsss"));
try
{
while (File.Exists(backupFile))
{
backupFile = backupFile.Replace(".log", "_1.log");
}
File.Move(_absolutePath, backupFile);
this.Dispose();
_writer = new StreamWriter(_absolutePath, true);
}
catch (Exception ex)
{
WriteToEventLog(ex.Message);
}
}
}

// Get default setting from configuraiton file
private void GetConfigSettings()
{
string appSetting = ConfigurationManager.AppSettings["FileLogger_Path"];
if (!string.IsNullOrEmpty(appSetting))
{
_path = appSetting;
}
int maxFileSize;
appSetting = ConfigurationManager.AppSettings["FileLogger_MaxFileSizeInMB"];
if (!string.IsNullOrEmpty(appSetting) && int.TryParse(appSetting, out maxFileSize))
{
_logFileSize = maxFileSize;
}
appSetting = ConfigurationManager.AppSettings["FileLogger_DefaultSeverity"];
if (!string.IsNullOrEmpty(appSetting))
{
try
{
_defaultSeverity = (LogSeverity)Enum.Parse(typeof(LogSeverity), appSetting);
}
catch (Exception ex)
{
WriteToEventLog(ex.Message);
}
}
}

// Clean up the stream writer
public void Dispose()
{
lock (_syncLock)
{
if (_writer != null)
{
_writer.Dispose();
}
}
}

// Write with default log severity
public void Write(string msg)
{
Write(_defaultSeverity, msg);
}

// Write message to log file
public void Write(LogSeverity logSeverity, string msg)
{
lock (_syncLock)
{
try
{
if (_writer.BaseStream == null)
{
_writer = new StreamWriter(_absolutePath, true);
}
CheckFileSize();
_writer.WriteLine("[{0}] at {1} -- {2}",
logSeverity.ToString(), DateTime.Now.ToString(), msg);
_writer.Flush();
}
catch (Exception ex)
{
WriteToEventLog(ex.Message);
}
}
}

private void WriteToEventLog(string message)
{
string source = "Logger";
string log = "Application";

try
{
if (!EventLog.SourceExists(source))
EventLog.CreateEventSource(source, log);

EventLog.WriteEntry(source, message, EventLogEntryType.Error);
}
catch { }
}
}

Thursday, May 10, 2007

.NET Interface Serialization Issue

Interface can not be serialized or de-serialized. That's because interface is just a contract not detailed implementation. However, in some cases, we do want to expose interface so objects are not restricted by a specific type.

Look at a simple example:
    public interface IPriceable
{
double GetPrice();
}
[Serializable]
public class ProductA : IPriceable
{
public double GetPrice()
{
return 123.345;
}
}

[Serializable]
public class ProductB : IPriceable
{
public double GetPrice()
{
return 234.567;
}
}

[Serializable]
public class PromotionPackage
{
public List<IPriceable> Items = new List<IPriceable>();
double GetPromotePrice()
{
//return PromotionCaculator.GetPrice(_items);
return 567.89; ;
}
}
The PromotionPackage contains a list of IPriceable objects (ProductA, ProductB etc.). Everything is okay except that an exception will be thrown when we serialize the PromotionPackage object:
{"Cannot serialize member PromotionPackage.Items of type IPriceable because it is an interface."}
A workaround would be wrapping the interface to an abstract class:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

public class Program
{
public interface IPriceable
{
double GetPrice();
}

[XmlInclude(typeof(ProductA))]
[XmlInclude(typeof(ProductB))]
public abstract class ProductBase : IPriceable
{
public abstract double GetPrice();
}

[Serializable]
public class ProductA : ProductBase
{
public override double GetPrice()
{
return 123.345;
}
}

[Serializable]
public class ProductB : ProductBase
{
public override double GetPrice()
{
return 234.567;
}
}

[Serializable]
public class PromotionPackage
{
public List<ProductBase> Items = new List<ProductBase>();
double GetPromotePrice()
{
//return PromotionCaculator.GetPrice(_items);
return 567.89; ;
}
}

static void Main(string[] args)
{
PromotionPackage package = new PromotionPackage();
package.Items.Add(new ProductA());
package.Items.Add(new ProductB());

string xmlString = string.Empty;
XmlSerializer serializer = new XmlSerializer(typeof(PromotionPackage));

// Serialize
using (StringWriter sw = new StringWriter())
{
serializer.Serialize(sw, package);
xmlString = sw.ToString();
}

// De-serialize
PromotionPackage newPackage = null;
using (StringReader sr = new StringReader(xmlString))
{
XmlTextReader reader = new XmlTextReader(sr);
newPackage = (PromotionPackage)serializer.Deserialize(reader);
}

Console.WriteLine("Done.");
Console.Read();
}
}

Saturday, May 05, 2007

A Managed Way To Serialize & Deserialze DateTime field

public class MyEvent
{
public string Name;

[XmlIgnore]
public DateTime Time;
[XmlElement("Time")]
public string TimeString
{
get { return Time.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); }
set { Time = DateTime.ParseExact(value, "yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); }
}

public MyEvent() { }
public MyEvent(string name, DateTime time)
{
Name = name;
Time = time;
}

static void Main(string[] args)
{
MyEvent evt = new MyEvent("event1", new DateTime(2007, 5, 5));

XmlSerializer serializer = new XmlSerializer(typeof(MyEvent));
TextWriter writer = new StreamWriter(@"c:\event.xml");
serializer.Serialize(writer, evt);
writer.Close();
}
}
Here TimeString is exposed as a public property. Can we make it private? The answer is yes, but it requires the DataContract new in .NET 3.0:
[DataContract]
public class MyEvent
{
[DataMember]
public string Name;

public DateTime Time;

[DataMember(Name="Time") ]
private string TimeString
{
get { return Time.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); }
set { Time = DateTime.ParseExact(value, "yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture); }
}

public MyEvent(string name, DateTime time)
{
Name = name;
Time = time;
}

static void Main(string[] args)
{
MyEvent evt = new MyEvent("event1", new DateTime(2007, 5, 5));

DataContractSerializer serializer = new DataContractSerializer(typeof(MyEvent));
XmlWriter writer = XmlWriter.Create(@"c:\event.xml");
serializer.WriteObject(writer, evt);
writer.Close();
}
}

Monday, April 16, 2007

.NET Class Library Get Configuration File

A class library is used by different kind of applications, like a test console, a WinForm or Web applications. And the class library needs to read a configuration file at run time. How to do that? The common way is copy the configuration file to the folder where the class library assembly is sitting. Then the configuration file can be located by reflection at run time. But this doesn't work in ASP.NET web site environment because of the .NET dynamic compilation process. One resolution is to handle the path differently in web environment. Let's say if We have a convention of copying the configuration file to the root folder of web site, then the code to retrieve the full path of configuration file is like:
    public static string GetConfigurationFile(string fileName)
{
string asmLocation = Assembly.GetExecutingAssembly().Location;
string asmFolder = asmLocation.Substring(0, asmLocation.LastIndexOf(@"\"));
string fileFullPath = asmFolder + @"\" + fileName;

// Fix the temporary folder issue when running in web environment
if (fileFullPath.Contains(@"\Microsoft.NET\Framework"))
{
fileFullPath = System.Web.Hosting.HostingEnvironment.MapPath("/") + fileName;
}

return fileFullPath;
}
(Updated 2008/2) Another easy way to get configuration file is using AppDomain.CurrentDomain.SetupInformation.ConfigurationFile property which maps to app.config for Cosole/WinForm applications, and maps to web.config in ASP.NET.

Tuesday, April 03, 2007

StringDictionary, NameValueCollection, Dictionary<TKey, TValue> and KeyedCollection<TKey, TItem>

How to store key/value data in .NET?

DictionaryEntry in .NET 1.0 and generic KeyValuePair<TKey, TValue> in .NET 2.0 both store key/value pair inside a struct (not class). How about many KeyValue pairs? One solution is to put Key/value objects inside a collection like Generic List. But there's a major problem of such use: search by key is expensive and you need to loop through the whole collection. HashTable is fast in search but it's limited to string/object pair, and it's not strongly typed.

Are there any out-of-box strongly-typed collections for key/value objects?

If the key and value both are strings, StringDictionary and NameValueCollection are options. They have been available since .NET 1.0 and both are under System.Collections.Specialized name space. The difference is that NameValueCollection can have duplicate keys (multiple values for the same key are allowed).

In .NET 2.0 we have generic Dictionary<TKey, TValue> that is efficient and easy to use. More importantly the key and value objects can be of any types, and are strongly typed. But one issue of generic dictionary is that it can not be serialized directly. Paul Welter provided a SerializableDictionary solution for the problem but it's just a workaround. The other drawback of generic dictionary is that index accessing is not supported.

Generic KeyedCollection<TKey, TItem> under System.Collections.ObjectModel name space does not have those two issues on generic dictionary. KeyedCollection<TKey, TItem> supports index and key search, just like a hybrid version of generic List and Dictionary. But KeyedCollection<TKey, TItem> is just an abstract class, and you have to inherit from it and implement at least one abstract method to tell what's the key in each object inside the collection:
protected abstract TKey GetKeyForItem(TItem item);
Following is a demo of how to use KeyedCollection, where the EmployeeCollection uses employee number as a key:
using System;
using System.Text;
using System.Collections.ObjectModel;

class Program
{
static void Main()
{
EmployeeCollection ec = new EmployeeCollection();
ec.Add(new Employee("123456", "Rob", 40));
ec.Add(new Employee("234567", "Steve", 45));

bool contained = ec.Contains("123456");
ec["123456"].Age = 44;
ec[1].Age = 45;

Console.Read();
}
public class Employee
{
public Employee(string empNumber, string name, int age)
{
EmployeeNumber = empNumber;
Name = name;
Age = age;
}
public string EmployeeNumber;
public string Name;
public int Age;
// other properties and memebers
}

public class EmployeeCollection : KeyedCollection<string, Employee>
{
protected override string GetKeyForItem(Employee item)
{
return item.EmployeeNumber;
}
}
}

Thursday, March 29, 2007

Thread Safety In .NET Collections

Most .NET collections are not thread-safe. Take generic list as an example, the MSDN description is as following:

Thread Safety

Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

A List<T> can support multiple readers concurrently, as long as the collection is not modified. Enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with one or more write accesses, the only way to ensure thread safety is to lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

So we need to implement read/write locks in multi-threaded environment when the list objects are modified. That's a lot of extra work and is prone to deadlock in a complicate system.

Is there any easy way on this? Can we build a new collection and switch the list reference to the new constructed collection? Following code demos such approach:
using System;
using System.Collections.Generic;
using System.Threading;

class Test
{
public class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}

private static List<Person> _personList = new List<Person>();
static void Main()
{
// Build initial list
for (int i = 0; i < 10; i++)
{
_personList.Add(new Person("Name" + i.ToString(), i));
}

new Thread(new ThreadStart(LoopthroughList)).Start();

//Following thread will throw InvalidOperationException:
//Exception: Collection was modified; enumeration operation may not execute.
//new Thread(new ThreadStart(UpdateListUnsafely)).Start();

// Following thread won't throw exception
new Thread(new ThreadStart(UpdateListSafely)).Start();

Console.Read();
}

static void LoopthroughList()
{
Console.WriteLine("First loop");
foreach (Person person in _personList)
{
Console.WriteLine("ListHashCode:{0} ListCount:{1} Name:{2} Age:{3}",
_personList.GetHashCode(), _personList.Count, person.Name, person.Age);
Thread.Sleep(100);
}
Console.WriteLine("Second loop");
foreach (Person person in _personList)
{
Console.WriteLine("ListHashCode:{0} ListCount:{1} Name:{2} Age:{3}",
_personList.GetHashCode(), _personList.Count, person.Name, person.Age);
}
}

static void UpdateListUnsafely()
{
Thread.Sleep(500);
_personList.RemoveAt(_personList.Count - 1);
_personList.Add(new Person("A New Person", 20));
}

static void UpdateListSafely()
{
Thread.Sleep(500);
List<Person> newList = new List<Person>(_personList);
newList.RemoveAt(newList.Count - 1);
newList.RemoveAt(newList.Count - 1);
newList[newList.Count - 1].Name = "Modified Name";
newList.Add(new Person("A New Person", 20));
_personList = newList;
Console.WriteLine("List updated! ListCount:{0}", _personList.Count);
}
}
Result:
The result looks promising. We don't see any error when switching the reference (theoretically we should lock this operation). Is such implementation really thread-safe now? Maybe yes maybe no. The problem is that I couldn't find an official answer from Microsoft.

Thursday, March 15, 2007

ASP.NET Find Control Recursively

Sometimes we need to get a control instance inside a page. Looking up each control recursively is the easiest way:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoginInfoUserControl loginControl = FindControl<LoginInfoUserControl>(this.Page, "ucLogin");
}

public static T FindControl<T>(Control root, string controlID) where T : class
{
if (root is T && root.ID == controlID)
{
return root as T;
}
foreach (Control control in root.Controls)
{
T foundControl = FindControl<T>(control, controlID);
if (foundControl != null)
{
return foundControl;
}
}
return null;
}
}

Wednesday, March 07, 2007

HttpWebRequest With Cookie Context

I was doing some load test on an ASP.NET page. The page uses Cache to store some profile data, and the Cache is associated with the client Cookie value. The load test tools I have don't have such dynamic cookie assignment functionality. So I created a simple load test tool for this. The key point is to assign the CookieContainer property of the HttpWebRequest object:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace HttpRequestTest
{
class Program
{
static void Main(string[] args)
{
string url = "http://localhost/MyDashBoard.aspx";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
CookieContainer cookieContainer = new CookieContainer();
Cookie cookie = new Cookie("cookieKey", "cookieValue");
cookie.Path= "/";
cookie.Domain = "localhost";
cookieContainer.Add(cookie);
request.CookieContainer = cookieContainer;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseData = response.GetResponseStream();
StreamReader reader = new StreamReader(responseData);
string responseFromServer = reader.ReadToEnd();

Console.Read();

}
}
}

Thursday, February 22, 2007

ICollection<T>, IList<T>, CollectionBase, Collection<T> And List<T>

.NET provides all these interfaces and classes. What is the difference between them?

They all inherit/implement IEnumerable interface, and support simple iteration over the collection.

ICollection<T> interface is the simplest one. It only inherits IEnumerable interface and includes just a few members.

IList<T> interface inherits ICollection<T> interface, and it offers you the ability to index an element. So go IList<T> if you need indexing.

CollectionBase is an abstract class inheriting from ICollection and IList interfaces. It's a recommanded way of using it to implement a custom collection before .NET 2.0, derive a class from it and you get all functions implemented by CollectionBase.

Collection<T> is a concrete implementation of ICollection<T> and IList<T>. It's better than CollectionBase because it's a generic collection and supports all new generic features.

List<T> class also implements both ICollection<T> and IList<T>. It has more power than Collection<T>. Collection<T> exposes about 10 methods, while List<T> exposes more than 40 methods. You are able to do sorting and search by default with List<T>.

List<T> has more functions, but too much implementation limits its extensibility. In general, use Collection<T> for public APIs, and use List<T> for internal containers.

An example of Collection<T> more extensible than List<T> is that Collecton<T> has virtual methods so you can override them and have your own handling logic when an item is inserted and updated inside the container:
    protected virtual void ClearItems();
protected virtual void InsertItem(int index, T item);
protected virtual void RemoveItem(int index);
protected virtual void SetItem(int index, T item);
Some people argue that interface is better because it only provides the contract and the detailed implementation is not exposed, and returning IList<T> or ICollection<T> are better Collection<T> or List<T>, in addition you can not inherit your custom class once it deriving from concrete class like collection<T> or List<T>. That's true, but other people debate that returning interface without functions to end users is useless, what's the point you expose a collection of objects without some basic functions like search and sorting? That's also valid. It really depends on the real situation and use case.

Related interface/class definition:
    public interface IEnumerable
{
IEnumerator GetEnumerator();
}

public interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

public interface ICollection<T> : IEnumerable<T>, IEnumerable
{
bool IsReadOnly { get; }
void Add(T item);
void Clear();
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
bool Remove(T item);
}

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
T this[int index] { get; set; }
int IndexOf(T item);
void Insert(int index, T item);
void RemoveAt(int index);
}

public abstract class CollectionBase : IList, ICollection, IEnumerable
{
protected CollectionBase();
protected CollectionBase(int capacity);
public int Capacity { get; set; }
public int Count { get; }
protected ArrayList InnerList { get; }
protected IList List { get; }
public void Clear();
public IEnumerator GetEnumerator();
protected virtual void OnClear();
protected virtual void OnClearComplete();
protected virtual void OnInsert(int index, object value);
protected virtual void OnInsertComplete(int index, object value);
protected virtual void OnRemove(int index, object value);
protected virtual void OnRemoveComplete(int index, object value);
protected virtual void OnSet(int index, object oldValue, object newValue);
protected virtual void OnSetComplete(int index, object oldValue, object newValue);
protected virtual void OnValidate(object value);
public void RemoveAt(int index);
}

public class Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
public Collection();
public Collection(IList<T> list);
public int Count { get; }
protected IList<T> Items { get; }
public T this[int index] { get; set; }
public void Add(T item);
public void Clear();
protected virtual void ClearItems();
public bool Contains(T item);
public void CopyTo(T[] array, int index);
public IEnumerator<T> GetEnumerator();
public int IndexOf(T item);
public void Insert(int index, T item);
protected virtual void InsertItem(int index, T item);
public bool Remove(T item);
public void RemoveAt(int index);
protected virtual void RemoveItem(int index);
protected virtual void SetItem(int index, T item);
}

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
public List();
public List(IEnumerable<T> collection);
public List(int capacity);
public int Capacity { get; set; }
public int Count { get; }
public T this[int index] { get; set; }
public void Add(T item);
public void AddRange(IEnumerable<T> collection);
public ReadOnlyCollection<T> AsReadOnly();
public int BinarySearch(T item);
public int BinarySearch(T item, IComparer<T> comparer);
public int BinarySearch(int index, int count, T item, IComparer<T> comparer);
public void Clear();
public bool Contains(T item);
public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter);
public void CopyTo(T[] array);
public void CopyTo(T[] array, int arrayIndex);
public void CopyTo(int index, T[] array, int arrayIndex, int count);
public bool Exists(Predicate<T> match);
public T Find(Predicate<T> match);
public List<T> FindAll(Predicate<T> match);
public int FindIndex(Predicate<T> match);
public int FindIndex(int startIndex, Predicate<T> match);
public int FindIndex(int startIndex, int count, Predicate<T> match);
public T FindLast(Predicate<T> match);
public int FindLastIndex(Predicate<T> match);
public int FindLastIndex(int startIndex, Predicate<T> match);
public int FindLastIndex(int startIndex, int count, Predicate<T> match);
public void ForEach(Action<T> action);
public List<T>.Enumerator GetEnumerator();
public List<T> GetRange(int index, int count);
public int IndexOf(T item);
public int IndexOf(T item, int index);
public int IndexOf(T item, int index, int count);
public void Insert(int index, T item);
public void InsertRange(int index, IEnumerable<T> collection);
public int LastIndexOf(T item);
public int LastIndexOf(T item, int index);
public int LastIndexOf(T item, int index, int count);
public bool Remove(T item);
public int RemoveAll(Predicate<T> match);
public void RemoveAt(int index);
public void RemoveRange(int index, int count);
public void Reverse();
public void Reverse(int index, int count);
public void Sort();
public void Sort(Comparison<T> comparison);
public void Sort(IComparer<T> comparer);
public void Sort(int index, int count, IComparer<T> comparer);
public T[] ToArray();
public void TrimExcess();
public bool TrueForAll(Predicate<T> match);

public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
public T Current { get; }
public void Dispose();
public bool MoveNext();
}
}

Friday, February 09, 2007

Binding Enum Type In .NET

Enum type is not bindable to list controls such as DropDownList and CheckBoxList, because Enum is not IEnumerable, IListSource or IDataSource type. One solution is put enum data to an IEnumerable collection such as generic dictionary, and then bind the list control to that collection. Following code demos such usage:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
BindableEnum.BindListControl<Status>(DropDownList1);
}
}

public enum Status
{
NotAvailable = 0,
Pending = 3,
InProgress = 4,
Completed = 5,
Aborted = 6
}

public static class BindableEnum
{
public static void BindListControl<TEnum>(ListControl list)
{
if (typeof(TEnum).BaseType != typeof(Enum))
return;

Dictionary<string, string> enumDict = new Dictionary<string, string>();
string[] names = Enum.GetNames(typeof(TEnum));
for (int i = 0; i < names.Length; i++)
{
enumDict.Add(names[i], ((int)Enum.Parse(typeof(TEnum), names[i])).ToString());
}
list.DataSource = enumDict;
list.DataTextField = "Key";
list.DataValueField = "Value";
list.DataBind();
}
}

Thursday, January 18, 2007

Automatic Properties Issue On Structs

In general, class objects are allocated on the heap while structs are created on the stack, reference vs. value for short. Their syntax is almost identical, but I found one issue using struct today. Following C# code doesn't compile in Visual Studio 2005:
    struct GeoCode
{
public double Longitude { get; set; }
public double Latitude { get; set; }

public GeoCode(double longitude, double latitude)
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}
The error is:

Backing field for automatically implemented property 'Program.GeoCode.Latitude' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer ...

And:
The 'this' object cannot be used before all of its fields are assigned to ...
It's okay with:
    struct GeoCode
{
public double Longitude;
public double Latitude;

public GeoCode(double longitude, double latitude)
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}
Sounds like the issue of automatic properties on structs in .NET 2.0. To fix it, just follow the error description "Consider calling the default constructor from a constructor..":
    struct GeoCode
{
public double Longitude { get; set; }
public double Latitude { get; set; }

public GeoCode(double longitude, double latitude) : this()
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}

Friday, January 05, 2007

A tricky int i=0; i=i++; i = ? question

I was asked a question that sounds simple but it's a bit tricky. What's the output of following C# code?
public class Program
{
static void Main(string[] args)
{
int i = 0; i = i++;
int j = 0; j = ++j;
Console.WriteLine("{0} {1}", i, j);
Console.Read();
}
}
I thought it's "1 1" but I was wrong. The correct answer is "0 1".

Why? i++ is an after operation, so a temporary value is created to store the before and after value. The explanation is not that straightforward. Let's look at the IL code generated by compiler, and see what's under the hood:
.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 47 (0x2f)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop

// i operation
IL_0001: ldc.i4.0 // Put constant number 0 onto the stack
IL_0002: stloc.0 // Pop from the stack and store it in the local variable #0 (number = 0)
IL_0003: ldloc.0 // Push local variable #0 onto the stack
IL_0004: dup // Duplicate the value in the stack (push another 0 onto stack)
IL_0005: ldc.i4.1 // Put constant number 1 onto the stack
IL_0006: add // Pop last two values from stack and push back their sum (1+0=1)
IL_0007: stloc.0 // Pop from stack and store it to local variable #0 (number=1)
IL_0008: stloc.0 // Pop from stack and store it to local variable #0 (overwritten number=0)

// j operation
IL_0009: ldc.i4.0 // put constant number 0 onto the stack
IL_000a: stloc.1 // Pop from the stack and store it in the local variable #1 (number=0)
IL_000b: ldloc.1 // Push local variable #1 onto the stack
IL_000c: ldc.i4.1 // Put constant number 1 on the stack
IL_000d: add // Pop last two values from stack and push back their sum (1+0=1)
IL_000e: dup // Duplicate the value in the stack (push another 1 onto stack)
IL_000f: stloc.1 // Pop from the stack and store it to local variable #1 (number=1)
IL_0010: stloc.1 // Pop from the stack and store it to local variable #1 (number=1)

// Print
IL_0011: ldstr "{0} {1}"
IL_0016: ldloc.0 // Load local variable #0 (0) onto stack
IL_0017: box [mscorlib]System.Int32
IL_001c: ldloc.1 // Load local variable #1 (1) onto stack
IL_001d: box [mscorlib]System.Int32
IL_0022: call void [mscorlib]System.Console::WriteLine(string,
object,
object)
IL_0027: nop
IL_0028: call int32 [mscorlib]System.Console::Read()
IL_002d: pop
IL_002e: ret
} // end of method Program1::Main
We can see that the plus operation is run in a separate stack, the result of 1 is assigned to the local variable, but is overwritten by original value of 0. Thus the original i value of 0 is used for the assignment of i = i++. Is it ambiguous? I'm not sure. It's the way how .NET deals with such scenarios.

(Updated Jan 7, 07) I tested in Java (1.5) and got the same result of "0 1". But in C++ (compiled by VS.NET 2005) it returns "1 1".