Adding TODOs to your C# code

Havings TODO items in your code is inevitable. I have yet to see a project where we do not have to come back and alter a few things later. In my recent project where I had to write an integration module to a financial transactions settlement system which was not totally ready. That settlement system was accessible to me through web services but a lot of those web services were not just ready yet. I had to write a log of code assuming that certain methods with those parameter will be available to me some day and hence the use of TODO markers. Visual Studio makes it very convenient. It has a few keywords like TODO, HACK or UNDONE which can be prepended to a comment to make it special.

For example a comment like:

// TODO: this needs to be done
// MySystem.Method1(parameters);

Once you have a comment like this in your code it becomes a part of your task list. The task list can be viewed anytime through the menu View -> Task List. The task list will be displayed by default along with the error list. The task list window has its own little drop down menu having its own options, User tasks or Comments. Select the comments option and all TODO, HACK or any other special comment you have in your code will be displayed there. It is a perfect way to create reminders about what still needs to be done in your code so you don’t miss out anything by mistake.

And yes, you can create your own keywords as well. This MSDN article (http://msdn.microsoft.com/en-us/library/zce12xx2(v=vs.80).aspx) shows how to do that.

Checking Exceptions in MsTest

So, we found out MsTest does not have an Assert method to check if your method throws an exception. But can take care of that.

///<summary>
/// Extension methods for MsTest Assert
///
</summary> 
public static class AssertEx
{
///<summary>
/// Check that the peice of code throws an exception
/// as expected
///</summary>
///<typeparam name=”T”></typeparam>
///<param name=”action”></param>
///<returns></returns>
public static T Throws<T>(Action action) where T : Exception
{
try
{
action();
}
catch (T ex)
{
return ex;
}
catch (Exception ex)
{
Assert.Fail(“Expected exception of type {0} but actual exception of type {1} was thrown.”, typeof(T), ex.GetType());
}

Assert.Fail(“Expected exception of type {0} but not exception was thrown.”, typeof(T));
return null;
}
}

This method can be used to run methods which are expected to throw exceptions.

AssertEx.Throws<MyException>( () => class.RunMethodRun() );

This will make sure that the method RunMethodRun() throws an exception or your unit test will fail.

Database Schema Versioning

Database schema is an important part of your source code and you would like to release it along with your application especially if it is a web application. The other reason to version your database is for continuous integration. Every time a team member makes some change in the code the build server picks it up and rebuilds the whole application again. If that change contains a database update, you would want that to happen on the build server automatically. Here comes your database script runner tool.

I have been looking for tools like that over the internet but could not find an open source script runner. The one which does the job is not open source and the one which is open source does not do the job right. So I decided to write my own.

This is a class library which takes in a connection string, a file format string and the path to the scripts directory. Connection string is off course the address of your database and the file format is an handy feature so you can use any name format for your sql scripts. For instance: a file name “my_%.sql” will read all files of the format my_<sequence number>.sql where sequence number is a 4 digit integer.

Here is the code. I use it as a library and run it at the start up on one of my services but you can create a console application and reference the assembly in it to use it as a standalone tool. I might create that console application later and will share it here if I do.

    public class SchemaUpdater
    {
        private readonly string _connectionString;
        private readonly string _nameformat;
        private readonly string _scriptdir;

        public SchemaUpdater(string connectionstring, string format, string scriptpath)
        {
            _connectionString = connectionstring;
            _nameformat = format;
            _scriptdir = scriptpath;
        }

        public void Update()
        {
            using (var connection = new SqlConnection(_connectionString))
            {
                connection.Open();
                var scriptseparator = new[] {"\nGO"};

                // Make sure we have a schema versions table
                var scriptfile = string.Format("{0}\\{1}", _scriptdir, "versions-table.sql");
                var transaction = connection.BeginTransaction(IsolationLevel.Serializable);
                try
                {
                    Array.ForEach(File.ReadAllText(scriptfile).Split(scriptseparator, StringSplitOptions.RemoveEmptyEntries),
                        (sql => new SqlCommand(sql, connection, transaction).ExecuteNonQuery()));
                    transaction.Commit();
                }
                catch(Exception)
                {
                    transaction.Rollback();
                    throw;
                }

                // Now run the baseline
                scriptfile = string.Format("{0}\\{1}", _scriptdir, "base.sql");
                transaction = connection.BeginTransaction(IsolationLevel.Serializable);
                try
                {
                    Array.ForEach(File.ReadAllText(scriptfile).Split(scriptseparator, StringSplitOptions.RemoveEmptyEntries),
                        (sql => new SqlCommand(sql, connection, transaction).ExecuteNonQuery()));
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }

                // Now run all the files
                var command = new SqlCommand("SELECT Version FROM SchemaVersion", connection);
                var version = command.ExecuteScalar();
                command.Dispose();

                var start = version == null ? 0 : Convert.ToInt32(version)+1;

                var filename = _nameformat.Replace("%", start.ToString("0000"));
                scriptfile = string.Format("{0}\\{1}", _scriptdir, filename);

                transaction = connection.BeginTransaction(IsolationLevel.Serializable);

                try
                {
                    while (File.Exists(scriptfile))
                    {
                        Array.ForEach(File.ReadAllText(scriptfile).Split(scriptseparator, StringSplitOptions.RemoveEmptyEntries),
                            (sql => new SqlCommand(sql, connection, transaction).ExecuteNonQuery()));

                        start++;
                        filename = _nameformat.Replace("%", start.ToString("0000"));
                        scriptfile = string.Format("{0}\\{1}", _scriptdir, filename);
                    }

                    new SqlCommand(string.Format("Update SchemaVersion SET Version={0}", start-1), connection, transaction).ExecuteNonQuery();

                    transaction.Commit();
                }
                catch(Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
    }

This is a small piece of code but it works for me, also takes care of the GO separator in the sql scripts and runs all commands in a transaction. It uses my scripts “version-tables.sql” which creates a new version tables in the database if it does not exist and “base.sql” which contain any sql statements which you want to run to create a baseline schema.

ASP.NET MVC: Binding arrays in model

One of the great features of ASP.NET MVC is the automatic model binding. This is one of those things which look trivial but in fact are very very important. This reduces the LoC and complexity by miles. For instance, you want to present a number of text inputs to the user and read multiple locations:

 

<input type="text" name="Location1" id="Location1" />
<input type="text" name="Location2" id="Location2" />
<input type="text" name="Location3" id="Location3" />

 

Now this would be tedious in your action:

 

public ActionResult UserData(string location1, string location2, string2)
{
   // do somthing
   return View();
}

 

And what if you don’t know how many locations would there be? That is where MVC shows the magic. Bring it on:

public ActionResult UserData(string[] locations)
{
   // do somthing
   return View();
}

 

 

Hmmm… pretty simple. Now keep adding location inputs in your view and MVC will bind all that to the location parameter. The key here is that the name of your input controls should be location as well with an index like a proper array.

 

<input type="text" name="location[0]" id="location[0]" />
<input type="text" name="location[1]" id="location[1]" />
<input type="text" name="location[2]" id="location[2]" />

 

The magic of model binding does not end here. That is, if you have another array of postcodes along with locations the method signature of your action will look dirty again. The solution for this in MVC is to bind everything in the model object and pass that object over to the action. Now your model object will look like this:

 

public class HomeModel
{
     public IList<string> Locations { get; set; }
     public IList<string> PostCodes { get; set; }
}

 

 

And the action signature will accept only one parameter which is the model.

 

public ActionResult UserData(HomeModel model)

 

Yes, everything is in that object, pretty neat. Make sure your view inherits from System.Web.Mvc.ViewPage<HomeModel> so it knows about its model type.

 

 

 

Share this post :

Binding a List with DataGridView

DataGridView control for WinForms was introduced in .NET 2.0 and VS 2005. Its a pretty flexible control offering a lot more than DataGrid control in the previous version. Recently I was looking for a control which inherently support embedded control in its cells and DataGridView came up as a strong candidate. It has a native support of some basic embedded controls like TextBox, CheckBox etc. I explored it a little more and found it extremely easy and quick to program. My usage of this control is not much advanced which I describe here.

It has been built for displaying relational data so you can bind it to a DataTable from the database or an array of business objects. What I have done here is that I used a BindingList object which is also provided with .NET and is a useful variant of List object. The advantage of BindingList is that it can act as a sink of events while simple List object can’t.  It provides a PropertyChangedEventHandler which is called when a row is added/updated or deleted. So you simple bind this list to your DataGridView and both objects will remain synchronized. If you add/delete/update something to one the other object will simple pick it up from the event. Have a look at this:

private void MyForm_Load(object sender, EventArgs e) 
{
             FillUpDataGridView();  
             MyDataGridView.DataSource = Settings.MyBindingList; 
}

The method FullUpDataGridView reads some business objects from a data source into the BindList object and the next statement displays the data in the control. You also need to bind DataGridView columns to properties of these business objects to specify which properties are displayed and which are not and their respective order.

Binding properties with columns of DataGridView control

This image shows name of the propery FeedEnabled which has been bound with the column "Enabled". My business object looks like:

public class FeedViewRow : INotifyPropertyChanged
{
    private string _FeedUri;
    private bool _AutoUpdate;
    private bool _FeedEnabled;         // Parameterless constructor for serialization
    public FeedViewRow() {  }
    public FeedViewRow(string Uri, bool Auto, bool Enabled)
    {
        _FeedUri = Uri;
        _AutoUpdate = Auto;
        _FeedEnabled = Enabled;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public bool FeedEnabled
    {
        get { return _FeedEnabled; }
        set { _FeedEnabled = value; this.NotifyPropertyChanged("FeedEnabled"); }
    }
    public string FeedUri
    {
        get { return _FeedUri; }
        set { _FeedUri = value; this.NotifyPropertyChanged("FeedUri"); }
    }
    public bool AutoUpdate
    {
        get { return _AutoUpdate; }
        set { _AutoUpdate = value; this.NotifyPropertyChanged("AutoUpdate"); }
    }
    private void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

Keep a string property for TextBox and bool for CheckBox.  You object should implement the INotifyPropertyChanged interface.

After this you can simply [de]serialize the BindingList object. For serialization:

IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForAssembly();
IsolatedStorageFileStream File = new IsolatedStorageFileStream(StorageFileName,
FileMode.Create, FileAccess.Write, FileShare.None, Storage);
XmlSerializer Serializer = new XmlSerializer(typeof(BindingList)); 
Serializer.Serialize(File, this);
File.Close();
Storage.Close();

This will write out an XML of the whole list. Simple!

 

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

C# Winforms: Using a progress bar with Web Browser Control

The .NET web browser provides a number of different events including some which tells when the browser started navigating to a web page and when that navigation completed.

These events are:

private System.Windows.Forms.WebBrowser ItemBrowser;

 

this.ItemBrowser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.ItemBrowser_Navigating);
this.ItemBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.ItemBrowser_DocumentCompleted);
this.ItemBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.ItemBrowser_Navigated);

 

This shows the functions are being called at proper events. Now let us come to the code in those functions. The goal is to show a marquee in the status bar when a page is clicked and stop that marquee when navigation is fully complete.

private void ItemBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    BrowserLabel.Text = "Loading ... ";
    BrowserProgressBar.MarqueeAnimationSpeed = 80;
    BrowserProgressBar.Style = ProgressBarStyle.Marquee;
}

 

I have created two items in the status strip. A Label named BrowserLabel and a progress bar item named BrowserProgressBar. The text property of BrowserLabel is set to “Loading … “ when a hyperlink is created. And to start the marquee we set the style of progress bar to Marquee and its speed to 80. Note that as you increase the AnimationSpeed it will slow down. It will be fastest at 1 and slowest at 100 (I have set 100 as MaxSpeed, you can change that property as well).

Now we need to stop this animation when browsing is complete:

void ItemBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    BrowserProgressBar.MarqueeAnimationSpeed = 0;
    BrowserProgressBar.Style = ProgressBarStyle.Blocks;

    BrowserLabel.Text = "Ready";
}

 

I set the style back to Block and AnimationSpeed to “0”. Style is a property and it can start/stop the animation according to its value so you don’t need to call a “start” function as required in the previous versions. Also the value of Label is reset here.

One function is still remaining:

void ItemBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (!ItemBrowser.IsBusy)
    {
        BrowserProgressBar.MarqueeAnimationSpeed = 0;
        BrowserProgressBar.Style = ProgressBarStyle.Blocks;

        BrowserLabel.Text = "Ready";
    }
}

 

This function is also called when navigation is completed. Although in most cases the DocumentCompleted function is sufficient but bookmark links do not call that function so Navigated function will do in those cases.

 

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!

C# Winforms: Create a Single Instance Form Using Singleton

A common practice in WinForms programming is to keep only one instance of a certain form in the application. A new instance of that form is never created and shown. I have previously written a small note on this topic and gave a solution here which I personally don’t like.

In this post I am presenting a much better solution which is based on the singleton pattern. Rather than each time looking for the form in a list of opened forms I make the constructor private.

Let us start with the Form:

public sealed partial class ThirdForm : Form
{

}

The class is sealed so it cannot be inherited. We don’t want a child create an instance of this class multiple times.

Now add these members and methods to the class:

private static readonly ThirdForm MyInstance = new ThirdForm();

This is the sole instance of this form. And the private constructor to avoid multiple instances outside the class:

private ThirdForm()
{
    InitializeComponent();
}

And the property to publish the sole instance:

public static ThirdForm OnlyInstance
{
    get { return MyInstance; }
}

Another functionality that you might want to add to your Form is a new Show method. And you may also want to know whether the form was already opened or your opened it. Here is the answer to these questions. Add this code to your form class to Show() or Select() if already shown.

public new void Show()
{
    if (IsShown)
        base.Show();
    else
    {
        base.Show();
        IsShown = true;
    }
}

A variable IsShown of type bool is added to the form to record the current state.

private static bool IsShown = false;

static ThirdForm()
{
    OnlyInstance.FormClosing += new FormClosingEventHandler(OnlyInstance_FormClosing);
}

private static void OnlyInstance_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
    IsShown = false;

    OnlyInstance.Hide();
}

The variable IsShown is set to false when the only instance of this form is closed. But remember its a singleton. We can’t let the only instance die so we catch FormClosing event and Hide() the form instead of closing it.

This solution looks elegant than looking for an opened form in an array but it has draw backs. You cannot catch the FormClosed event because it will never happen. The form is created only once so if your form is based on some volatile objects you will never see the change even if you close and open it again. May be I try to address these problems in another post some day. Spot On!

Share this post : digg it! Facebook it! live it! reddit! technorati! yahoo!