Dataset Vs custom object (Entity)

Labels:

Dataset

A dataset is a class in .Net representing the structure similar of a SQL database. It contains one or more tables. You can create typed dataset, it's a class which inherits from the base class dataset and have tables with specified name, columns with specified names and types. It's very easy to create with Visual Studio, in the server explorer window when you are connected to a database, you simply create a new dataset and you drag and drop the tables you need. Next you run a query against a database or via a table adapter and you fill this dataset, it's very easy. A dataset implements all the interfaces for databinding such as IErrorDataInfo, INotifyPropertyChanged, ... (see Databinding and error validation in WinForm).

Custom object (Entity)

A custom object is a class that your write by your own. It contains properties (generally no business code) and basic validations (see Databinding and error validation in WinForm). You run a query against a database and you map SQL columns to the properties of your custom classes.

Why to use dataset or custom object (Entity)

A dataset is very easy and is rapidly created but there are some problems for big projects :

  • A dataset is a fixed structure, if you have a SQL table person and in the future you have in this SQL table more than one type of person, a seller and a buyer you can't do inheritance with datatable.
  • If you plan to do a web service returning data, dataset is a big structure, if your table contains only one row of data with one column, the XML result of your web service contains more data for the definition of the dataset than for the data itself.
  • Also for web service, dataset is a class of the .Net framework and it doesn't exist in other platform, it is not WSI compliant, and it will be very difficult for not .Net client to use it.

Custom object doesn't have this problem :

  • A custom object is a basic class and you can do inheritance, you can create a class person and in the future create 2 classes, one Buyer and other one Seller and these classes inherit from the class Person. So you can benefit of polymorphism and you don't have maintenance problems.
  • Into web service, the XML output contains only properties which contains data and no more and the definitions is very small.
  • Custom object produces basic XML output WSI compliant if you use properties in your custom object which contains only primitive types or other custom objects which also contain properties with primitive types or custom objects ... You can also create properties defined as list, collection, ... and these properties will be transformed to XML array.

Conclusion

For small projects dataset is a good choice, you can create rapidly an application with databinding. Pay attention that if you create a web service it's only for .Net clients.

For big projects dataset can lead to maintenance, evolution problems, it'll be difficult to change an existing dataset, the only solution will be to create a new one. With custom object we can make inheritance, create interfaces, ... to have a flexible design for future changes. It takes at the beginning a little more time to start the project in comparison with dataset because you need to create your objects and implements the necessary interfaces if you want to take advantages of databinding (see Databinding and error validation in WinForm). But now with linq and linq to SQL it's more easier to work with custom objects.







Databinding and error validation in WinForm

image

I write this post because I have searched a long time before to obtain an acceptable result with error validation and databinding.

With databinding and a little bit of code you can obtain the result from the screen shot rapidly and this code is very stable.

The first step is to write our business object, in this sample the class Person with 2 properties "Lastname" and "Firstname".

Next via the datasource window we drag and drop the first name and last name property into the window. The error property in the following screen shot will be explained later.

image

Next to show errors on our winform we add an error provider to the window and we can set the current error for each control via the validate event of each control but it's long and it's for each new form with the same object.

The error provider component have a property datasource, we can bind to it a dataset and it will show errors into data grid but for custom object?

You have to implement the interface IDataErrorInfo. This interface have 2 get properties Error and an indexer with a string as key. The error property return a message saying if the whole object have one or more errors, the indexer return for a property if the property is good or not. When a bound control lose focus, it will read the indexer property and the string parameter will be the property name to check, if we return a string different of null or empty, the property is in error state and the error provider will show it.

See the implementation of the Person class:

 

   1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using System.ComponentModel;

    5 

    6 namespace DataBindingTest

    7 {

    8     class Person : IDataErrorInfo

    9     {

   10         private Dictionary<string, string> errors = new Dictionary<string, string>();

   11 

   12         private string error = string.Empty;

   13 

   14         private string lastname;

   15         private string firstname;

   16 

   17         private void Validate(string field, string value)

   18         {

   19             switch (field)

   20             {

   21                 case "Lastname":

   22                     if (String.IsNullOrEmpty(value))

   23                     {

   24                         this.errors["Lastname"] = "There is an error";

   25                     }

   26                     else

   27                     {

   28                         this.errors.Remove("Lastname");

   29                     }

   30                     break;

   31                 case "Firstname":

   32                     if (String.IsNullOrEmpty(value))

   33                     {

   34                         this.errors["Firstname"] = "There is an error";

   35                     }

   36                     else

   37                     {

   38                         this.errors.Remove("Firstname");

   39                     }

   40                     break;

   41                 default:

   42                     break;

   43             }

   44         }

   45 

   46         public string Lastname

   47         {

   48             get

   49             {

   50                 this.Validate("Lastname", this.lastname);

   51                 return this.lastname;

   52             }

   53 

   54             set

   55             {

   56                 this.lastname = value;

   57                 this.Validate("Lastname", this.lastname);

   58             }

   59         }

   60 

   61         public string Firstname

   62         {

   63             get

   64             {

   65                 this.Validate("Firstname", this.firstname);

   66                 return this.firstname;

   67             }

   68 

   69             set

   70             {

   71                 this.firstname = value;

   72                 this.Validate("Firstname", this.firstname);

   73             }

   74         }

   75 

   76         #region IDataErrorInfo Members

   77 

   78         public string Error

   79         {

   80             get

   81             {

   82                 if (this.errors.Count > 0)

   83                 {

   84                     return "There are " + this.errors.Count + " errors";

   85                 }

   86 

   87                 return null;

   88             }

   89         }

   90 

   91         public string this[string columnName]

   92         {

   93             get

   94             {

   95                 if (this.errors.ContainsKey(columnName))

   96                 {

   97                     return this.errors[columnName];

   98                 }

   99                 else

  100                 {

  101                     return null;

  102                 }

  103             }

  104         }

  105 

  106         #endregion

  107     }

  108 }

 

This method is good for basic validation such as null, length, regex validation.

Now if you change the property of our custom object via business code, it will not be reflected directly to the screen. The binding source doesn't know that the value has changed. The solution is to implement the interface INotifyPropertyChanged, it will declare the event PropertyChanged on your class. Then you raise this event giving to it the name of the property into the setter of all of the properties of the Person class and now the binding source will be notified of the change and refresh it on the screen.

61 public string Firstname

   62         {

   63             get

   64             {

   65                 this.Validate("Firstname", this.firstname);

   66                 return this.firstname;

   67             }

   68 

   69             set

   70             {

   71                 this.firstname = value;

   72                 if (this.PropertyChanged != null)

   73                 {

   74                     this.PropertyChanged(this, new PropertyChangedEventArgs("Firstname"));

   75                 }

   76                 this.Validate("Firstname", this.firstname);

   77             }

   78         }

There are a lot of interfaces you can implement to have your live easier...





Team foundation : Area and iteration

I write this entry because I don't know the best way to use area and iteration in Team Foundation.

Area

For the area, there is no problem, nearly everyone says that an area is a part of the project, a component for sample a project's areas into a project can be the UI, a webservice with sub areas.
There is an article on msdn blog about when to use Team project and area "When to use Team Projects"

Iteration

For the iterations I have read 2 solutions, one is that each iteration is a version of project so V1.0, V1.1, ...

The other solution is that the iteration is analyze, development, test, demo, release, ...

I found an idea on this post "My 2 cents on Areas and Iterations in Team Foundation Server" to combine the 2 as this :

\Project
  \V 1.0
     \dev
     \test
     \demo
  \V 2.0
     \dev
     \test
     \demo





Team Foundation structure

Labels:

One advantage with Team Foundation is that it offers a lot a functions such as label, branching, merge, ... but how to use it?

My First approach, bad one

image 

My first approach was to create a branch and to work on this branch and before each release, make a merge to the main and then delete the branch. So if a bug occurred into the current release, I can correct it into the main.

But there are problems:

  • I delete the working branch before each release, by this way I always lose the history of my source files
  • If a bug occurs into the current release, I correct it into the main, but how to merge it into the working branch? It's possible to merge a branch to a baseline, the version from which the branch comes from, not in the other direction, so unable to apply the correction into the working branch.
An other approach

image

This approach is better, it's not the only one but this is the simplest way for little team.

The main is the current working branch and after each release, in this case we don't merge but we do a branch with the name of the release (version), so I keep my history into the current working branch and I can merge a bug fix from a release branch to the main/working branch.

There is a good document which explains this structure with other on Codeplex

Mots clés Technorati : ,,,,




The continuous integration

Labels:

Definition and usability

The integration for people that don't know what is it, the goal is to take all the source code, to build and to do all the unit tests to see if all is correct, that all things make a coherent project. Continuous says that we will do an integration as much as possible. Why? See by a concrete sample. Imagine that we have the 2 following classes: 

image

We have 2 developers X and Y, each having the latest version of the files. The method "StartRace" of the class CarRider makes a call on the method "SpeedUp" of the class Car. Now the developer X modifies and adds a parameter on the method "SpeedUp", he will also change the call of this method into the class "CarRider" and the developer Y add a class "TrustControlEngine" with a method "RegularSpeed" which calls the method "SpeedUp" of the class "Car". We have the following situation: 


Developer X
image
Developer Y
image


For the moment  the code builds for each developer, now imagine that the situation stays 2 months in this state and then they want to put the application in production, the result of the build would be catastrophic. This is evident that the code doesn't build anymore because the class "TrustControlEngine" uses the method "SpeedUp" without parameter. The continuous integration is necessary and we don't need to do it by hand, there are tools that can automate this work.

The tools

There are many tools, for the moment I know 2 tools:

The tools to do continuous integration take the latest version of all the files from a source control and check that all builds, it is possible to configure the tools to run unit tests, to analyze code, to run code coverage, ... These steps can be executed when there is a detection of check-in of after a defined elapsed time. The tool notifies us by mail (for sample) the result of the integration.

Sample of a structure that I setup with some tools: 
image





The process of the development by iteration

Labels:

The development's process is made of some steps that we do to create our software. The process that was very used in the past and that seems natural is the process named "Waterfall" by comparison  with a water fall. In this process we begin by all the analysis, next by all the development, next all the tests, next the demo and the the release. That can be illustrated as :
image 
One of the big problem with this method is that we see a problem too late, what we do if when we show the application to the end user if this one says that the application doesn't meet his need because we misunderstood what he wanted and this has an impact to the rest of the application, we redo all?

The process by iteration can solve this problem, we split the work into small steps where an iteration is made of the same steps as the "Waterfall"  but for a functionality of the application, an use case. We will do a little of analysis, a little of development, a little of test, a little of demo and one release for this use case. In this case if the user explains to us that there is a problem, we correct only this part of the analysis, the rest is analyzed into the next iteration.
image
This method has more advantages:

  • It is easy to adapt, correct a bad situation
  • More regular refactoring of the code
  • More regular feed back of the end user
  • Show to the end user the advancement of the project
  • ...




Unit test

Labels:

Definition

A test by definition everyone knows what it is. The most important here is "unit", "unit" for an unit, an unit test is a test which will test an unit of independent code of an other. The test must verify the good working of a method for a specific case.

The unit test is not done by the end user of the project but code that will test the code of the software that you are building. At the first look it seems odd but when you do it one time, you will want to do it always.

 

How to do it
Steps

All steps are a part of the following iteration:

  • Decide a method to write
  • Create a tests list
  • Take a test from the list and implement it
  • Check that the test code builds and check that the result of the test is red
  • Implement the code (doing refactoring if we are not at the first iteration) which will change the result of the test to green
  • Run the test and check that the result of the test is green
Sample

    We will decide to write a method to do a division of 2 numbers. In the code we write only the signature of the method and the minimum so the code builds:
    public double Divide(int a, int b):image 

  • I create the following tests list ::
    • To check that the division of the 2 numbers is correct
    • To check that the division by 0 throws the good exception.
      • The tests list must cover at least the documentation of the method that we are writing, it is the contract of the method. It is possible that you add documentation to the method when writing the test.
        image
        next delete the automatic created class in this project and add a new Unit Test
        image 
        The next screen lets you choose different classes, choose the method to test
        image The skeleton of the test is now created
        image We adapt the code to check that the result of the division of 6 by 2 is well 3 and we run the test to check that it builds and that is red.
        image Now we adapt the code so the result is green, we write only the code to make the test become green and no more code, it's important so all the code is tested.
        image Now we take the next test and we do the same steps, write the test, checks that it's red, implements the code and now we can also do refactoring and we finally check that the test is green.
        image 
Schema of the itiration

image