Thursday, October 26, 2006

ApplicationSettingsBase in .NET 2.0

The new namespace called System.Configuration and a class in that namespace called ApplicationSettingsBase that will be your new friend when dealing with this issue.

Before we dive into this topic more, a word here from experience with this class - it's remarkably easy and convienent to use as long as you take a few extra steps yourself. I don't give the issue of creating settings a moments thought anymore since this class was released in .NET 2.0.

Now, let's see why...

The first conundrum that a developer faces (and has always faced) when dealing with settings is where to put the data that needs persisting. In the Win32 world and even .NET 1.x, it was common to resort to the in-famous Registry to store application data. You basically have a choice - store it in the per-user area (Current User), or the per-machine area (Local Machine). The latter has additional restrictions in that you need read/write access to the registry keys that you want to edit there and a low rights user account may not have such access. It also can be problematic since there is one set of data there for all users which can complicate data that needs to be per-user.

The Registry also has another glaring deficiency (besides being easily corrupted and hard to edit) - there is no support for format changes to the data being stored. Imagine v1.0 of your glorious application shipped and had several setting entries. A few months go by and you ready v1.1 to ship to customers. You found the need to add some entries to your set and remove a few. You also decide to store these entries in a different registry subfolder. It's pretty much left to you to spend time writing a conversion/migration routine. Even worse, as versions of your application proliferate, you have to continue to update that conversion code to handle everything back to v1.0 so that any stragglers in your user base and get up to your latest version.

What a pain.

This is a place the Microsoft thought long and hard about when they devised ApplicationSettingsBase (which rumor has it derived from some excellent work done in the Microsoft Patterns & Practices group in the famous code "blocks"). ApplicationSettingsBase is one of those swiss army knives that allows a developer to handle how settings are stored, or leave it to the class to handle it on behalf of the developer. The latter is by far the most common and likely approach for most teams. Why spend time writing plumbing code when you can leave it to Microsoft? By default, ApplicationSettingsBase generates a .config file containing the settings stored in a XML format and stored deep down in the MyDocuments area. It's a known safe place to store application and user data and all users will have access to their own MyDocuments area.

Round three on managing settings in a .NET 2.0 application using System.Configuration. ApplicationSettingsBase. We're now at the point of talking about how this class supports migration of settings within your project.

The challenge with any implementation of application settings is how to manage the evolution of those settings over time. You may find the need to add, remove, update and adjust settings as time passes and your application evolves. Using the default storage provider in .NET 2.0, ApplicationSettingsBase writes out the settings and their values into an XML file similiar to app.config but called user.config. Your next question undoubtably is "where does .NET put this file?".

The answer is fascinating.

First, you have to remember that since settings are likely to be per-user based items, they need to go someplace guaranteed to be accessible to even a user with a low rights account (ie. User security group). The stipulated location for this kind of information is the "Documents and Settings" folder typically found in the root of your C: drive. This is also where the MyDocuments folder is located. However, ApplicationSettingsBase doesn't store (by default) its data in MyDocuments. It chose instead to place this information in Local Settings\Application Data. These is a sibling folder to MyDocuments and is intended for per-user data that is non-roaming (ie that is computer dependent).

As an aside, if you regularly deal with issues such as where to place files, what folders you should use for specific purposes, how to respond to environmental changes in the operating system, etc, I highly recommend getting a copy of Microsoft's Designed for Windows XP spec v2.3 which is in Word document format. This handy little tome will help you resolve and dispense with the interminable discussions that sometimes take place among developers trying to decide these issues.

Back to ApplicationSettingsBase. Although the Local Settings\Application Data folder is used, ApplicationSettingsBase doesn't stop there. It proceeds to create a sub folder named with the name of the company assigned to your application EXE file properties. If the name has spaces, those are substituted with underscores. Not sure why Microsoft does this, but they do. Next, the class creates a sub folder under the company name folder with the name of your EXE plus a bunch of ugly looking characters you can think of as a unique identifier of sorts. In this folder, it creates yet another sub folder with the version of your EXE. In that folder goes the user.config with your settings. It's important to note that the version number includes the full version number down to the build and revision octets.

Each time you build your application (by default) Visual Studio .NET 2005 helpfully updates your version number (actually build number)incrementing it each time. When this happens, ApplicationSettingsBase will automatically create a new sub folder in that location I described earlier with the new version number. Over time as you develop an application on a machine, you can end up with hundreds or thousands of these little sub folders each containing a version of the user.config file that existed for that build.

Now for the really interesting (and helpful) part.

When ApplicationSettingsBase is created when your application runs, it offers (but doesn't require) the ability to migrate older settings values to the new structure using ApplicationSettingsBase.Upgrade(). This is one of those auto-magical methods that makes your life as a .NET developer really sweet. This method will upgrade and copy values from an older build/version of your application into the new user.config. So you don't lose settings between builds and neither do your users. Which will make them very happy indeed.

Tuesday, October 24, 2006

Generic List

Generic List Class is a new in the .Net Framework version 2.0 .It represent strongly typed list of the object that can be accessed by index.It also provide methode for search,sort and manipulate list.

Namespace: System.Collections.Generic
Assembly: mscorlib (in mscorlib.dll)

[SerializableAttribute]
public class List : IList, ICollection,IEnumerable, IList, ICollection, IEnumerable

The List class is the generic equivalent of the ArrayList class. It implements the IList generic interface using the array whose size is dynamically increased as required.

The List class uses both an equality comparer and an ordering comparer.

Methods such as Contains, IndexOf, LastIndexOf, and Remove use an equality comparer for the list elements. The default equality comparer for type T is determined as follows. If type T implements the IEquatable generic interface, then the equality comparer is the Equals method of that interface; otherwise, the default equality comparer is Object.Equals(Object).

Methods such as BinarySearch and Sort use an ordering comparer for the list elements. The default comparer for type T is determined as follows. If type T implements the IComparable generic interface, then the default comparer is the CompareTo method of that interface; otherwise, if type T implements the nongeneric IComparable interface, then the default comparer is the CompareTo method of that interface. If type T implements neither interface, then there is no default comparer, and a comparer or comparison delegate must be provided explicitly.

The List is not guaranteed to be sorted. You must sort the List before performing operations (such as BinarySearch) that require the List to be sorted.

Elements in this collection can be accessed using an integer index. Indexes in this collection are zero-based.

List accepts a null reference (Nothing in Visual Basic) as a valid value for reference types and allows duplicate elements

Performance Considerations
In deciding whether to use the List or ArrayList class, both of which have similar functionality, remember that the List class performs better in most cases and is type safe. If a reference type is used for type T of the List class, the behavior of the two classes is identical. However, if a value type is used for type T, you need to consider implementation and boxing issues.

If a value type is used for type T, the compiler generates an implementation of the List class specifically for that value type. That means a list element of a List object does not have to be boxed before the element can be used, and after about 500 list elements are created the memory saved not boxing list elements is greater than the memory used to generate the class implementation.

Example

using System;
using System.Collections.Generic;

public class Example
{
public static void Main()
{
List names = new List();

Console.WriteLine("\nCapacity: {0}", names.Capacity);

names.Add("Vishal");
names.Add("Joe");
names.Add("Prashant");
names.Add("Deepak");

Console.WriteLine();
foreach(string name in names)
{
Console.WriteLine(name);
}

Console.WriteLine("\nCapacity: {0}", names.Capacity);
Console.WriteLine("Count: {0}", names.Count);

Console.WriteLine("\nContains(\"Vishal\"): {0}",
names.Contains("Vishal"));

Console.WriteLine("\nInsert(2, \"Shobhit\")");
names.Insert(2, "Shobhit");

Console.WriteLine();
foreach(string name in names)
{
Console.WriteLine(name);
}

Console.WriteLine("\nnames[3]: {0}", names[3]);

Console.WriteLine("\nRemove(\"Deepak\")");
names.Remove("Deepak");

Console.WriteLine();
foreach(string name in names)
{
Console.WriteLine(name);
}

names.Clear();
Console.WriteLine("\nClear()");
Console.WriteLine("Capacity: {0}", names.Capacity);
Console.WriteLine("Count: {0}", names.Count);
}
}

Monday, October 23, 2006

Settings in VS 2005

Settings can represent user preferences, or valuable information the application needs to use. For example, you might create a series of settings that store user preferences for the color scheme of an application. Or you might store the connection string that specifies a database that your application uses. Settings allow you to both persist information that is critical to the application outside of the code, and to create profiles that store the preferences of individual users.

In C# use settings by accessing the Properties namespace. In the course of this article, you will learn the difference between application and user settings, how to create new settings at design time, how to access settings at run time, and even how to incorporate multiple sets of settings into your application.


Application and User Settings
Settings have four properties:

Name: The Name property of settings is the name that is used to access the value of the setting at run time.
Type: The Type of the setting is the .NET Framework type that the setting represents. A setting can be of any type. For example, a setting that holds a user preference of color would be a System.Color type.
Scope: The Scope property represents how a setting can be accessed at run time. There are two possible values for the Scope property: Application and User. These will be discussed more in this section.
Value: The Value property represents the value returned when the setting is accessed. The value will be of the type represented by the Type property.

The crucial distinction between application-scope and user-scope settings is that user-scope settings are read/write at run time, and their values can be changed and saved in code. Application-scope settings are read only at run time. While they can be read, they cannot be written to. Settings with application scope can only be changed at design time, or by altering the settings file manually

Creating a New Setting at Design Time
You can create a new setting at design time by using the Settings designer. The Settings designer is a familiar grid-style interface that allows you to create new settings and specify properties for those settings. You must specify Name, Type, Scope, and Value for each new setting. Once a setting is created, it can be assessed in code using the mechanisms described later in this article.

To Create a New Setting at Design Time
1. In Solution Explorer, expand the Properties node of your project.
2. In Solution Explorer, double-click the .settings file in which you want to add a new setting. The default name for this file is Settings.settings.
3. In the Settings designer, set the Name, Type, Scope, and Value for your setting. Each row represents a single setting. Figure 1 shows an example of the Settings designer.

To Change the Value of a Setting Between Application Sessions

Using Microsoft Notepad or some other text or XML editor, open the .exe.config file associated with your application.
Locate the entry for the setting you want to change. It should look similar to the following example:

This is the setting value


Type a new value for your setting and save the file.