Browsing:

Month: June 2011

Really really back to basics: Intro to OOP: C# classes. (And intro to Linq to XML as well).

Here's an intro to OOP in C# for those who are interested. It's a real world example.
I have a bunch of SQL Servers and I need to execute some SP's on their databases. The configuration information is stored in an XML file. I want to solve this problem in an OOP way. So we need to create a class and instantiate objects from that class.

Obviously, there should be a class named Database server or something like that, and it has properties (or variables, or fields).

Creating the class

First let's create a class:

public class DbServer {

}

Creating its properties

Then, we will define its properties:

public class DbServer {
private string _name;
private string _instance;
private string _database;
private string _username;
private string _password;
}

Why are they private? That is to make sure that these variables can only be manipulated from inside the class.
But what is that good for? These values should be queried, right?
Indeed. That's why public properties will be exposed to them as well:


public class DbServer {

private string _name;
private string _instance;

public string Name {
get { return _name; }
set { _name = value; }
}

public string Instance{
get { return _instance; }
set { _name = value; }
}

Why then, go through all this and not just make the fields public from the start?!
No, this is one of the principles of OOP: Encapsulation. There are some benefits to encapsulation:

  • Preventing unauthorized access to the data
  • Ensuring data integrity through error checking
  • Creating read only properties

Let's alter the code a bit:

public string Name {
   get {
        return _name;
         } 
   set {
   //should not be empty        
       if (value.Length < 1 ) {
        throw new Exception("Servername cannot be empty");
         } else {
         _name = value;                    
          }
   }          
 }           

There, I added a business rule. It would also be nice to add some more regex to the class and throw appropriate exceptions.

here's how to make the property read-only by omitting the 'setter' and for the 'getter' to actually fetch the data from a database, or as in this scenario, from an XML file:

public string Instance
    {
       get
          {
            _instance = getElement().Element("instance").Value;
             return _instance;
           }
      }

Auto-Implemented Properties

In cases when there would be more trivial properties when there is no additional logic required, you can use auto-implemented properties. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.


public class DbServer {

public string Name { get; set; }
public string Instance { get; set; }

}

In this way, the properties are mutable by other client code.
But what if you would fetch the Instance value from a database or an XML file?

Then the code would be as follows:


public class DbServer {

public string Name { get; private set };

public string Instance
  { 
    get
     {  
          return getElement().Element("instance").Value; 
      }  
 }

//the constructor
public DbServer (string name) 
{
    Name = name;
}

Where did the business logic go? In this particular class, there is hardly need for business logic, as it reads values from an XML file. It might be better to separate the business logic in another (partial) class.
The servername (Name) is obligatory, so we set that when instantiating the DbServer object: in the constructor.

The constructor

To find the right SQL server I need to supply the servername. With that servername, we can query the XML file for the rest of the values of the properties.
So, when instantiating the DBserver object, we should provide the servername.
Therefore we need a constructor.

public DbServer(string name)
   {
        Name = name;
    }

Now we can instantiate a Dbserver instance with a name. Like this:

 DbServer server = new DbServer("SQLSERVER01");

Well.. these are the basics of OOP in C#. Now let's add a little bonus material. Here is how we actually read the values from the XML file:

Linq to XML

This is the XML file that contains all then servers:

To query this with C#, we need to add the following references:

using System.Xml;
using System.Xml.Linq;

Querying an XML document is as simple as this:

var result = from s in XDocument.Load("Servers.xml").Descendants("server")
                where s.Element("name").Value == "SQLSERVER01"
                select s).FirstOrDefault();

we would get the value of the username field like this:

result.Element("username").Value;

All the code

Finally, this is all the code from this article:

Hope this has helped you somehow!