Sunday, November 6, 2011

Friday, August 26, 2011

C#: A better PropertyChanged

If you have to implement and use IPropertyChanged in your code then you might feel annoyed by all the code that must be written to support the PropertyChanged event:
public class Product : INotifyPropertyChanged
{
 public event PropertyChangedEventHandler PropertyChanged;

 private int _productId;
 public int ProductId
 {
  get { return _productId; }
  set
  {
   _productId = value;
   RaisePropertyChanged("ProductId");
  }
 }

 private string _name;
 public string Name
 {
  get { return _name; }
  set
  {
   _name = value;
   RaisePropertyChanged("Name");
  }
 }

 protected void RaisePropertyChanged(string propertyName)
 {
  if (PropertyChanged != null)
   PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 } 
}
Not only is this code trivial and repetitive but since the property name is passed as a string then it can easily lead to typos. Luckily there is a better way to do this:
public class Product : PropertyChangedBase<Product>
{
 public int ProductId
 {
  get { return GetPropertyValue(x => x.ProductId); }
  set { SetPropertyValue(x => x.ProductId, value); }
 }

 public string Name
 {
  get { return GetPropertyValue(x => x.Name); }
  set { SetPropertyValue(x => x.Name, value); }
 }
}
PropertyChangedBase:
public class PropertyChangedBase<T> : INotifyPropertyChanged
{
 private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
 public event PropertyChangedEventHandler PropertyChanged;

 protected TProp GetPropertyValue<TProp>(Expression<Func<T, TProp>> property)
 {
  var name = GetPropertyName(property);
  return (TProp) _properties[name];
 }

 protected void SetPropertyValue<TProp>(Expression<Func<T, TProp>> property, object value)
 {
  var name = GetPropertyName(property);
  _properties[name] = value;
  RaisePropertyChanged(name);
 }

 protected void RaisePropertyChanged(string propertyName)
 {
  if (PropertyChanged != null)
   PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 }

 private string GetPropertyName<TProp>(Expression<Func<T, TProp>> property)
 {
  return (property.Body as MemberExpression).Member.Name;
 }
}

Sunday, August 21, 2011

New job as a Consultant at Capgemini

31st of March I had my last day at Mamut, one of the leading software houses in Europe. It was a great company to work for, with great employees and great products and I truly enjoyed my time there. But everything has an end. After reviewing things I thought it was time for a change in order to get more experience from other industries and companies.

On the 1st of April I had my first working day at Capgemini, one of the worlds largest and leading IT consultancy company. So far I'm very satisfied. In a short time I've got to meet many new people and learn and experience new things.

How to enable automatic logon in Windows 7

This is how you can enable automatic logon in Windows 7:

1. Press the Windows key on the keyboard + r. This will open the Run dialog.
2. Enter "netplwiz" and click OK.
3. The User Accounts dialog will now show. Uncheck the box "Users must enter a user name and password to use this computer."
4. Click OK.

C#: How to get the all the field/column names in a DataReader

The following helper method writes out the index position, the name and the data type for all the fields/columns in a DataReader, to the output window in Visual Studio:

public static void DataReaderDebugger(IDataReader reader)
{
 System.Diagnostics.Debug.WriteLine("### DataReader Debug Info ###");
 for (int i = 0; i < reader.FieldCount; i++)
 {
  string info = string.Format("{0}. {1} ({2})",
        i.ToString(),
        reader.GetName(i),
        reader.GetFieldType(i).Name);

  System.Diagnostics.Debug.WriteLine(info);
 }
 System.Diagnostics.Debug.WriteLine("######");
}

Monday, April 4, 2011

Search engine friendly URLs in ASP.NET MVC using dynamic routing and a SQL Server database

Search engine friendly URLs, also known as rewritten URLs, is a feature where a more logical and readable URL is exposed to the user. An example of such an URL is www.kindblad.com/about.

Today ASP.NET MVC supports friendly URLs out of the box through its routing feature, but the default implementation only supports hard coding of routes and pre-population of routes (using your own data source) during application startup. This is often not an ideal solution, especially when there are thousands of routes. In this post I will go through how we can change the default implementation into a dynamic one that reads the routing information from a database.

1) Let's begin by creating a Page table in our database:

Some sample data:

This table will contain a list of all the pages on our website, together with the friendly URL and the controller it maps to. For instance when a user request the URL http://www.kindblad.com/about the controller Article would be loaded.

2) Next we need an entity class that will represent the page row:

public class PageItem
{
 public int PageId { get; set; }
 public string Title { get; set; }
 public string FriendlyUrl { get; set; }
 public string ControllerName { get; set; }
}

3) Then we need a new class called PageManager that will be responsible for querying the page table in the database for a row that matches the given friendly URL, and for mapping the row to the PageItem type:

public class PageManager
{
 public static PageItem GetPageByFriendlyUrl(string friendlyUrl)
 {
  PageItem page = null;

  using (var cmd = new SqlCommand())
  {
   cmd.Connection = new SqlConnection("Server=(local);Database=MyWebsite;Trusted_Connection=True;");
   cmd.CommandText = "select * from Page where FriendlyUrl = @FriendlyUrl";
   cmd.Parameters.Add("@FriendlyUrl", System.Data.SqlDbType.NVarChar).Value = friendlyUrl;
    
   cmd.Connection.Open();
   using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
   {
    if (reader.Read())
    {
     page = new PageItem();
     page.PageId = (int) reader["PageId"];
     page.Title = (string) reader["Title"];
     page.ControllerName = (string) reader["ControllerName"];
     page.FriendlyUrl = (string) reader["FriendlyUrl"];
    }
   }

   return page;
  }
 }
}

4) The next thing we need to do is to create a custom route handler. This class will be triggered by the ASP.NET MVC framework when a new request comes in to the server. This happens before the Controller has been created, so it gives us the chance to tell ASP.NET MVC that we want to load another controller than it would originally have. So create a new class named FriendlyUrlRouteHandler:

public class FriendlyUrlRouteHandler : System.Web.Mvc.MvcRouteHandler
{
 protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
 {
  var friendlyUrl = (string) requestContext.RouteData.Values["FriendlyUrl"];

  PageItem page = null;

  if (!string.IsNullOrEmpty(friendlyUrl))
   page = PageManager.GetPageByFriendlyUrl(friendlyUrl);

  if (page == null)
   page = PageManager.GetPageByFriendlyUrl("home");

  requestContext.RouteData.Values["controller"] = page.ControllerName;
  requestContext.RouteData.Values["action"] = "index";
  requestContext.RouteData.Values["id"] = page.PageId;

  return base.GetHttpHandler(requestContext);
 }
}

In this route handler we will take the URL. If it is not set, we will set it to the default which is home. Then we will query the Page table for a row that matches the friendly URL. Further we will change the RouteData.Values["controller"] to the controller we want to load. After ASP.NET MVC has executed the code it will load the controller that we defined in the RouteData.Values["controller"].

5) And the last thing we need to do is to tell AS.NET MVC that we want to use our own route handler. So modify the RegisterRoutes method in the Global.asax to the following:

public static void RegisterRoutes(RouteCollection routes)
{
 routes.RouteExistingFiles = false;
 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 routes.MapRoute(
  "Default",
  "{*FriendlyUrl}"
 ).RouteHandler = new FriendlyUrlRouteHandler();
}

That's it. Now our website has full support for friendly URLs, both single level URLs like "about" but also multi-level URLs like "about-us/employees/eric".

Monday, March 14, 2011

ViewStateToDB version 1.0 is out

ViewStateToDB is a small project that I created some time ago. Now I thought it was time to get it out as an open source project in case others have a need for the same functionality. I have created a project on CodePlex for it, wrapped up the code and made a release.

What is ViewStateToDB? As the name implies it's a single assembly to be used in an ASP.NET Web Form site/application in order to persist the view state to a database instead of to the page/HTML. This saves both bandwidths as the size of the page is greatly reduced, and the security is increased since the view state is not publicly visible anymore.

Have a look at CodePlex for more information about ViewStateToDB.

Monday, February 28, 2011

Replace code comments with unit tests

Not long ago code comments using XML was the thing. Every class and method should have some comment related to it. This worked great in the beginning until the code was updated and the comments were not. Eventually it all got out of sync and the comments were considered useless and were ignored.

The new trend today is to see unit tests as the documentation as they are (usually) up-to-date. By just reading the method names of the tests we should get the idea of what the code is actually doing. Consider the following method:

public void UpdateCustomerName(int customerId, string name, string email)
{
 if (string.IsNullOrEmpty(name))
  throw new ValidationException("Customer name cannot be empty.");

 _dataProvider.UpdateCustomerName(customerId, name);

 if (!string.IsNullOrEmpty(email))
  _mailSender.SendMail(email, "Your customer data has been updated.");
}

With the following unit tests:

[TestMethod]
[ExpectedException(typeof(ValidationException))]
public void UpdateCustomer_throw_exception_when_customer_name_is_empty()
{
 var dataProviderFake = MockRepository.GenerateStub<IDataProvider>();
 var mailSenderFake = MockRepository.GenerateStub<IMailSender>();

 var customerUpdater = new CustomerUpdater(dataProviderFake, mailSenderFake);

 customerUpdater.UpdateCustomerName(1, "", "");
}

[TestMethod]
public void UpdateCustomer_update_the_customer_name_in_the_database()
{
 var dataProviderFake = MockRepository.GenerateStub<IDataProvider>();
 var mailSenderFake = MockRepository.GenerateStub<IMailSender>();

 var customerUpdater = new CustomerUpdater(dataProviderFake, mailSenderFake);

 customerUpdater.UpdateCustomerName(1, "Bill", "bill@somecompany.com");

 dataProviderFake.AssertWasCalled(x => x.UpdateCustomerName(0, null), x => x.IgnoreArguments());
}

[TestMethod]
public void UpdateCustomer_email_customer_if_email_address_is_not_empty()
{
 var dataProviderFake = MockRepository.GenerateStub<IDataProvider>();
 var mailSenderFake = MockRepository.GenerateStub<IMailSender>();

 var customerUpdater = new CustomerUpdater(dataProviderFake, mailSenderFake);

 customerUpdater.UpdateCustomerName(1, "Bill", "bill@somecompany.com");

 mailSenderFake.AssertWasCalled(x => x.SendMail(null, null), x => x.IgnoreArguments());
}

By reading the method names we see the main logic of this method:
1. Throw exception when the customer name is empty.
2. Update the customer's name in the database.
3. E-mail customer if the e-mail address is not empty.

Conclusion: If we focus on writing unit tests with good method names then we can save ourselves from writing inline code comments.

Saturday, February 12, 2011

Is your iPad dead? Try this...


This morning my iPad suddenly went black. I tried to turn it on again by holding in the sleep button, but without success. I then remember having a similar problem with my iPod many years ago, and luckily the same fix that worked back then also worked for my iPad:

- Press and hold the sleep and home button until you see screen come on. This can take up to 20 seconds.

Sunday, January 30, 2011

Developers should be lazy

One of my daily goals is to be a lazier developer. By this I mean - if what I'm implementing today also need to be implemented tomorrow or the day after, I should be able to deliver it with at least the same quality but with less effort. In order to achieve this, code duplication must be avoided and reusable components must be created whenever possible.

The difference between unit tests and integration tests

Developers usually write two types of tests for their code, unit tests and integration tests.

Unit tests are written for testing the correctness of the smallest unit of code in an application. In object oriented programming such a unit is usually a method. The unit must be tested in isolation when unit testing. This means that any dependency the unit has, such as a database, service or file system, must be abstracted away and replaced by a fake object. A fake object can be created manually or by using a mocking framework.

Integration tests on the other hand are for testing the correctness of the unit under test together with all of its dependencies. In such a test it's allowed to call a database, service, file system or any other type of dependency the code might have.

Monday, January 24, 2011

A true unit test does not...

A true unit test does not:
  • Depend on any code outside its own unit.
  • Talk to a database.
  • Invoke a service.
  • Call the file system.
  • Send an e-mail.
  • Communicate across the network.
  • Affect other unit tests.
  • Depend on environment specific configuration settings.

Monday, January 10, 2011

Unit tests should be in the same project as the code under test

Most of the .NET projects that I have seen with decent test coverage have the unit tests located in a separate test project. The structure of this unit test project usually reflects the structure of the project under test. Any folder and class in the project under test would also exist in the test project, but where the class has a *Tests suffix in the name.

On a project that I'm working on we also did it the same way. In the beginning it worked pretty well, keeping the two projects in sync wasn't too much hassle. But as the structure and the code was growing in size the two projects got more and more out of sync. The project under test would get new code added and it would get refactored, while the unit test project would not. Also more and more classes were lacking unit tests or the tests weren't up to date. Before this got totally out of hand I decided to find a better way to structure things. After playing around with a few different approaches I ended up with a simple solution to this problem. By simply moving the unit tests in to the same project as the code under test the problem was solved. The project under test would then have both a class A and a class ATests.

This approach has some nice benefits:
1) Easy to see if a class has any tests, just look for the ClassNameTests class.
2) Don’t have to maintain multiple structures.
3) Makes navigation between the class under test and the test class easier.
4) Signals the importance of unit tests.

But it also has some drawbacks:
1) The project needs to reference all the libraries that are required by the test code, such as mocking frameworks.
2) Changing the projects into a test project gives some overhead when compiling.
3) The compiled code/assemblies will be bigger in size. A way to solve this is to remove all the *Tests classes before compiling.

For unit tests I would recommend using this approach. When it comes to integration tests I suggest having them in a separate project as these tests are not to be run as frequent as the unit tests.

Saturday, January 1, 2011

Goals for 2011

It's the first day of the year and it's time to set my goals for 2011:
  • Write 52 blog posts.
  • Write 3 articles to be published on any larger technology site.
  • Maintain the 3 open source projects that I released in 2010, and release 2 new projects.
  • Create and release a simple Windows Phone 7 application.
  • Move this blog to my own to-be-created blog engine running on ASP.NET MVC and a NOSQL database.
  • Learn more about business intelligence by learning Microsoft SQL Server Integration Services and Microsoft SQL Server Reporting Services.
  • Become fluent on the ADO.NET Entity Framework.
  • Learn about event-driven architecture and NServiceBus.