Tuesday, December 8, 2009

Filtering LinqDataSource

Codes can be downloaded here

The RAD nature of ASP.NET Webforms makes it the sound choice for creating tools and utilities. I’m talking about small applications which aid development and are not intended for production. Among these features, the one that probably saves the greatest amount of time is data binding. I’ve tried all the data sources and with LINQ elegant syntax involving extension methods and lambda’s, I expected that with LinqDataSource, I can apply these new language features during filtering. I’m very disappointed to find out I have to deal instead with something I hated most – string literals!

image

The page I created is a log viewer which is nothing but a grid and a bunch of controls for the filter values. The illustration here is simplistic but the technique is not compromised in any way. The data is stored in a table with columns for the date the log was made, the level or severity of the message and of course the message. A grid will display this using LinqDataSource.

Config LinqDataSource 3 

Because it’s an ad hoc filter, I decided not to use the configurable WHERE parameters of the LinqDataSource. I thought I could add parameters as needed at run time. It is indeed possible and after some rummaging, I found out that the best place to do this is in the  LinqDataSource.Selecting event. In this event, the sender is a LinqDataSourceView which exposes a Where string property. This accepts the body of the lambda expression that one usually put in the Where extension method. The only catch: it’s string. Beautiful! The tough part is when dealing with dates because you have to use DateTime utility methods and all this without the benefit of Intellisense. Shown below are the pertinent codes for the sample app you can download for this post.

image

Tuesday, November 17, 2009

Temporal Data: Considerations, Conventions and Cheats

I’m not an expert of temporal database, its concepts and principles. The techniques I discuss here are the ones I employed to an application during my early days of programming. For exhaustive information on this subject, you may consult the works of Richard T. Snodgrass or C.J. Date. It’s so easy, just Google them. ;)
Temporal Granularity
The first thing to establish in a temporal database is the shortest length of time by which a change in the data is considered significant. This is commonly referred to as the "temporal granularity”.  In my application, I assumed it to be by “day” but SQL Server didn’t have any DATE-only data type until version 10 so this limitation was taken into consideration during the development. A function was created to remove the time portion of a DATETIME.
image
Figure 1 – A function to remove the time portion of a DATETIME
Index
If you isolate the columns to be tracked in another table, the new table should have a unique clustered index on the combination of the foreign key and the start date time. An example of this is the operation history table which tracks changes of the rate of an operation. In that table, the foreign key and start date combination is part of a unique clustered index to ensure that there is always one valid rate per given date. It also wouldn’t hurt if a check is employed to make sure that the end date is always after the start date.
image
Figure 2 – Table containing temporal data should have unique clustered index on the FK and start date/time
Querying Strategy
Querying a version of data in a temporal table always involves a date parameter indicating the version to retrieve. This date should fall between the start and end dates of at most one row for every id. The id here refers to the foreign key pointing to the non-temporal parent table. To make this clear, consider the following transactions:
  1. Operation “Button Attachment” with rate of 0.35 is inserted on 10/28/2009
  2. Rate for operation “Button Attachment” is changed to 0.37 on 11/01/2009
These insert 3 rows: 1 for the operation table and 2 to the operation history. The former is not pertinent to the discussion because it does not contain temporal data. In the latter, the rows inserted are highlighted below:
image
Figure 3 – Sample rows showing the current and previous version of a temporal data
If the user asks for the rate on 10/30/2009, obviously she would retrieve 0.35. The query is straightforward as long as the date fall between the transaction dates. What would she get then if she asks for the rate on 11/01/2009? Again, this is where business should come to the rescue. The business should establish the convention employed during the closing and opening of two contiguous periods, which happens when the data is updated. The convention can be determined by simply asking two questions:
Given an update on date n
  • What should be the end date of the previous period?
  • What should be the start date of the current period?
The answers determine the insert and update strategy to employ. If for the first question, Business says n-1, then it also implies that the answer for the second question is n. It can also be an n for the first and n+1 for the second. Important thing is that they should not overlap. After the convention is established, the BETWEEN operator can be safely used in the query as shown here:

SELECT o.name_vc, h.labor_sm FROM t_operation o
JOIN t_ophist h ON o.operation_id = h.operation_id
WHERE o.operation_id = @operation_id
AND (@versionDate BETWEEN h.start_dt AND h.end_dt)
Figure 4 – The most correct way of querying temporal data
In Figure 3 however, one can see that in my application, the end of the previous and the start of the current periods are the same. This is because back the, I didn’t know about BETWEEN operator. To achieve the same effect, I had to use inequalities operator and lines like these were all over the place:

start_dt <= @versionDate AND @versionDate < end_dt
Figure 5 – A condition used in the application in lieu of BETWEEN

Thru that filter statement, I effectively established the convention of n on end of current and n+1 on the start of the new version
Data Modification Logic
One interesting aspect of temporal data is that it changes the conventional semantics of data modification.  Update can be any of these 3 cases: update plus insert, update only, delete and update. A delete in the other hand is merely an update on one column. Finally, an insert may only occur in the temporal table and not in the parent (non-temporal) table. Now it should be clear why dealing with temporal data is definitely not a walk in the park.

When a temporal data in my application is updated, the start date of the current version is compared to the date of the transaction. The first case in update happens if the transaction date is not the same as the start date of the current version. The current version is closed or invalidated and a new version is inserted. Invalidating a version is just providing a valid value to the end date depending on the convention used. The “Button Attachment” transactions is an example of this case. The update is later than the start date of the current version therefore a new record is inserted and the current version is invalidated with the date of the transaction.

The second case happens when the transaction occurs on the same day as the start date of the current version. A delete and insert in this case is an overwork because all that is needed is an update on the rate (labor_sm). If we use the “Button Attachment” as an example, this is the case when the rate is raised again to 0.38 on 11/1/2009.

The third case is a special case of the second. This happens when the new value is the same as the value of the previous version. The previous version is the one preceding the current. In the “Button Attachment” example, this happens when the rate is changed back to 0.35 on 11/01/2009. This is like not updating the 10/28/2009-11/01/2009 version at all. So the course of action is to delete the current and open the 10/28/2009-11/01/2009 version.

image
Figure 6 – An stored procedure illustrating the different cases involved in updating a temporal data
As mentioned before, there is no actual delete in a temporal database. Delete is achieved by simply closing the current version on the temporal table. In the example, if “Button Attachment” is deleted on 11/01/2009, the only action taken is closing the current version. The record “Button Attachment” in the operation table is left intact. This means that during insert, it’s possible that the data is already in the operation table. In such a case, an insert to the operation history for the new valid version of the said data does the job.
Cheats
Later during the development of the application, it became clear that most of the queries in the frontend involved only the current data. I was fully aware of the performance implication innate to temporal queries like that in Figure 4 so I decided to employ a cheat. Instead of BETWEEN, I used = operator to get the current version since a convention is already established that end date for current should always be 12/30/5000. This also means that end date was no longer null-able and was included in the unique clustered index together with the FK and start date.

Another cheat that I employed later in my other projects is what I call the “reverse relationship”. It still uses = but instead of end date, the parent table contains a foreign key of the temporal child table. This also necessitates having a surrogate primary key in the temporal table. Usually, like in Figure 2, the temporal table can use the combination of the FK and the start date as a composite PK but in the case of reverse relationship, this composite key becomes a bulky FK in the parent table. A lean and faster approach is to have a surrogate key as FK like the one illustrated in Figure 7. Of course, it doesn’t have to be a constraint; a column pointer would suffice but careful check should be done to avoid pointing to a non-existent temporal data. The “fast” factor comes into play in there is a very high volume of data in the temporal table. A slight performance benefit can be squeezed out from querying integer instead of a date.
Reverse relationship
Figure 7 – A sample parent-temporal child table with “reverse relationship” to speed up temporal query
I’ve also seen temporal table that has flag column to indicate if the row is current. Like the reverse relationship, any technique that involves additional column to convey a semantics also open the database to potential synchronization problems. For example, it’s possible that a flaw in the update logic might insert the wrong FK in the parent table or flag the wrong row as current.

I’m sure there are still more “cheats” or techniques out there. A modeler can employ even the most unconventional but it shouldn’t matter as long it’s justified. These kind of practices deviates from the standard so proper documentation of these “deviation” is also a must.

What’s Next

Next post will be about the preliminary efforts I had when translating the VB6 version of the application to .NET version. I’ll discuss the overall architecture and motivation of the approach I chose.

Sunday, November 1, 2009

Temporal Data

In the first installment of this series, I mentioned that I unnecessarily complicated the ApparelFactory app by introducing temporal data, thus delving myself into the world of temporal database. A temporal database differs from an ordinary database in that it stores different version of data based on their validity throughout time. Other people simply refers to these versions as “history” of the information. A piece of data is said to be “valid” on a certain time if it is consider to be true at that time.  
“Querying a particular version of a temporal data is not straightforward because you need to consider the time component.”
It’s easy to spot a database which contains temporal data. You usually see two time columns in a table indicating the start and the end during which the data is considered valid. The granularity dictates the data type used. For example, if you don’t consider changes within a day to be relevant, then you can use DATETIME ignoring the time portion. SQL Server 2008 has a DATE data type well-suited for this need. If changes within the year is not relevant, you can use INT for both the start and end years. The granularity is usually dictated by the business but in the case of the ApparelFactory, I simply assumed that changes within the day is not relevant, thus I have a tables like the one below where start_dt and end_dt are the start date and end date respectively.
image
Figure 1 – A table for storing temporal data
Most of the time, users are only concerned with the current valid version of the data. Past versions are of interest only for analysis and evaluation of trends, say the price fluctuation of certain commodity. They may be viewed only through reports and some other data warehousing tools. Querying a particular version of a temporal data is not straightforward because you need to consider the time component. For example, in the t_allowance table, if I were to write a flexible query to retrieve any version an employee’s allowance by date, the WHERE statement would have looked like this
WHERE employee_id = @employee_id AND (@referenceDate BETWEEN start_dt AND end_dt)
Figure 2 – Flexible WHERE statement for a temporal data
A query involving BETWEEN operator is not the most efficient so coders usually cheat when writing one for retrieving the current version. They use = instead, but this presupposes that there is already an established convention in determining the current version. The most common is to make the end date nullable and any row with a null value is considered current. In the application, I used the another variation which sets the end date to a very unrealistically high value. This has the advantage of not requiring you to convert the null end date to a real value when using BETWEEN. This is because using BETWEEN on a null date always evaluates to false.

image
Figure 3 – Sample query utilizing equality operator instead of BETWEEN for temporal data
In a true temporal database, every change in the data is recorded. This is not practical since most of the time, only a subset of the columns are worth tracking. Only the columns  which trends are worth analyzing are tracked. These are then separated in a table together with  the start and end time columns. In the apparel app, I made sure that user can always see the history of the rates of every operation as well as their usage in a style (what operation is involved in a style at a certain point). The queries would have been complicated had I not employed some “acceptable cheats” in my table design. I’ll discuss more about these so-called cheats in the future installment of the series.

image
Figure 4 – Column which need to be tracked are usually taken out and made into a separate table
Temporal data are useless if the coder doesn’t employ an intuitive way of presenting them to the user. All these data should be available to reports of course, but users also appreciate it if they could see them instantly without resorting to reports. This way, they don’t have to be inundated with so many information when all they want is, let’s say the rate history for an operation which rate the company has just decided to change. In this connection, the ability for a user to select a date as a parameter during viewing of the data is very integral when designing the UI. A coder can simply throw in a DateTimePicker or Calendar web control. If the user prefers the actual change dates, then a list is a good choice. This approach involves another query but it always ensures new results during every query. It also presents the user with the exact number of changes; something not available with the date time picker / calendar approach.

In the application, the list approach is used as seen in Figure 5. The number of current operation for the style is 3, one is added sometime on 11/01/2009. The rate of one operation also changed on the same date, thus changing the current rate of the style.

Style history 1
Figure 5 – A UI displaying historical changes on data membership

The addition of another operation and the change in rate of another one can be seen in Figure 6. Since only the rate is tracked for the operation, it makes much more sense to simply display the history right away.

Operation view
igure 6 – A UI displaying historical changes of a single column
Being able to work on temporal database is really a fulfilling experience for a coder, let alone for a novice. A coder feels that his application adds more value to the business because it ensures all the data are there and easy for the viewing. The flipside is, it might not be needed at all and it’s just another unnecessary complexity to an already delayed project. It wouldn’t hurt if the client is asked first because the last thing a coder needs is a flawless feature that no one even dares to use.

Next, I’ll discuss the adjustments, conventions and the cheats I employed.

Friday, October 16, 2009

Logging the Stack Trace

Codes can be downloaded here

Stack trace is very important in locating exceptions because unlike the Message property, it can pinpoint the exact location of the line that throws the exception. Unfortunately, developers seldom log the stack trace for 2 reasons:

  1. They can be very long which in turn requires a large storage capacity
  2. The information don’t help that much because the methods are listed in reverse order.

The size of the stack trace depends on where the method that throws the exception is located in the call stack. Take for example adding of record functionality in this application:

image

The function has a very shallow stack which is initiated by a button click and terminates in the database. This is illustrated by the call stack diagram below:

Button click in Default.aspx  -----calls----> Entity Framework Model -----calls------> Database

If a line in the “button click” method causes an exception, say a database integrity violation,  the first method in the stack trace is not not the “button click” but the one that detects the violation which is shown here:

at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(Boolean acceptChangesDuringSave) at System.Data.Objects.ObjectContext.SaveChanges() at WebApp._Default.btnException_OnClick(Object sender, EventArgs e) in C:\Users\Vanni\Documents\Visual Studio 2008\Projects\StackTraceSplit\WebApp\WebApp\Default.aspx.cs:line 28

For the developer searching for the bug in a production environment, the last method in the trace is the most important because that is where he’s going to start the search. To make his life easy, one can write a extension methods for System.Exception that can reverse the order of the stack trace and retrieve only a portion of it, usually the ones which the developer has access to. Extension methods are user-defined methods that can attached to an object which implementation is off-limit to developers. The method should adhere to the following guidelines in order for it to qualify as an extension method

  1. It has to be static
  2. It has to have a return value
  3. The first parameter should be in the form “this <object to extend> parameter value”

The extension methods for the predicament discussed may look like the ones below. Note that it’s a good practice to specify the class as static because this ensures that all methods should be static too.

 image

The first method splits the entire stack trace into arrays by using the characters “ at “ as the separator and reverses the order. The second is an overload which accepts a number of stack to return, starting from the top. The third method returns only one big chunk of the stack trace and is intended for logging.

When running the following codes,

image

a portion of the result would look like this:

image

Now that will definitely make a debugger’s life easy!

Sunday, October 11, 2009

Aliasing a class? Whoa!

I accidentally discovered a feature in C# that I thought only possible with C/C++ – aliasing a class. I’ve been coding .NET for years but never have I encountered examples or extensive discussion on this. I will not be a fan of this because I’m sure this also have the same problems inherent to the C/C++ equivalent. One justification for using this may be for shortening of a class name, but again we don’t have to type who needs to type the entire class name? Don't we have Intellisense to help us with that. Besides, if class has very unwieldy long name, it wouldn’t hurt to contract some words or better, redesign it because it may not be cohesive all along.
image

Wednesday, October 7, 2009

“Nullable object must have a value.” – could be a sign of something serious

At first glance, the InvalidOperationException with the message “Nullable object must have a value.” is probably the most senseless of all .NET exceptions. This is because the message is very misleading when one takes it by its face value. The most logical conclusion a reader can derive is that it’s something about failing to assign a non-null value to a Nullable<T> object. Microsoft could have used a much better verbiage because what’s actually triggering the exception is an attempt to perform an action to the Nullable<T> object which value happens to be null. In other words, it’s about an invalid action, not value.
image
Figure 1 – A message that can leave you dumbfounded
Unfortunately, the capability of Visual Studio in detecting null nullable is limited only to uninitialized fields. If the nullable object is a property, then all you can do is sit and wait for the bomb to go off. In Figure 2, the properties SampleClass.NullableBool and Program.NullableBool are never checked by Visual Studio whereas _nullableBool cannot escape the scrutiny.
image
Figure 2 – Visual Studio can help detect only uninitialized nullable fields
Figure 3 shows the most common mistakes that trigger the exception. The first case is when the Value property is called to extract the encapsulated native type. The second case is quite common among new programmers where instead of calling Value, a cast is performed on the nullable object.
image
Figure 3 – Be on the lookout for lines similar to these
Bear in mind though that calling ToString() on a null nullable is perfectly legal as long as it’s initialized. It simply yields a blank which is what exactly we want in the UI.
image
Figure 4 – It’s safe to call ToString as long as the nullable is initialized

There Could Me Something More

When you’re done cursing Microsoft, do yourself a favor and go back to your codes. The message could be a sign of a more serious type of bug lurking somewhere. This is because it’s possible that nullables are used in boolean conditions without the benefit of a prior nullability check. If this is the case and the coder does not call the Value property, the compiler does not complain at all. It simply evaluates the condition as false!
image
Figure 5 – A null nullable is always evaluated as false
In the business rules of your application, it might be that a null is equivalent to a false and in this case, you could care less about codes similar to Figure 5. However, the fact that 3-value logic is already allowed to permeate in the application also means that null deserves a separate treatment altogether. A null could mean “I don’t know”, “not yet”, or “maybe”.
image
Figure 6 – This block can wreak havoc in your application.

Defensive Coding

Nullable<T>.HasValue can be used to check if the value is null. You usually use this whenever a null value is treated differently as illustrated in the snippet below:
image
Figure 7 – Using HasValue prevents exception and aids in the 3-value logic evaluation
In the rare cases where a null means false or any valid value of a type, one can use the coalesce C# operator ?? as shown here:
image
Figure 8 – The coalesced operator is handy when null value can be interpreted in some other way
In the next release of .NET, I hope we could get a much more meaningful message, something like “Attempting to perform action to a Nullable<T> is not allowed when its value is null.” Whatcha think?

Sunday, September 27, 2009

Linked Server and Synonym

Last Friday, I needed to compare the content of both the DEV and QA databases as a preparation for a QA deployment. My machine just got a fresh image so I didn’t have the database tools that could have made the task a breeze. I had to finish ahead of the deployment so instead of rummaging for the installer of the tools, I decided to improvise. Good thing, they were just few reference tables which usually have few columns.

image

In order to accomplish my task, I should be able to connect to the QA database in a remote machine and query the equivalent tables together local ones in a single query. But SQL Server has no innate ability to query database from other machine. You connect to that machine using the feature called Linked Server. It’s not going to be a smooth procedure though per my experience but the solution is not too complex to stymie anyone. Once connected, you can query the pertinent tables and here, another feature called Synonym, first introduced in SQL Server 2005, can offer a little convenience.

So the first step is to create a linked server. One way to accomplish this is by right clicking the Linked Servers under the Server Objects node and selecting “Add New Linked Server…”. In my case, I was connecting only to a SQL Server instance so in the General Page all I needed to specify was the name of the instance. Be aware that this is not an arbitrary value when connecting to a SQL Server instance. It has to be the name of the instance.

image

Next is to configure the security aspect. The objective here is to specify a local login which will be mapped to another login in the remote server so that whenever you use the linked server, you actually use a proxy login in the remote server with the correct privileges. If both servers are located in the same machine, you can simply add any login with correct privileges and check “Impersonate” as shown below. This is a good practice since you’re controlling who gets access to the remote server.

image

Applying the setting above in a remote server in an Active Directory however, produces this vague error message:

image

I have no idea where the heck this “NT AUTHORITY\ANONYMOUS” account comes from so I googled the last sentence which, as you can see, is pretty much generic. Not surprisingly, the result was a myriad of situations on almost anything that involves NT authentication. Among them, this one, in my opinion gives the closest semblance to my predicament. Although the KB is applicable only to SQL Server 7.0, I still tried the solution. Mapping the local login didn’t work either so I ultimately settled for SQL Server-authenticated account to establish the security context. I skip the mapping list altogether so the configuration dialog should then contain only values similar to the ones below:

image

After establishing the linked server, one can proceed to cross database query like this:

image

If you perform considerable number of queries on the remote server, you can leverage on Synonym which can spare you some keystrokes and make the queries a tad shorter. This is because with Synonym, you can create alias on certain objects of the remote database. You create a synonym in the “Synonym” node of your database. With my linked server, a synonym configuration would look like this:

image

The only arbitrary field is the name. Everything depends on the properties of the local and remote database. You can also create synonyms for other objects like function, stored procedures and view. Note that the account used by the linked server should have the needed privileges to the concerned object in order to succeed with the creation. With that taken cared of, the previous query then becomes:

image

Like any other database objects, Synonym is “securable” meaning you can control who gets to do what on it. This can be done in the Permission page of the Create Synonym dialog as shown below. First I thought this can be used to grant access for logins other than the one used in the linked server but based on my investigation, it looks like it’s dependent on the linked server logins. This means you cannot grant access on a synonym to a login unless it is also capable of connecting to the linked server. For safety reasons, I would have loved it if I could let a developer access a synonym but not the linked server.

image

Obviously this not the most efficient way of comparing data between two identical databases but sometimes when you do things manually, you would be compelled to explore some hidden features in a technology. Who knows, those features might come handy for tasks where tools for achieving them are not there yet.

Sunday, September 20, 2009

My First Battle

A few months back, I got a notice from Yahoo! that it’s was about to pull the plug on Briefcase, its free online storage service and that I needed to transfer all the files. There, I found a zip file of the very first industrial-strength project I developed almost 9 years ago together with some friends. When I got a copy of Visual Studio 6 from a friend, I decided to look into the codes again and what I discovered are traces of struggle, perseverance, and naiveness that shaped the coder that I am today. Every project is a battle. This is the first one and I had only the slightest idea of what I got myself into.

The project is a VB6 client-server application for an apparel company. It was used to compute wage for factory workers based on the work items (known as job) they’ve done for the week. It was originally a college project but the primary stakeholders, realizing the huge return of investment from automated process, tasked them to continue working on it for a price. Well, we didn’t really know the price at that point but the idea of making money out of the craft you’re trying to learn from school was just too enticing. I joined the team when it was realized that MS Access was no longer up to the job. In my case, my enthusiasm was further bolstered by the fact that I was still beginning to learn SQL Server.

The project became an eye-opener to the real nature of the craft I chose. I didn’t graduate with a computer degree but I decided to pursue programming thru self-thought because it’s the only way I can satisfy the “control freak” in me. I thought it would be fun, after all it’s about doing what you really love, right? Well, nothing could be further from the truth. It turned out to be a nightmare; capable of turning anyone into a zombie due to several sleepless nights and skipped meals. The same is the nature of software development as I experience nowadays but the big differences is that we were still naive then. We lacked the experience and knowledge about good software development practices. Exacerbating the situation were the comparatively primitive technologies we’re using which always compelled us to make compromises in order to achieve the best solutions. This post, and the ones hereafter, will explore the mistakes I made and how they influenced the subsequent projects I had. I will also discuss the by which they should be implemented using the most current technologies.

The Model and the Names

Virtually every business application deals with data so it just makes perfect sense if I start with the data model. I can say that I designed about 90% of the data model. Another member took care of the remaining 10% for an auxiliary applications which he solely developed. The first thing you would probably notice is the application of Hungarian Notation and underscores. I learned this style and the naming convention, which you will see momentarily, from the book I was reading at that time. As a beginner, you tend to be dogmatic and don’t even dare to ponder if what you’re imitating is actually right. I later found out that this style is not just hard to read but totally unnecessary.

There were more tables than what were actually needed. This is because I maintained history on some data which I thought would be valuable for auditing and report generation. This is actually a big mistake. Queries involving temporal data are not straightforward because you’re always dealing with composite unique keys involving dates. Besides, the stakeholder did not ask for it - I just assumed it. The adjustments we made just to cater for temporal data, significantly delayed the delivery of the project. I was guilty of that.

“As a beginner, you tend to be dogmatic and don’t even dare to ponder if what you’re imitating is actually right.”

image

The model included extraneous tables.

I did not use the IDE to create my database objects. Instead, I painstakingly wrote the script for the entire database! For a beginner, it’s a great way to learning SQL but it’s a bad practice simply because it takes so much time. Companies don’t hire you because you can write an entire script of a database. They hire those who can achieve things within the shortest period of time so that means being adept with tools.

image

Sample script for a table, complete with constraints.

“The adjustments we made just to cater for temporal data, significantly delayed the delivery of the project. I was guilty of that.”

Later in the development, I’ve had enough of Hungarian Notation and this couldn’t be more evident than the contact number column. From a book I referenced, contact numbers were stored as integer and I just blindly followed that. But having it so requires parsing and formatting in the UI. Worse, changing its data type also means making sure the procedure or views that used it were modified because the column name has changed. Coupling is the biggest headache from Hungarian Notation especially that time when there was still no refactoring tools. Another lesson I learned from this is that a column, even though they can be stored as numbers, should never be numeric unless it's being used in some kind of computation.

image 

Some columns did not use Hungarian Notation anymore

What’s next

this point, it’s should be clear that I just scratched the surface of one laborious undertaking. In the next installment of this series, I’ll discuss the complexities involved in dealing with time-aware data.

Saturday, September 12, 2009

Spring Season

Codes can be downloaded here

Yesterday, I got the chance to tinker with another wiring framework, the grand daddy of them all – Spring.NET - which is actually the first wiring framework I came to know about. This is already my third post with regard to wiring framework so you can expect some references to the castle and unity posts along the way. Like the last two, I’d like to share the opinions from the point of view of someone who just wants a quick wiring solution.

First, you need to download the framework here. Spring is an application framework encompassing other concerns which include but not limited to data access, logging, and testing. The documentation is pretty impressive, complete with samples. It even explains the concepts that drives the creation of framework. Best of all, it has a PDF format which I prefer because of the bookmark feature.

Since we only want wiring framework, the Spring.Core dll would suffice. This is located in the <spring framework installation folder>\bin\net\2.0\release. Make a reference to it together with the abstraction and the concrete assemblies.

image

Like any other frameworks that utilize the .NET configuration feature, Spring requires configuration entries. This part is well documented so nube shouldn’t have any problem. As you can see in the illustration below, Spring uses the term “context” for what we usually refer as “container” This may be because the context object has more functions other than resolving objects but I haven’t explored this yet. Among the 3, I find Spring entries to be the most verbose. First, you need a separate handler for the object (type in Unity, component in Castle). Then, the context should have a reference to the section which contains the objects it can resolve. In Unity, the objects are simply nested within the container and Castle is similar but doesn’t give you the option to specify which container the objects belong. One thing I like though is the absence of the interface declaration in the objects. In the declaration for the object “searcher” we don’t have to specify ISearcher.  Doing so would have been redundant since you will specify it in the codes anywise.

image

Nothing new with the code part. You instantiate the context, which in our case is the default. The resolution however, could have benefitted from generics. Among the 3 framework, this is the only one that uses casting.

image

Voila!

image

I’m sure there are still so many features in Spring that need to be explored. One feature which piques my curiosity is its tight integration with NHibernate. For the time being, I think I should be good with Castle.

Sunday, August 23, 2009

A Roadblock to Unity

Codes can be downloaded here

In my last post, I showed a simple dependency injection using Castle Windsor. This time, I tinkered Microsoft Unity Framework and tried to find out how it faired against the former. There are nomenclature differences but the structure and code are fairly similar. It wasn’t a smooth coding though for I encountered a roadblock. The problem is on retrieving of the configuration section for Unity:

image

The message is misleading because the files have always been there and the solution is actually to install the assembly Microsoft.Practices.Unity.Configuration in the GAC. There is a discussion about this problem here. Unfortunately, I wasn’t able to make the other suggested solutions work. After the GAC install, the app configuration became

image

Take note that I needed to embed the version and the public key token which can be found when browsing the C:\Windows\Assembly folder

image

I don’t like these because I’m not sure if these values are portable. These just add headaches during deployment.

As I mentioned earlier, the difference are mostly confined to nomenclature. One thing to take note though is the attribute “type” in the node “type” which equivalent in Windsor is “mapTo”, not “type”.

Being a MS implementation, it’s no surprise that Unity uses BCL classes to do its chores. For example, in the initialization of the container, you use the System.Configuration.ConfigurationManager instead of some customized XML interpreter. This is a great welcome to programmers because it significantly lower the learning curve.

image

At this point, I still prefer Windsor over Unity. I’ve perused the documentation and found Unity to be a little verbose. I might be wrong on that but the roadblock I just experienced would probably justify my stand.

Friday, July 10, 2009

Welcome to the Castle

Codes can be downloaded here.

The proven viability of Aspect Oriented Programming (AOP) as a programming paradigm has led to the porting of popular Inversion of Control frameworks to multiple platforms. One of these frameworks is the Castle Windsor which has its roots in open source and Java communities. One of the tenets of AOP is to promote loose coupling among the different components of your application so that anytime during application’s lifetime, the implementations of the functionalities can be changed without affecting the codes. Changes would involve only adding of entries in a configuration file. In this entry, I will show the most common and the fastest way of initializing Castle Windsor. Figure 1 illustrates the different components of a typical application adhering to AOP. The context, which is the final application, uses only abstraction objects in the form of interface. The implementations of the abstraction, known as concretes, are in separate components and are developed independently. The role of Castle Windsor is to “inject” the desired concrete during runtime. In so doing, the context will also create an association to the concrete but since this activity is dynamic, the diagram does not show it. Which concrete to inject is determined from an entry in the configuration file.

image

Fig. 1 - Component diagram of the sample solution

The code below shows a very simplistic interface which will be abstracting the application from the concrete implementations.

image

Fig. 2 - The abstraction interface

The implementation is likewise simplistic. All we need is an indication of what assembly is being injected.

image

Fig. 3 - Sample implementation of the abstraction

In order for Castle Windsor to inject a particular concrete assembly, that assembly has to be referenced by the application together with its dependency stack. Figure 4 shows all the concretes being referenced but this is not always the case. You just need to reference what you intend to inject.

image

Fig. 4 - Required assemblies in the final application

Castle Windsor needs a customized section in the configuration file and the list of concretes you want to inject, each identified by a string ID. Each item in the list is defined by the <component> node. Besides the ID, the node also specifies the full type name and the assembly of the abstraction and the concrete. The code will retrieve these data during runtime using the ID as you’ll see in the next section.

image 

Fig. 5 - Configuration entries for Castle Windsor

The first thing to do in the application codes is to initialize the IoC container. Figure 6 shows instantiation of the container using an overload that reads the “castle” section in the configuration file. The container is responsible for resolving the correct type based on the entry in the configuration which is illustrated in the next line.

image

Fig. 6 – Code usage

Since we’re specifying ExtensiveSearcher as our searcher, we get the result in Figure 6. Swapping the entries would affect the display accordingly.

image

Fig. 7 – Output after injecting ExtensiveSearcher assembly