Skip to content

February 15, 2007

Building a “Stupid Client” … Part 3

We now have an idea of what the front end is doing to build our dataset. So let’s look at what our Webservice and Business Layer will do to accomplish their work. First off let’s start by looking at the Webservice method:

/// <summary>
/// Write the truck to a file span> 
/// for now( database futuristically )
/// </summary>
/// <param name="truck">truck dataset.</param>
[WebMethod]
public void InsertTruck(DataSet truck)
{
    ObjectBuilder ob = new ObjectBuilder(truck);

    Truck tr = ob.Build<Truck>();

    //-- VALIDATE TRUCK --
    if (tr.ValidateTruck() == string.Empty)
        tr.InsertTruck();
}

 

The first thing we do here is declare a new instance of the OjbectBuilder class. We pass the DataSet  truck, into the constructor. We then ask the object builder to build our truck object by letting it know that it has to Build . This method takes in a generic type and returns that same specified type after it is hydrated. We will have a look at the build method in just a second.

So now that we have our object created and hydrated, we check its validity. This method will check datatypes, business rules and so on. If that check passes we invoke the InsertTruck() method, and “Insert” the truck. In a normal application this method would tap the database and insert our new Truck. In our case it just writes the info to a .dat file in C:\Temp.

With all that out of the way we can now check out the ObjectBuilder class. The code can be found by following the link below.

===============================================
CODE: ObjectBuilder.cs
===============================================

Not too complex. The class has a DataSet property, which is set when the constructor is called. This is the dataset that will be used to rebuild our object and then hydrate it. The Build() method is by far the most complex. However, if we examine this method, it too will be simple to understand, and then you can say you used reflection. Before we do all that lets give a shout out to the DNN project, codeproject.com, and adargel who wrote the article.

So let’s get to it and check out what the code does…. line by line.

    public T Build<T>()
    {
  

This line tells us that we will be using generics. The method will return a Generic type T, not yet known, and we will specify this generic type when we call the method.

Truck tr = ob.Build<Truck>();

This method call tells us that we want a Truck object built, hydrated and returned. So, with that out of the way let’s look at the first line that does some work.

    T entity = Activator.CreateInstance<T>();
   

This line creates a new instance called entity of generic type T. In our case that type will be Truck. The next half of this line asks for a new instance of this class. This will call the default constructor. So, we now have a new object of type Truck that is ready to be hydrated. The next line:

DataRow row = _dsObjectToBuild.Tables[0].Rows[0];

just grabs the first datarow out of the details table in our dataset.

So, onto the loop(s). The first loop will just itterate through all the properties in our new object. It does so by using reflection.

//-- ROLL THROUGH ALL THE PROPERTIES IN THE OBJECT --
foreach (PropertyInfo property in
                   entity.GetType().GetProperties())

We want to roll through all of the PropertyInfo ( properties ) objects that our new object has. You have to include System.Reflection for this to work. Moving on… the next line:

if(property.CanWrite && property.CanRead) 

We want to make sure that we can read and write from and to the property. Small step but a rather important one. At any rate, the next line puts us in another loop! Whats going on!?

foreach (object ca in property.GetCustomAttributes(false))

This line will itterate through all the custom attributes of the particular property. But what is a Custom Attribure? http://www.devx.com/dotnet/Article/11579 . All together now: “Thank you DevX.com!”

Think of custom attributes as properties( attributes ) that can be specified for methods, properties and so on. One common Custom Attribute that you may be familiar with is [Webmethod] . This declares a method in a webservice as one that needs to be exposed. In much the same way we can create our own attributes by inheriting from System.Attribute .

The custom attribute that we are insterested in for this simple example is DatabaseParameter. This will indicate that the current property is one that will ultimately get dumped to the DB. The following line performs that check:

if (ca is DatabaseParameter)

Some may not care that the properties passed from the client app are not columns in the table you will dump the data to. In that case you do not need to check whether or not the values coming back are DatabaseParameters, if that is the case you can exclude the inner for loop and the check. And now… last but not least the most important line:

property.SetValue(entity, row[property.Name], null);

This line actually sets the value of the property based on the value of the particular column in the DataRow ( ie: row[property.Name] ).

So once this is all done executing we have a nice hydrated object ready to return. Once that happens control is sent back to the Webservice and the InsertTruck() method is called. Which in turn drops the object to a text file. Again, in a real world application that data would be dumped to a database. The code for the Webservice and Business Layer can be found below.

================================================
CODE DOWNLOAD: WS_BUILDER.zip
================================================

So, where do we go from here? For anyone following along I would recommend giving the code a shot, so you can see it working for yourself. I plan on posting 2 followups one on CustomAttributes and an explanation of how this particular endeavour is leveraging them, and the second will be on a different setup for you folks that do not like Reflection. I won’t reveal too much but will say this, we will use interfaces and a custom business hydrator for each class.

At any rate that is all for now. Feel free to comment with any questions, or let me know if I missed anything.

Read more from Random Rants

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments