Navigation to the webpage was canceled in chm file

If you download a chm file, or receive it in a mail, it’s likely that you will get the following exception when opening it:

chm1

In order to make it work, save the chm file to a local drive; right click it and select properties, and click unblock. Open it again and now it works:

chm2

Also, if you download visual studio projects from a web site as a zip file, you have to do unblock the zip file in the same way before unzipping it, otherwise visual studio will also give you warnings that it is not trusted.

August 27, 2010 17:40 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Code that needs to run before a WCF service is called for the first time

I was looking for a way to execute some piece of code only once when a WCF service is accessed for the first time. In particular, I needed to initialize the Castle IoC container.

The first attempt seemed easy: use the Application_Start event in the global.asax file. While this works, it has a drawback: it only works with http protocol! And I want a solution that works independent from the protocol that is used to access the service.

The next possibility I found was to add a special folder called App_Code, and put a class in it that contains a method AppInitialize. When the service is accessed the first time, the code in this method will be executed first. While this works perfectly, there is one drawback… code in the App_Code folder is not build before being deployed, so you end up with source code on the server, which I think is not optimal.

Luckily there is a clean way to make this work for every protocol, and it’s actually quite simple. First add a class to your service project, for example HostFactory, and put the following method in it:

  1: public class HostFactory : ServiceHostFactoryBase
  2: {
  3:     public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
  4:     {
  5:         Type service = Type.GetType(constructorString);
  6:         ServiceHost host = new ServiceHost(service, baseAddresses);
  7:         // hook up event handlers
  8:         host.Opening += new EventHandler(host_Opening);        
  9:         return host;
 10:     }
 11: 
 12:     void host_Opening(object sender, EventArgs e)
 13:     {
 14:         // Code that runs on application startup
 15:         var iocContainer = WindsorBootstrapper.Initialize();
 16:         var locator = new WindsorServiceLocator(iocContainer);
 17:         ServiceLocator.SetLocatorProvider(() => locator);
 18:     }
 19: }

and also, make sure to add Factory to your svc file, like:

  1: <%@ ServiceHost Language="C#" Debug="true" Service="EC.Service.Quartz.ServiceAdapter.QuartzService" 
  2:     CodeBehind="QuartzService.svc.cs" Factory="EC.Service.Quartz.HostFactory" %>

Now you have a protocol-independent way of making sure that code is executed before the first request to the service is done.

August 19, 2010 22:44 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Visual Studio 2010 style

The default colors of visual studio are, well, kind of boring. But now it’s possbible to change that with only a few mouse clicks! First go to http://studiostyles.info and download your favorite style. Then, in visual studio 2010, select Tools > Import and Export Settings:

style01

Check the Import selected environment settings, and click Next.

style02

You probably want to save the current settings, so accept the default and click Next.

style03

Then click the Browse button and select the template you downloaded:

style04

…and then the Next button.

style05

Finally click the Finish button.

style06

And if everything was ok:

style07

Click Close, and behold the new style :)

style09
May 7, 2010 05:18 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Transform collection to comma separated list

Today I had to transform a collection of integers into a string in the form of a comma separated list. In the ‘old-style- approach it would probably be something like:

  1: List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
  2: StringBuilder strb = new StringBuilder();
  3: foreach (int number in numbers)
  4: {
  5:     strb.Append(number.ToString());
  6:     strb.Append(",");
  7: }
  8: string commeSeparatedList = strb.ToString().TrimEnd(',');

But actually this can be done in a short way, like:

  1: List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
  2: string commeSeparatedList = string.Join(",", numbers.Select(n => n.ToString()).ToArray());

which produces the same result. In my case it was not a collection of integers, but a list of objects; but is the same approach:

  1: string commaSeparatedListOfGroups = string.Join(",", allRelatedGroups.Select(g => g.Id.ToString()).ToArray());
May 7, 2010 05:14 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Clone objects

Today a collegue asked for a clean way to clone objects in C#,  so that you really have different objects instead of a reference copy . So imagine that you have a class Employee as follows:

  1: public class Employee
  2: {
  3:      public string FirstName { get; set; }
  4:      public string LastName { get; set; }
  5: }

and you would copy it:

  1: Employee original = new Employee()
  2: {
  3:     FirstName = "Homer",
  4:     LastName = "Simpson",
  5: };
  6: 
  7: Employee copy = original;
  8: copy.FirstName = "Marge";
  9: Console.WriteLine(string.Format("{0} {1}", original.FirstName, original.LastName));
 10: Console.WriteLine(string.Format("{0} {1}", copy.FirstName, copy.LastName));

Changing the first name of the copied object obviously also changes the first name of the original object, because it has been copied by refererence and so original and copy refer to the same object:

CO_01

And this was not wat we wanted.

To solve it, we first write an extension method that will be available on each class that implements the ICloneable interface:

  1: static class Extensions
  2: {
  3:    public static T Clone<T>(this T objectToClone) where T : ICloneable
  4:    {
  5:      return (T)objectToClone.Clone();
  6:    }
  7: }

Next we have to make the Employee class implement the ICloneable interface:

  1: public class Employee : ICloneable
  2: {
  3:   public string FirstName { get; set; }
  4:   public string LastName { get; set; }
  5: 
  6:   #region ICloneable Members
  7: 
  8:   public object Clone()
  9:   {
 10:     return new Employee() {FirstName = FirstName, LastName = LastName};
 11:   }
 12: 
 13:   #endregion
 14: }

And if we now use the Clone method like:

  1: Employee copy = (Employee)original.Clone();

then the new object is really a copy of the original:

CO_02

If you want to clone a list of objects, add an extension method like this:

  1: static class Extensions
  2: {
  3:    public static IList<T> Clone<T>(this IList<T> listToClone) where T : ICloneable
  4:    {
  5:      return listToClone.Select(item => (T)item.Clone()).ToList();
  6:    }
  7: }

and to clone this list is then very simple:

  1: IList<Employee> copiedList = originalList.Clone();

This example clones only the Employee object (known as shallow copy, see here), but what if the Employee class contains other reference types? In this case we have to implement a deep copy, meaning that every subclass has to implement ICloneable too, for example, if you have a City:

  1: public class City: ICloneable
  2: {
  3:   public string CityName { get; set; }
  4: 
  5:   #region ICloneable Members
  6: 
  7:   public object Clone()
  8:   {
  9:     return new City() { CityName = CityName };
 10:   }
 11: 
 12:   #endregion
 13: }

then Employee has to clone it like:

  1: public class Employee : ICloneable
  2: {
  3:   public string FirstName { get; set; }
  4:   public string LastName { get; set; }
  5:   public City City{ get; set; }
  6: 
  7:   #region ICloneable Members
  8: 
  9:   public object Clone()
 10:   {
 11:     return new Employee() {FirstName = FirstName, LastName = LastName, City = (City)City.Clone() };
 12:   }
 13: 
 14:   #endregion
 15: }

We can do one other improvement. As you see we always have to cast the Clone operation to its actual type. To solve  that we can create a generic ICloneable interface:

  1: interface ICloneable<T> : ICloneable
  2: {
  3:   new T Clone();
  4: }

and adapt the classes to it:

  1: public class Employee : ICloneable<Employee>
  2: {
  3:   public string FirstName { get; set; }
  4:   public string LastName { get; set; }
  5:   public City City{ get; set; }
  6: 
  7:   #region ICloneable<Employee> Members
  8: 
  9:   Employee ICloneable<Employee>.Clone()
 10:   {
 11:     return new Employee() { FirstName = FirstName, LastName = LastName, City = City.Clone() };
 12:   }
 13: 
 14:   #endregion
 15: 
 16:   #region ICloneable Members
 17: 
 18:   object ICloneable.Clone()
 19:   {
 20:     return new Employee() { FirstName = FirstName, LastName = LastName, City = City.Clone() };
 21:   }
 22: 
 23:   #endregion
 24: }
 25: 
 26: public class City : ICloneable<City>
 27: {
 28:   public string CityName { get; set; }
 29: 
 30:   #region ICloneable<City> Members
 31: 
 32:   public City Clone()
 33:   {
 34:     return new City() { CityName = CityName };
 35:   }
 36: 
 37:   #endregion
 38: 
 39:   #region ICloneable Members
 40: 
 41:   object ICloneable.Clone()
 42:   {
 43:     return new City() { CityName = CityName };
 44:   }
 45: 
 46:   #endregion
 47: }
May 7, 2010 02:42 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Castle MicroKernel/Windsor QuickStart 2: LifeStyle and LifeCycle

Objectives

In this Hands-On Lab, you will be introduced to the Castle MicroKernel/Windsor framework. In particular, you will:

  • Understand LifeStyle
  • Understand LifeCycle

System requirements

You must have the following items to complete this lab:

  • Microsoft Visual Studio 2008 SP1 (professional edition)

Prequisites

You must have the following skills to understand this lab:

  • Fundamental knowledge of software development in .NET 3.5
  • Basic knowledge of Castle

Understand LifeStyle

LifeStyle is a strategy that is related to an instance of a component. The supported lifestyles are:

  • Singleton: only one instance will be created for the whole life of the container. This is the default lifestyle.
  • Transient: for each request a new instance if the component is created
  • PerThread: for each thread there exists only one instance of a component
  • Pooled: Instances will be pooled to avoid unnecessary constructions
  • Custom: the instantiation of components is handled by your custom ILifestyleManager implementation

The default lifestyle is singleton. To indicate which lifestyle you want to use, you can use attributes to decorate the class:

  1: [Transient]
  2: public class CustomerRepository : ICustomerRepository
  3: {
  4:     …
  5: }

or in the configuration file:

  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:   <configSections>
  4:     <section
  5:       name="castle"
  6:       type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
  7:       Castle.Windsor" />
  8:   </configSections>
  9:   <castle>
 10:     <components>
 11:       <component
 12:         id="customer.business"
 13:         service="CastleExample.ICustomerBusiness, CastleExample"
 14:         lifestyle="transient"
 15:         type="CastleExample.CustomerBusiness, CastleExample" />
 16:       <component
 17:         id="customer.repository"
 18:         service="CastleExample.ICustomerRepository, CastleExample"
 19:         lifestyle="transient"
 20:         type="CastleExample.MockCustomerRepository, CastleExample" />
 21:     </components>
 22:   </castle>
 23: </configuration>

I prefer to do it in configuration because otherwise the code will be coupled again to the Castle container, or, in complicated projects, it may be handier to do it in code but in that case, create specific classes that are responsible for these configuration tasks, so that in your code you have as little as dependencies to Castle as possible.

So try this: add a transient lifestyle to the components in the configuration file, and to see the effect, modify the constructor of CustomerBusiness and add constructors to CustomerRepository and MockCustomerRepository as follows:

  1: public class CustomerBusiness : ICustomerBusiness
  2: {
  3:   private ICustomerRepository customerRepository;
  4:   public CustomerBusiness(ICustomerRepository customerRepository)
  5:   {
  6:     // using constructor injection the concrete customer repository is injected
  7:     this.customerRepository = customerRepository;
  8:     Console.WriteLine("CustomerBusiness constructor");
  9:   }
 10:   …
 11: }
 12: 
 13: public class CustomerRepository : ICustomerRepository
 14: {
 15:   public CustomerRepository()
 16:   {
 17:     Console.WriteLine("MockCustomerRepository constructor");
 18:   }
 19:   …
 20: }
 21: 
 22: public class MockCustomerRepository : ICustomerRepository
 23: {
 24:   public MockCustomerRepository()
 25:   {
 26:     Console.WriteLine("MockCustomerRepository constructor");
 27:   }
 28:   …
 29: }

Modify Program.cs:

  1: static void Main(string[] args)
  2: {
  3:   …
  4:   // Use business
  5:   UseRegisteredBusiness();
  6:   UseRegisteredBusiness();
  7:   UseRegisteredBusiness();
  8: }

If you run the application, you will notice that each constructor is only called once and so there is only one instance created of the components for all calls:

DI2_01

Change the configuration that components use the transient lifestyle, and then run the application again to see the difference:

DI2_02

Now for each call of the business component, the constructors are called, which means that new objects are created for each call.

Understand LifeCycle

On the other hand there is LifeCycle, which is a strategy that is related to the different phases of an instance. It means that we can implement a number of interfaces; and these implementations are executed at the right time. Out of the box there are two groups of lifecycles:

  • Commission: these are executed when the component is being created. Interfaces are:
    • Castle.Model.IInitializable
    • System.ComponentModel.ISupportInitialize
  • Decommission: these are executed when the component is being destructed. Interface is:
    • System.IDisposable

So, bottom line: if you implement one of these interfaces for your component, Castle will take care of calling your implementations at the right time. Notice that if you use these, the coupling to Castle container will be higher.

May 7, 2010 02:39 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Castle MicroKernel/Windsor QuickStart 1: introduction

Objectives

In this Hands-On Lab, you will be introduced to the Castle MicroKernel/Windsor framework. In particular, you will:

  • Understand IoC and DI
  • Download Castle Windsor
  • Create a test application
  • Use configuration file

System requirements

You must have the following items to complete this lab:

  • Microsoft Visual Studio 2008 SP1

Prequisites

You must have the following skills to understand this lab:

  • Fundamental knowledge of software development in .NET 3.5

Understand IoC and DI

Inversion of Control (IoC) and Dependency Injection (DI) are two related practices in software development which are known to lead to higher testability and maintainability of software products.

In the traditional way of coding, you instantiate the objects you want to use, so this means that at compile time you know which are the real classes you are going to interact with – you call them directly. So it means that you are in control, and not the consumers of your code. If you invert this, it would mean that you don’t know what the real classes are: someone else (the consumer) decides which will be the real classes, and how they will be instantiated. In this case you don’t know the concrete classes, but you only know the interfaces, and you don’t care about the actual implementation that is used. Therefore there are less dependencies and the coupling in a system is reduced. In fact, the control of dependency creation is pushed outside of the class itself. It is all about removing dependencies from your code.

A simple example: have a look at the following code:

  1: public class Car
  2: {
  3:   Engine engine;
  4:   public Car()
  5:   {
  6:     engine = new Engine();
  7:   }
  8: }

We have a extremely strongly dependency between Car and Engine, because the Engine is instantiated in the Car, so we can’t install any other engine inside this car. To make this code better, we change it slightly:

  1: public class Car
  2: {
  3:   IEngine engine;
  4:   public Car(IEngine engine)
  5:   {
  6:     this.engine = engine;
  7:   }
  8: }

Notice the difference? The control of creation of the engine has been moved out of the car.  Now the code that creates the car also chooses the engine:  this is inversion of control. Inversion of control is also known as the Hollywood principle: ‘don’t call me, I call you’, so in this case it’s like the Engine class saying to the Car class: ‘don’t create me, I will be created by someone else’.

Another concrete (simplified) example: in the following picture, a client uses the CustomerBusiness component, which uses the CustomerRepository component to access the database. You see that CustomerBusiness has a hard reference to the concrete CustomerRepository:

DI_01

Now imagine that we want to add unit tests to test the business component:

DI_02

Now we have a problem, because when we test the business component we don’t want it to use the real CustomerRepository but a mock implementation of it. In the current architecture, we do not have this flexibility. To solve this, we can use the IoC pattern: let the Client and Unit test decide which repository the business component should use.  So, the CustomerBusiness component no longer decides what repository it uses. To achieve this, we create a ICustomerRepository interface. This interface is then implemented by the CustomerRepository (this implementation uses the real database) and also by the MockCustomerRepository (this implementation uses no database, but mock data). The CustomerBusiness component now has only a reference to the ICustomerRepository interface, and it doesn’t know what the real implementation is, and it doesn’t care:

DI_03

The control of which repository is used is inverted to the client (wants the business component to use CustomerRepository) and the unit test (wants the business component to use MockCustomerRepository).

In a further step we can do the same for every component: create your interface first and then one or more implementations. So in our example also the business component can be abstracted, although we have only one implementation at this time:

DI_04

It takes a while to understand this approach because it’s a mind shift and has a certain learning curve: the way you build your software changes. But using these principles eventually lead to better structured, modularized, testable and maintainable applications. Once you get used to it, it actually becomes a habit to build software this way.

To summarize, the advantages are:

  • loose coupling between components: you share contracts, not implementations
  • flexibility: it’s easy to change behavior
  • easy to test components: replace dependencies by mocking components so that you can really test what you want to test
  • improve code reuse: each component has its responsibility
  • extensibility: future changes can be implemented easily by injecting new implementations

Dependency creation is often delegated to inversion of control containers, frameworks that allow needed dependencies to be injected automatically; this process is called dependency injection.

There are a number of such frameworks that supply these patterns, like Castle, StructureMap, Spring.NET, Autofac, Unity, NInject and others, but they all implement about the same principles; although Castle has also a number of aspect oriented features. In these quickstarts we will be using Castle.

Download Castle

You need the Castle Project assemblies on your local machine, so download the project release at http://www.castleproject.org/castle/download.html.

Create a test application

We are going to create a simple test application to demonstrate the basics of Castle. Start Visual Studio and create a new console application called CastleExample. Add references to the following assemblies:

  • Castle.Core.dll
  • Castle.DynamicProxy2.dll
  • Castle.MicroKernel.dll
  • Castle.Windsor.dll

We are going to implement the example from previous chapter in a simple way, focusing on how to use Castle to achieve dependency injection. We start by defining the domain object for customer, so add a new class Customer:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: 
  6: namespace CastleExample
  7: {
  8:     public class Customer
  9:     {
 10:         public int Id{ get; set; }
 11:         public string FirstName { get; set; }
 12:         public string LastName { get; set; }
 13:     }
 14: }

Then we design the interface for the customer repository. Add a new class ICustomerRepository:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: namespace CastleExample
  6: {
  7:     public interface ICustomerRepository
  8:     {
  9:         Customer CreateCustomer(Customer customer);
 10:         List<Customer> ReadCustomers();
 11:         void DeleteCustomer(int Id);
 12:     }
 13: }

We already now that we will have two implementations for this interface: a real one, using a database; and one that uses mock data. For the real one, add a class CustomerRepository:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: namespace CastleExample
  6: {
  7:     public class CustomerRepository : ICustomerRepository
  8:     {
  9:         #region ICustomerRepository Members
 10:         public Customer CreateCustomer(Customer customer)
 11:         {
 12:             // TO DO: Create customer in database here
 13:             Console.WriteLine("CreateCustomer in CustomerRepository");
 14:             return null;
 15:         }
 16:         public List<Customer> ReadCustomers()
 17:         {
 18:             // TO DO: Read customers from database here
 19:             Console.WriteLine("ReadCustomers in CustomerRepository");
 20:             return null;
 21:         }
 22:         public void DeleteCustomer(int Id)
 23:         {
 24:             // TO DO: Delete customer in database here
 25:             Console.WriteLine("DeleteCustomer in CustomerRepository");
 26:         }
 27:         #endregion
 28:     }
 29: }

For the mock repository, add a class MockCustomerRepository:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: namespace CastleExample
  6: {
  7:     public class MockCustomerRepository : ICustomerRepository
  8:     {
  9:         #region ICustomerRepository Members
 10:         public Customer CreateCustomer(Customer customer)
 11:         {
 12:             // Mock a newly created customer
 13:             Console.WriteLine("CreateCustomer in MockCustomerRepository");
 14:             return null;
 15:         }
 16:         public List<Customer> ReadCustomers()
 17:         {
 18:             // Mock a list of customers
 19:             Console.WriteLine("ReadCustomers in MockCustomerRepository");
 20:             return null;
 21:         }
 22:         public void DeleteCustomer(int Id)
 23:         {
 24:             // Mock delete
 25:             Console.WriteLine("DeleteCustomer in MockCustomerRepository");
 26:         }
 27:         #endregion
 28:     }
 29: }

Note that we don’t actually implement CustomerRepository and MockCustomerRepository, we just use Console.WriteLine to demonstrate the effect later.

Now let’s write the Main method in the Program.cs file:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using Castle.Windsor;
  6: namespace CastleExample
  7: {
  8:     class Program
  9:     {
 10:         private static IWindsorContainer container;
 11:         static void Main(string[] args)
 12:         {
 13:             // Register components
 14:             container = new WindsorContainer();
 15:             container.AddComponent<ICustomerRepository,
 16:                      CustomerRepository>("customer.repository");
 17:             // Use repository
 18:             UseRegisteredRepository();
 19:         }
 20:         public static void UseRegisteredRepository()
 21:         {
 22:             // Get the actual registered customer repository
 23:             ICustomerRepository customerRepository =
 24:                     container.Resolve<ICustomerRepository>();
 25:             customerRepository.ReadCustomers();
 26:         }
 27:     }
 28: }
 29: 

In the Main method we first initialize a new WindsorContainer object, and then we indicate that whenever a ICustomerRepository interface is used in our code, we want the actual object to be of type CustomerRepository. So here we register the component, which doesn’t mean that it is already instantiated – this is only done when it’s needed.

Then, in the UseRegisteredRepository method, we use the container again to get the actual customer repository and we can use its methods.

Run the application, and as expected we can see that the ReadCustomers of the CustomerRepository class is being called:

DI_05

Now let’s change this so that the MoclCustomerRepository is used:

  1: static void Main(string[] args)
  2: {
  3:     // Register components
  4:     container = new WindsorContainer();
  5:     container.AddComponent<ICustomerRepository,
  6:                    MockCustomerRepository>("customer.repository");
  7: 
  8:    // Use repository     UseRegisteredRepository();
  9: }

Run the application again, and verify that this time the ReadCustomers of the MockCustomerRepository class is being called:

DI_06

Let’s add the business component. Again, first add a class ICustomerBusiness for the interface:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: namespace CastleExample
  6: {
  7:     public interface ICustomerBusiness
  8:     {
  9:         Customer AddCustomer(Customer customer);
 10:         List<Customer> GetCustomers();
 11:         void RemoveCustomer(int Id);
 12:     }
 13: }

We know we have one implementation at the moment, so add a class CustomerBusiness as follows:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: namespace CastleExample
  6: {
  7:     public class CustomerBusiness : ICustomerBusiness
  8:     {
  9:         private ICustomerRepository customerRepository;
 10:         public CustomerBusiness(ICustomerRepository customerRepository)
 11:         {
 12:             // using constructor injection the concrete customer repository is injected
 13:             this.customerRepository = customerRepository;
 14:         }
 15:         #region ICustomerBusiness Members
 16:         public Customer AddCustomer(Customer customer)
 17:         {
 18:             return customerRepository.CreateCustomer(customer);
 19:         }
 20:         public List<Customer> GetCustomers()
 21:         {
 22:             return customerRepository.ReadCustomers();
 23:         }
 24:         public void RemoveCustomer(int Id)
 25:         {
 26:             customerRepository.DeleteCustomer(Id);
 27:         }
 28:         #endregion
 29:     }
 30: }

Note that we never instantiate the customer repository that is to be used. Instead, in the constructor we accept a parameter of type ICustomerRepository, and we use that in the business component without caring about what the real implementation looks like. Thanks to constructor injection, the real object to be used will be injected by the caller.

Finally, modify Program.cs to test this:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using Castle.Windsor;
  6: namespace CastleExample
  7: {
  8:     class Program
  9:     {
 10:         private static IWindsorContainer container;
 11:         static void Main(string[] args)
 12:         {
 13:             // Register components
 14:             container = new WindsorContainer();
 15:             container.AddComponent<ICustomerBusiness,
 16:                             CustomerBusiness>("customer.business");
 17:             container.AddComponent<ICustomerRepository,
 18:                        MockCustomerRepository>("customer.repository");
 19:             // Use repository
 20:             UseRegisteredRepository();
 21:             // Use business
 22:             UseRegisteredBusiness();
 23:         }
 24:         public static void UseRegisteredRepository()
 25:         {
 26:             // Get the actual registered customer repository
 27:             ICustomerRepository customerRepository =
 28:                 container.Resolve<ICustomerRepository>();
 29:             customerRepository.ReadCustomers();
 30:         }
 31:         public static void UseRegisteredBusiness()
 32:         {
 33:             // Get the actual registered customer business
 34:             ICustomerBusiness customerBusiness =
 35:                container.Resolve<ICustomerBusiness>();
 36:             customerBusiness.GetCustomers();
 37:         }
 38:     }
 39: }

Now the Main method decides what business component will be used (CustomerBusiness), and what repository component will be used (MockCustomerRepository). When the CustomerBusiness object is created, Castle notices that it has a constructor that accepts an interface (ICustomerRepository) and injects the actual implementation for this interface as configured in the beginning of the Main method.

Run the application again to see if the second line in the console output is indeed MockCustomerRepository:

DI_07

To summarize, what we have done it enabled the client to choose which actual implementations of ICustomerBusiness and ICustomerRepository it wants to use. The business component itself only knows the interface of the repository, not the actual implementation. It means that we now have a way to easily change the implementation: a real client would register the real CustomerRepository, a unit test would register the MockCustomerRepository.

To demonstrate another form of injection, property injection, create a new class Tester that contains our testing methods and also two properties customerBusiness and customerRepository :

  1: public class Tester
  2: {
  3:   // These properties will be injected
  4:   public ICustomerBusiness customerBusiness { get; set;}
  5:   public ICustomerRepository customerRepository { get; set; }
  6:   public void UseRegisteredRepository()
  7:   {
  8:     // Get the actual registered customer repository
  9:     customerRepository.ReadCustomers();
 10:   }
 11: 
 12:   public void UseRegisteredBusiness()
 13:   {
 14:     // Get the actual registered customer business
 15:     customerBusiness.GetCustomers();
 16:   }
 17: }

and change the Main() method as follows:

  1: static void Main(string[] args)
  2: {
  3:   // Register components
  4:   container = new WindsorContainer();
  5:   container.AddComponent<ICustomerBusiness,
  6:          CustomerBusiness>("customer.business");
  7:   container.AddComponent<ICustomerRepository,
  8:          MockCustomerRepository>("customer.repository");
  9:   container.AddComponent<Tester, Tester>("tester"); 
 10:   Tester tester = container.Resolve<Tester>();
 11:   tester.UseRegisteredRepository();
 12:   tester.UseRegisteredBusiness();
 13: }

As you can see the Tester class has to properties that will be injected automatically by Castle when they are used.

Note however that the use of constructor injection is preferred, because when  you use this you have an explicit indication of a dependency that has to be fulfilled – you know it at compile time. If you use property injection, run-time exceptions may occur.

Use configuration file

In the previous example we used code to configure the container, but of course we have more flexibility if we would be able to do that in a configuration file.
Add a configuration file to the project, and add a section to configure Windsor Container:

  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:   <configSections>
  4:     <section
  5:         name="castle"
  6:         type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
  7:               Castle.Windsor" />
  8:   </configSections>
  9:   <castle>
 10:     <components>
 11:     </components>
 12:   </castle>
 13: </configuration>

Then add the components we need:

  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:   <configSections>
  4:     <section
  5:         name="castle"
  6:         type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
  7:               Castle.Windsor" />
  8:   </configSections>
  9:   <castle>
 10:     <components>
 11:       <component
 12:            id="customer.business"
 13:            service="CastleExample.ICustomerBusiness, CastleExample"
 14:            type="CastleExample.CustomerBusiness, CastleExample" />
 15:       <component
 16:           id="customer.repository"
 17:           service="CastleExample.ICustomerRepository, CastleExample"
 18:           type="CastleExample.MockCustomerRepository, CastleExample" />
 19:     </components>
 20:   </castle>
 21: </configuration>

Finally, we need to create the Windsor Container passing a configuration interpreter and a resource in the Main method:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using Castle.Core.Resource;
  6: using Castle.Windsor;
  7: using Castle.Windsor.Configuration.Interpreters;
  8: namespace CastleExample
  9: {
 10:     class Program
 11:     {
 12:         private static IWindsorContainer container;
 13:         static void Main(string[] args)
 14:         {
 15:             // Register components
 16:             container =
 17:                 new WindsorContainer(
 18:                     new XmlInterpreter(new ConfigResource("castle")));
 19: 
 20:             // Use repository
 21:             UseRegisteredRepository();
 22:             // Use business
 23:             UseRegisteredBusiness();
 24:         }
 25:         public static void UseRegisteredRepository()
 26:         {
 27:             // Get the actual registered customer repository
 28:             ICustomerRepository customerRepository =
 29:                 container.Resolve<ICustomerRepository>();
 30:             customerRepository.ReadCustomers();
 31:         }
 32:         public static void UseRegisteredBusiness()
 33:         {
 34:             // Get the actual registered customer business
 35:             ICustomerBusiness customerBusiness =
 36:                 container.Resolve<ICustomerBusiness>();
 37:             customerBusiness.GetCustomers();
 38:         }
 39:     }
 40: }

Run the application and it will now use the configuration file.

May 7, 2010 02:36 by lustuyck
E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Observable trackable collection in WPF

For a WPF application I needed a two-way binding between a DataGrid and a collection of business entities. First I used a simple ObservableCollection, and although the binding itself works fine, there is no fully built-in functionality to keep tracking information of added, changed or removed entities. So I decided to write a generic ObservableTrackableCollection. In my project I used the MVVM pattern: the ViewModel is bound to the view and uses the model entities.

Important to know first is that I wanted the model to be responsible for its validation. Here’s a simplified version of the SupplierModel:

  1: public class SupplierModel
  2: {
  3:     public int Id { get; set; }
  4:     public string Name { get; set; }
  5:     public string Description{ get; set; }
  6:     public string Address { get; set; }
  7:     public string Number { get; set; }
  8:     public int PaymentTerms { get; set; }
  9:     public string ValidationErrors
 10:     {
 11:         get
 12:         {
 13:             StringBuilder message = new StringBuilder();
 14:             message.Append(this["Name"]);
 15:             message.Append(this["PaymentTerms"]);               
 16:             return message.ToString();
 17:         }
 18:     }
 19:     public string this[string property]
 20:     {
 21:         get
 22:         {
 23:             string message = null;
 24:             switch (property)
 25:             {
 26:                 case "Name":
 27:                     if (string.IsNullOrEmpty(Name))
 28:                     {
 29:                         message = "Name is mandatory!";
 30:                     }
 31:                     break;
 32:                 case "PaymentTerms":
 33:                     if (PaymentTerms > 365)
 34:                     {
 35:                         message = "Payment terms shoud be smaller than or equal to 365!";
 36:                     }
 37:                     break;
 38:                 default:
 39:                     break;
 40:             }
 41:             return message;
 42:         }
 43:     }          
 44: }

The view model is bound to the DataGrid, so it implements INotifyPropertyChanged so that property changes can be detected by the binding mechanism, and also IDataErrorInfo so that validation errors can be detected. The view model exposes the model by encapsulating it. Validation is done  by delegating the validation task to the SupplierModel. Here’s the SupplierViewModel:

  1: public class SupplierViewModel : INotifyPropertyChanged, IDataErrorInfo
  2: {
  3:     public event PropertyChangedEventHandler PropertyChanged;       
  4: 
  5:     private SupplierModel supplier = null;
  6:    
  7:     public SupplierViewModel()
  8:     {
  9:         this.supplier = new SupplierModel();
 10:     }
 11:     public SupplierViewModel(SupplierModel supplier)
 12:     {
 13:         this.supplier = supplier;
 14:     }
 15:     protected void RaisePropertyChanged<T>(Expression<Func<T>> property)
 16:     {
 17:         PropertyChangedEventHandler handler = this.PropertyChanged;
 18: 
 19:         if (handler != null)               
 20:             handler(this, property.CreateChangeEventArgs());
 21:     }
 22:     public int Id
 23:     {
 24:         get { return supplier.Id; }
 25:         set { supplier.Id = value; RaisePropertyChanged(() => Id); }
 26:     }
 27:     public string Name
 28:     {
 29:         get { return supplier.Name; }
 30:         set { supplier.Name = value; RaisePropertyChanged(() => Name); }
 31:     }
 32:     public string Description
 33:     {
 34:         get { return supplier.Description; }
 35:         set { supplier.Description= value; RaisePropertyChanged(() => Description); }
 36:     }
 37:     public string Address
 38:     {
 39:         get { return supplier.Address; }
 40:         set { supplier.Address = value; RaisePropertyChanged(() => Address); }
 41:     }
 42:     public string Number
 43:     {
 44:         get { return supplier.Number; }
 45:         set { supplier.Number = value; RaisePropertyChanged(() => Number); }
 46:     }
 47:     public int PaymentTerms
 48:     {
 49:         get { return supplier.PaymentTerms; }
 50:         set { supplier.PaymentTerms = value; RaisePropertyChanged(() => PaymentTerms); }
 51:     }      
 52:     #region IDataErrorInfo Members
 53:     /// <summary>
 54:     /// A summary of the errors for the supplier object. The supplier model takes care of the
 55:     /// actual validation, and its results is used by the view model to update the validation state.
 56:     /// </summary>
 57:     public string Error
 58:     {
 59:         get
 60:         {
 61:             return supplier.ValidationErrors;
 62:         }
 63:     }
 64:     public string this[string property]
 65:     {
 66:         get
 67:         {               
 68:             return supplier[property];
 69:         }
 70:     }
 71:     #endregion      
 72: }
 73: 

As you see, every time a property is set, RaisePropertyChanged is used to indicate a change. It uses the following extension method CreateChangeEventArgs:

  1: public static class PropertyExtensions
  2: {
  3:     public static PropertyChangedEventArgs CreateChangeEventArgs<T>(this Expression<Func<T>> property)
  4:     {
  5:         var expression = property.Body as MemberExpression;
  6:         var member = expression.Member;
  7:         return new PropertyChangedEventArgs(member.Name);
  8:     }
  9: }

This way we don’t have to use strings when notifying a property has changed and we avoid runtime errors if we mistype something.

I also have a MainViewModel, to which the DataCOntext of the view is set. This view model contains a ObservableTrackableCollection<SupplierViewModel> property, which is bound to the DataGrid on the view.

  1: public class MainViewModel
  2: {
  3:     private ObservableTrackableCollection<SupplierViewModel>
  4:                   suppliers = new ObservableTrackableCollection<SupplierViewModel>();
  5:      public MainViewModel()
  6:     {
  7:         Suppliers.ItemsAdded += new ObservableTrackableCollection<SupplierViewModel>.CollectionItemHandler(Suppliers_ItemsAdded);
  8:         Suppliers.ItemsRemoved += new ObservableTrackableCollection<SupplierViewModel>.CollectionItemHandler(Suppliers_ItemsRemoved);
  9:         Suppliers.ItemPropertyChanged += new ObservableTrackableCollection<SupplierViewModel>.ItemPropertyHandler(Suppliers_ItemPropertyChanged);
 10:     }
 11:     public ObservableTrackableCollection<SupplierViewModel> Suppliers
 12:     {
 13:         get { return suppliers; }
 14:     }       
 15:     void Suppliers_ItemPropertyChanged(object sender, ItemPropertyEventArgs args)
 16:     {
 17:         System.Diagnostics.Debug.WriteLine("changed: " + args.PropertyName);
 18:     }
 19:     void Suppliers_ItemsRemoved(object sender, CollectionItemEventArgs<SupplierViewModel> args)
 20:     {
 21:         foreach (var item in args.CollectionItems)
 22:         {
 23:             System.Diagnostics.Debug.WriteLine("removed: " + item.Name);
 24:         }
 25:     }
 26:     void Suppliers_ItemsAdded(object sender, CollectionItemEventArgs<SupplierViewModel> args)
 27:     {
 28:         foreach (var item in args.CollectionItems)
 29:         {
 30:             System.Diagnostics.Debug.WriteLine("added: " + item.Name);
 31:         }           
 32:     }
 33: 
 34:     public void LoadSuppliers()
 35:     {
 36:         IList<SupplierModel> supplierList = SupplierRepository.GetSuppliers();
 37:         foreach (SupplierModel supplier in supplierList)
 38:         {
 39:             suppliers.Add(new SupplierViewModel(supplier));
 40:         }
 41:         suppliers.ResetTrackInfo();
 42:     }
 43:     private DelegateCommand saveSuppliersCommand;
 44:     public ICommand SaveSuppliersCommand
 45:     {
 46:         get
 47:         {
 48:             if (saveSuppliersCommand == null)
 49:             {
 50:                 saveSuppliersCommand = new DelegateCommand(SaveSuppliers, CanSaveSuppliers);
 51:             }
 52:             return saveSuppliersCommand;
 53:         }
 54:     }
 55: }

As you can see, thanks to the ObservableTrackableCollection we have a number of built-in features:

  • events like ItemsAdded, ItemsRemoved, ItemPropertyChanged allow the view model to be informed of changes
  • the property IsCollectionValid is true when every item in the collection validates, or false when there is at least one error
  • the GetChanges method allows us to get the added, modified, deleted and original entities in the collection
  • the ResetTrackInfo sets the track information of all collection items to ‘not modified’.

Note that I use the model’s SupplierRepository to fill the suppliers collection with SupplierModel items, using a service:

  1: public class SupplierRepository
  2: {
  3:     public static IList<Schepers.Client.SCSA.Models.SupplierModel> GetSuppliers()
  4:     {
  5:         StockServiceReference.StockServiceClient client = new StockServiceClient();
  6:         GetSuppliersResponse response = client.GetSuppliers(new GetSuppliersRequest() { });
  7:         client.Close();
  8:         IList<SupplierModel> suppliers = response.Suppliers.TransformList<StockServiceReference.Supplier, SupplierModel>();
  9:         return suppliers;
 10:     }
 11: }

And here is the implementation of my ObservableTrackableCollection:

  1: /// <summary>
  2: /// An ObservableTrackableCollection is an observable collection of a
  3: /// generic type with tracking capabilities. The generic type has to
  4: /// implement INotifyPropertyChanged so that the ObservableTrackableCollection
  5: /// is notified when a property of the type changed. It also has to
  6: /// implement IDataErrorInfo, to that it is able to validate its collection
  7: /// items.
  8: /// </summary>
  9: /// <typeparam name="T">Type that collection consists of.</typeparam>
 10: public class ObservableTrackableCollection<T> : ObservableCollection<T>
 11:     where T : INotifyPropertyChanged, IDataErrorInfo
 12: {
 13:     // Delegate for collection handler
 14:     public delegate void CollectionItemHandler(object sender, CollectionItemEventArgs<T> args);
 15:     public delegate void ItemPropertyHandler(object sender, ItemPropertyEventArgs args);
 16:     // Events
 17:     public event CollectionItemHandler ItemsAdded;
 18:     public event CollectionItemHandler ItemsRemoved;
 19:     public event ItemPropertyHandler ItemPropertyChanged;
 20:     /// <summary>
 21:     /// True if all collection items validate, false if there is a validation
 22:     /// error in one or more items. It uses the IDataErrorInfo implementation of
 23:     /// the entities to do this validation.
 24:     /// </summary>
 25:     public bool IsCollectionValid
 26:     {
 27:         get
 28:         {
 29:             bool areErrors = false;
 30:             foreach (IDataErrorInfo item in this)
 31:             {
 32:                 if (item.Error != string.Empty)
 33:                 {
 34:                     areErrors = true;
 35:                     break;
 36:                 }
 37:             }
 38:             return !areErrors;
 39:         }
 40:     }
 41:     /// <summary>
 42:     /// Occurs when items have been added to the collection.
 43:     /// </summary>
 44:     /// <param name="sender"></param>
 45:     /// <param name="args"></param>
 46:     protected void OnItemsAdded(object sender, CollectionItemEventArgs<T> args)
 47:     {
 48:         if (ItemsAdded != null)
 49:         {
 50:             ItemsAdded(sender, args);
 51:         }
 52:     }
 53:     /// <summary>
 54:     /// Occurs when items have been removed from the collection.
 55:     /// </summary>
 56:     /// <param name="sender"></param>
 57:     /// <param name="args"></param>
 58:     protected void OnItemsRemoved(object sender, CollectionItemEventArgs<T> args)
 59:     {
 60:         if (ItemsRemoved != null)
 61:         {
 62:             ItemsRemoved(sender, args);
 63:         }
 64:     }
 65:     /// <summary>
 66:     /// Occurs when a property has been changed.
 67:     /// </summary>
 68:     /// <param name="sender"></param>
 69:     /// <param name="args"></param>
 70:     protected void OnItemPropertyChanged(object sender, ItemPropertyEventArgs args)
 71:     {
 72:         if (ItemPropertyChanged != null)
 73:         {
 74:             ItemPropertyChanged(sender, args);
 75:         }
 76:      }
 77:     // List of all trackable objects.
 78:     private List<Trackable<T>> items = new List<Trackable<T>>();
 79:     /// <summary>
 80:     /// Occurs when an item has been added to or removed from the observable collection.
 81:     /// </summary>
 82:     /// <param name="e"></param>
 83:     protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
 84:     {
 85:         base.OnCollectionChanged(e);
 86:         switch (e.Action)
 87:         {
 88:             case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
 89:                 // One or more items have been added.                   
 90:                 IList<T> addedCollectionItems = new List<T>();
 91:                 foreach (var item in e.NewItems)
 92:                 {
 93:                     // Add item to trackable collection.
 94:                     Trackable<T> trackable = new Trackable<T>((T)item, TrackingState.Added);
 95:                     items.Add(trackable);
 96:                     addedCollectionItems.Add((T)item);
 97:                     // Every time a new item is inserted, attach a PropertyChangedEventHandler so that we can
 98:                     // track property changes of the item.
 99:                     ((T)item).PropertyChanged += new PropertyChangedEventHandler(ObservableTrackableCollection_PropertyChanged);
100:                 }
101:                 OnItemsAdded(this, new CollectionItemEventArgs<T>(addedCollectionItems));
102:                 break;
103:             case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
104:                 // One or more items have been deleted.
105:                 IList<T> removedCollectionItems = new List<T>();
106:                 foreach (T item in e.OldItems)
107:                 {
108:                     Trackable<T> trackable = items.Find(t => t.Item.Equals(item));
109:                     switch (trackable.TrackingState)
110:                     {
111:                         case TrackingState.Unmodified:
112:                         case TrackingState.Changed:
113:                             // Item was original or modified, and then deleted.
114:                             trackable.TrackingState = TrackingState.Removed;
115:                             break;
116:                         case TrackingState.Added:
117:                             // Item was added and then deleted, no need to track it anymore.
118:                             items.Remove(trackable);
119:                             break;
120:                         default:
121:                             break;
122:                     }
123:                     removedCollectionItems.Add((T)item);
124:                 }
125:                 OnItemsRemoved(this, new CollectionItemEventArgs<T>(removedCollectionItems));
126:                 break;
127:             case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
128:                 throw new NotImplementedException("Replace not yet handled.");
129:         }
130:     }
131:     /// <summary>
132:     /// Occurs when a property has changed.
133:     /// </summary>
134:     /// <param name="sender"></param>
135:     /// <param name="e"></param>
136:     void ObservableTrackableCollection_PropertyChanged(object sender, PropertyChangedEventArgs e)
137:     {
138:         // Mark as modified only if it was original item.      
139:         Trackable<T> trackable = items.Find(t => t.Item.Equals(sender));
140:         switch (trackable.TrackingState)
141:         {
142:             case TrackingState.Unmodified:
143:                 trackable.TrackingState = TrackingState.Changed;
144:                 break;
145:             default:
146:                 break;
147:         }
148:         OnItemPropertyChanged(this, new ItemPropertyEventArgs(e.PropertyName));
149:     }
150:     /// <summary>
151:     /// Resets tracking information of all items in the collection.
152:     /// </summary>
153:     public void ResetTrackInfo()
154:     {
155:         foreach (Trackable<T> trackable in items)
156:         {
157:             trackable.TrackingState = TrackingState.Unmodified;
158:         }
159:     }
160:     /// <summary>
161:     /// Gets changes in the collection for specified track state.
162:     /// </summary>
163:     /// <param name="trackingState">Tracking state.</param>
164:     /// <returns>List of changed items in collection.</returns>
165:     public List<T> GetChanges(TrackingState trackingState)
166:     {
167:         var results = from i in items
168:                       where i.TrackingState == trackingState
169:                       select i.Item;
170:         return results.ToList<T>();
171:     }
172:     /// <summary>
173:     /// This class is used by ObservableTrackableCollection to enable tracking of
174:     /// items of type U.
175:     /// </summary>
176:     /// <typeparam name="U">Type to track.</typeparam>
177:     private class Trackable<U>
178:     {
179:         public Trackable(U item, TrackingState trackingState)
180:         {
181:             Item = item;
182:             TrackingState = trackingState;
183:         }
184:         public U Item;
185:         public TrackingState TrackingState;
186:     }
187: }
188: 
189: /// <summary>
190: /// Tracking states.
191: /// </summary>
192: public enum TrackingState
193: {
194:     /// <summary>
195:     /// Indicates that an item is not changed, deleted or added.
196:     /// </summary>
197:     Unmodified,
198:     /// <summary>
199:     /// Indicates an item was changed.
200:     /// </summary>
201:     Changed,
202:     /// <summary>
203:     /// Indicates an item was removed.
204:     /// </summary>
205:     Removed,
206:     /// <summary>
207:     /// Indicates an item was added.
208:     /// </summary>
209:     Added
210: };
211: 
212: /// <summary>
213: /// EventArgs for collection items.
214: /// </summary>
215: /// <typeparam name="T"></typeparam>
216: public class CollectionItemEventArgs<T> : EventArgs
217: {
218:     public IList<T> CollectionItems { get; set; }
219:     public CollectionItemEventArgs(IList<T> collectionItems)
220:     {
221:         this.CollectionItems = collectionItems;
222:     }
223: }
224: /// <summary>
225: /// EventArgs for item properties.
226: /// </summary>
227: public class ItemPropertyEventArgs : EventArgs
228: {
229:     public string PropertyName { get; set; }
230:     public ItemPropertyEventArgs(string propertyName)
231:     {
232:         this.PropertyName = propertyName;
233:     }
234: }

This is my first version, so it may be improved, but the general idea is that this generic ObservableTrackableCollection gives you validation and tracking capabilities, but that each component in the MVVM pattern still has its own responsability: the model contains model data and validation logic, the view model encapsulates this model and contains everything that is needed by the view like for example property change notifications, properties the view can bound too, etc…

May 7, 2010 02:27 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Creating a database table with zip codes

Today I needed a database table in Sql Server that contains all belgian zip codes and city names. Obviously I was not going to create this by hand, so I wanted to share how I did it because I think it’s a common requirement.

The first step was to find a list of zip codes and city names. On the site http://www.post.be/site/nl/residential/customerservice/search/postal_codes.html you can download this list in excel format. From this file I extracted the zipcode and city name and saved this as a csv-file, which then looked like:

1000;Brussel
1000;Bruxelles
1005;Ass. Réun. Com. Communau. Commune
1005;Brusselse Hoofdstedelijke Raad
1005;Conseil Region Bruxelles-Capitale
1005;Ver.Verg.Gemeensch.Gemeensch.Comm.
1006;Raad Vlaamse Gemeenschapscommissie
etc... 

The second step was to create the database table that will contain this information, so I created a table called City with the following columns:

ZipCode, int
Name, varchar(100)

The next step was the actual import from the csv file into the table. To do this, I used the bulk copy technique: just open a new query window and execute the following statement:

  1: BULK
  2: INSERT City
  3: FROM 'd:\postcodes.csv'
  4: WITH
  5: (
  6:   FIELDTERMINATOR = ';',
  7:   ROWTERMINATOR = '\n'
  8: )

And now the table City is filled with 2903 records:

zip_01

As a last step I added another column as the primary key:

Id, int, primary key (identity)

And now each entry has a primary key:

zip_02

I think this is probably the easiest way to create a table with zip codes and city names.

May 7, 2010 02:24 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

ASP.NET MVC QuickStart 8: partial updates using jquery

Objectives

In this Hands-On Lab, you will learn how to do partial updates in JSON format using jquery. In particular, you will:
- Task 1: add new controller action and view
- Task 2: add controller action method to get list of members
- Task 3: add jquery to populate members combo box
- Task 4: show member details

System requirements

You must have the following items to complete this lab:
- Microsoft Visual Studio 2008 SP1 (professional edition)
- Microsoft ASP.NET MVC 1.0

Prequisites

You must have the following skills to understand this lab:
- Fundamental knowledge of software development in .NET 3.5
- Some experience in ASP.NET web development
This lab builds further on the QuickStart 7 code.

Task 1: add new controller action and view

We are going to create a new page that has a combo box containing all member last names, and the details of the selected member. First add a new controller action to the MembersController:

  1: public ActionResult Index2()
  2: {
  3:     // return this list to the default view
  4:     return View();
  5: }

Also add a view for this action method:

ASPNETMVC_QS8_01

In this case we are not going to create a strongly typed view because the needed data will be retrieved asynchronously using jquery.

Modify the generated view. First, place a combo box in the view:

  1: <%@ Page Title="" Language="C#"
  2:          MasterPageFile="~/Views/Shared/Site.Master"                                                  
  3:          Inherits="System.Web.Mvc.ViewPage" %>
  4: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
  5:              runat="server">
  6:   Index2
  7: </asp:Content>
  8: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
  9:              runat="server">
 10:     <h2>Index2</h2>
 11: 
 12:     <% <select id="MembersDropDownList" />
 13: </asp:Content>

To fill this combo box with members using AJAX, we have to:

  • Add a controller action method that returns a list of members
  • Write some jquery that uses the controller action method to populate the combo box when the page has been rendered

We will do this in the next tasks.

Task 2: add controller action method to get list of members

Add a new action method called GetCustomers to the MembersController:

  1:  public JsonResult GetMembers()
  2: {
  3:     // Get a list of members using the model
  4:     List<Member> members = MemberService.GetMembers();
  5: 
  6:     // Return list of members as JSON
  7:     return this.Json(members);
  8: }

As you see this method returns a different type of action result: a JsonResult. It’s in JSON format, which is a lightweight data-interchange format (see http://json.org).

Task 3: add jquery to populate members combo box

Now we have to consume the JSON data and populate the combo box with members.

First we need references to the jquery javascript libraries, so open up the Site.Master and add the needed references:

  1: <head runat="server">
  2:   <title>
  3:     <asp:ContentPlaceHolder ID="TitleContent" runat="server" />
  4:   </title>
  5:   <link href="../../Content/Site.css" rel="stylesheet"
  6:         type="text/css" />
  7:   <script src="/Scripts/jQuery-1.3.2.js"
  8:           type="text/javascript"></script>
  9:   <script src="/Scripts/jquery-1.3.2.min.js"
 10:           type="text/javascript"></script>
 11: </head>

Open the Index2 view. To retrieve the list of members when the DOM of the page is loaded and to populate the combo box with these members, we can write the following  jquery:

  1: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
  2:              runat="server">
  3:     <script type="text/javascript">
  4:         $(document).ready(function()
  5:         {       
  6:             // if the DOM is loaded, start retrieving the members
  7:             $.getJSON(
  8:                 "/Members/GetMembers", null, function(data)
  9:                 {
 10:                     addMembers(data);
 11:                 })       
 12:         });
 13:         function addMembers(data)
 14:         {
 15:             // Get the DOM reference to the drop-down list.        
 16:             var membersDropDownList = $("#MembersDropDownList");
 17: 
 18:             // Loop through each member and populate the combo box.           
 19:             $.each(data, function(index, optionData) {
 20:                 membersDropDownList.append("<option value='"
 21:                     + optionData.ID
 22:                     + "'>" + optionData. LastName                                               
 23:                     + "</option>");
 24:             });       
 25:         };
 26:     </script>
 27:     <h2>Index2</h2>
 28: 
 29:     <select id="MembersDropDownList" />
 30: 
 31: </asp:Content>

Take your time to study and understand the jquery syntax.

Now start the application and go to the page “/members/index2”. If everything works, the combo box should be populated:

ASPNETMVC_QS8_02

Task 4: show member details

Finally, we want to show the details of the selected member. The first step to do that is to provide a new action member for the MemberController that retrieves the details of a member. So add the following action method to the MemberController:

  1: public JsonResult GetMemberDetails(int memberID)
  2: {  
  3:     // Get member details using model
  4:     Member m = MemberService.GetMember(memberID);
  5:     // Return list of members as JSON
  6:     return this.Json(m);
  7: }

The next thing is to make sure that when the selected combo box item changes, the member details are updated. Again, we will do that with jquery:

  1: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
  2:              runat="server">
  3:     <script type="text/javascript">
  4:         $(document).ready(function()
  5:         {       
  6:             $.getJSON(
  7:                 "/Members/GetMembers", null, function(data)
  8:                 {
  9:                     addMembers(data);
 10:                 })
 11: 
 12:             var membersDropDownList = $("#MembersDropDownList");
 13:             membersDropDownList.change(function() {                                
 14:                 populateDetails(this.value);
 15:             })
 16:         });
 17:         function populateDetails(id)
 18:         {
 19:             $.getJSON("/Members/GetMemberDetails",
 20:                 {memberID : id }, function(data) {                
 21:                     $("#FirstName").html(data.FirstName);
 22:                     $("#LastName").html(data.LastName);
 23:                 });
 24:         }
 25:         function addMembers(data)
 26:         {
 27:             // Get the DOM reference to the drop-down list.        
 28:             var membersDropDownList = $("#MembersDropDownList");
 29: 
 30:             // Loop through each member and populate the combo box.           
 31:             $.each(data, function(index, optionData) {
 32:                 membersDropDownList.append("<option value='"
 33:                     + optionData.ID
 34:                     + "'>" + optionData.LastName
 35:                     + "</option>");
 36:             });       
 37:         };
 38:     </script>
 39:     <h2>Index2</h2>   
 40: 
 41:     <select id="MembersDropDownList"></select>
 42: 
 43:     <p />
 44: 
 45:     <div>First name: <span id="FirstName"></span></div>
 46:     <div>Last name: <span id="LastName"></span></div>              
 47: </asp:Content>

Start the application again, go to the page “/members/index2” and select another member. The details should become visible:

ASPNETMVC_QS8_03

One thing left: when we initially load this page, the member details are not filled in. To solve that, just add the following line of code:

  1: <script type="text/javascript">
  2:         $(document).ready(function()
  3:         {       
  4:             $.getJSON(
  5:                 "/Members/GetMembers", null, function(data)
  6:                 {
  7:                     addMembers(data);
  8:                     populateDetails(membersDropDownList.val());
  9:                 })
 10: 
 11:             var membersDropDownList = $("#MembersDropDownList");
 12:             membersDropDownList.change(function() {                                
 13:                 populateDetails(this.value);
 14:             })                                                                  
 15:         });
 16: </script>
 17: 
If you try it now, the member details will be visible when the page is first loaded
May 7, 2010 02:14 by lustuyck
E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed