May 2008 - Posts

Whenever it comes to determining whether a business object meets a certain state, I like to do create a property or method for this.  For instance, evaluate the property below:

public bool IsCompleted
{
    get { return this.CompletedDate != null; }
}

The IsCompleted property checks to see if a completed date, which is a nullable type, has a value specified to it.  If it does, then it's completed in the system.  This may seem like a simple thing, and not necessary.  Additionally, from an agile perspective, it may be viewed that I'm coding for a situation in the future that may or may not happen.

Though those are all valid points, I disagree.  I think this is the perfect way to encapsulate certain behavior and make object states easier to read (is it completed or not, vs. is the completed date null or not null).  Plus, it's very little code, and prevents more involved code changes by putting completion checking logic in one place.

For instance, what happens if the status of the object can be closed, and this is now considered a completed item?  Furthermore, closing an item does not mark it completed, because a closed item is not technically completed, yet it no longer needs to be visible in the system.  Imagine the following:

public bool IsCompleted
{
    get { return (this.CompletedDate != null) && (this.Status == "Completed" || this.Status == "Closed"); }
}

This change is easily encapsulated into one property.  If this logic is used 100 times in the system, my approach only requires one change, whereas if I didn't use this approach, 100 lines of code need to change.

Posted by bmains | with no comments

One issue often overlooked is concurrency issues.  I know in my development, I sometimes overlook this task.  But concurrency issues are important, especially with some data access layers like LINQ-to-SQL.  So how can this be prevented?  You can use an approach like the following:

public static class MyClass
{
   private static DataSet _data = null;
   private static object _lock = new object();

   public static DataSet GetData()
   {
      if (_data != null)
        return _data;

      lock(_lock)
      {
        //important to check twice; when the first lock is released, _data could be populated for subsequent locks
        if (_data != null)
          return _data;

         //Load the data from the data access layer
      }
   }
}

In this example, I used a static class, but this could be done in instance classes as well.  To lock the resource down, simply provide it an object; in books I've read, the approach above was used, but I've also seen an approach where someone uses a class type.  For more information about locking processes, see this:  http://msdn.microsoft.com/en-us/library/ms173179.aspx

It's important to check for the existence of the data twice; if two classes access this shared resource, the first process locks the resource, and populates the _data variable.  The second resource passed the first not null check, and is currently at the lock.  Without the second check after the lock, it would populate the _data variable again.  Rather, in this scenario, the second check finds that _data has been populated, and returns it.

Posted by bmains | with no comments
Filed under:

 The DataTable object has a nice feature when it comes to error handling.  It has a HasErrors property that determines whether any errors exist in the table object.  Using this, it's possible to loop through all the rows, then check the GetColumnsInError method to collect error information with the GetColumnError method, as illustrated below:

 

 

 

 

 

 

 

public 

static string[] GetRowErrorInformation(DataTable table) {
if (!table.HasErrors)
   
return new string[] { };

 

 

List<string> errors = new List<string>();

 

 

foreach (DataRow row in  table.GetErrors()) {
 
DataColumn[] columns = row.GetColumnsInError();
 
foreach (DataColumn column in columns)
    errors.Add(row.GetColumnError(column));
}

 

 

return errors.ToArray();
}

In this example, the errors are returned as a string array.  If you need a single string, you can simply use string.Concat() to concatenate the values.

Posted by bmains | with no comments
Filed under:

If you haven't heard about the series I'm doing, the Calendar Day View project is one that I'm trying to use TDD practices to show the process creating a custom control.  However, there are times when TDD breaks down, not because TDD fails, but because I failed to implement TDD.  Now, that's OK; really, the universe isn't going to come crashing down because I didn't create unit tests ahead of time, or jumped ahead into the code.

Case in point: I started to create new classes and a new approach for rendering items and calendar items.  I also used CodeSmith Studio to generate an AJAX component for me; CodeSmith Studio is awesome for generating a lot of code rather quickly; I just had to invest a moderate portion of time to get the script right, and the dividends pay off in the long run.  Thanks CodeSmith!

Anyway, I've started to create all these assets without creating tests or thinking about how the tests will come into play in the AJAX scenario.  That's not necessarily bad (unless you are a hard core TDD person).  However, the question is what I've developed is correct or not, which unit tests would have helped flesh out.  That's really what the biggest question around TDD is; does it really help you write better code, and does the extra hours put in to writing tests really mean less hours testing and maintaining later?

So I think I'll take a break, and revisit it another day when I'm more focused on TDD.  If you too wonder if unit testing is important, I came across this which might help explain it some:  http://weblogs.asp.net/adilakhter/archive/2008/04/18/why-unit-testing-is-so-important.aspx

Posted by bmains | with no comments
Filed under:

 I had some trouble validating date input using VAB and the PropertyProxyValidator.  As I would think would be the norm, for a date that I have specific requirements on, I'll setup a NotNullValidator, along with a DateRangeValidator to make sure the date fits within a certain range.  But I was getting errors because the PropertyProxyValidator was tied to a TextBox control, which means that the underlying value is a string.  Because it's a string, it couldn't be validated against.

The ValueConvert event fires whenever a server-side validation occurs (which is the mode that it works in), allowing you to convert the value to an alternative format.  This allowed me to convert the date from a string to a DateTime reference, and this solved the problem.

Posted by bmains | with no comments
Filed under:

There are many resources out there on the web that illustrate exporting data to excel from an ASP.NET page, using the gridview control.  This is the most common approach, though the Excel approach is not limited to a GridView control (I got it to work with a ListView that rendered a complex table structure).  I found this (http://aspalliance.com/771) as one of them, but it includes an extra tidbit I was having problems with.

For some reason, my default setup had the exception "GridView does not exist in a form that defines runat="server", or something like that.  By overriding the Page's method VerifyRenderingInServerForm, this alleviates the problem.  Don't know why; this method is meant to check whether the a control exists in a form, but I don't know why a control rendered via Excel has that very problem, being the control was within a server form.  Anyway, this caused it to work.

Posted by bmains | with no comments
Filed under:

LINQ to SQL is an intricate, yet "sensitive" tool into how it works.  A LINQ to SQL query is translated into a SQL query that is performed against the database.  This process occurs through a series of components that break the expression down into its simplest parts, so that it can take this query and build up a SQL implementation.

However, what this means is that you cannot do certain things with LINQ to SQL if that query touches the DataContext; the reason is queries against the DataContext are translated through LINQ to SQL; but objects queried not using the DataContext are in the category of LINQ to Objects, so these queries are not translated into SQL (because they don't go against the database).

In my latest findings, I tried to do something like this:

var results = from c in this.Context.Customers
                    where (from p in currentConfiguration.Preferences
                                where p.CustomerKey == c.CustomerKey
                                select p.Customer).Contains(c)
                    select c;

When I did this, I got the following exception: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.  The reason was that currentConfiguration is a variable passed into a method.  It should have been loaded with the same context object reference, so that shouldn't have been the issue.  As soon as I rewrote it like this:

var results = from c in this.Context.Customers
                    where (from p in this.Context.Preferences
                                where p.CustomerKey == c.CustomerKey
                                && p.CustomConfigurationKey == customConfiguration.CustomConfigurationKey
                                select p.Customer).Contains(c)
                    select c;

I no longer got that exception.

Posted by bmains | with no comments
Filed under:

So, to start out, I thought a little bit about the initial setup for how I could do some testing on the server side of the control.  You have to understand the inner workings of server controls to understand.  At the end of the process, no matter whether the control is a simple control, a composite control, or a control employing data binding or templating, there is a rendering process that converts the contents of the control to it's HTML equivalent.  For instance, a GridView is rendered as a table, a panel as a span, composite controls as a collection of HTML elements, etc.

The control has a Render method that takes an HtmlTextWriter object, which renders all of the content.  With composite control, if no render method is defined, then during rendering phase, the base CompositeControl class calls the Render method on each control.  The HtmlTextWriter object simply uses a stream to write HTML tags, DHTML attributes, and any other content to the underlying stream.  What this means is that the constructor of HtmlTextWriter could take an instance of a StringWriter class, and all HTML is written to a local writer, and easily retrieved through StringWriter.ToString().

To start out with TDD, the following test was created:

[

Test]
public void TestRenderingCalendarHourly() {
   
this.FirstTimeVisible = new TimeSpan(8, 0, 0);
    this.LastTimeVisible = new TimeSpan(16, 0, 0);
   
this.TimeInterval = CalendarDayViewIncrement.Hour;
   
StringWriter textWriter = new StringWriter();
   
HtmlTextWriter htmlWriter = new HtmlTextWriter(textWriter);

 

    this.RenderCalendar(htmlWriter);
   
StringReader reader = new StringReader(textWriter.ToString());
   
XElement doc = XElement.Load(reader);

    var tdTags = from tdTag in doc.Elements("tr").Elements("td")
                     
select tdTag;

    Assert.AreEqual(8, tdTags.Count());
}

Picturing an Outlook calendar, in the current view is a period of time between 8:00 and 4:00 (in this example above).  The length of time between each interval of time is one hour, so every slot in the calendar is an hour.  The StringWriter is passed into the HTMLTextWriter, and the contents are read from a StringReader; textReader.ToString() returns the HTML that is generated from that method.

Now, at this point, when the test is created, by some TDD practitioners, none of the classes, properties, or methods have been implemented.  I personally create the class definition, so it appears in VS intellisense, but most times do not implement the properties and methods (like I said, I'm not always the most faithful TDD practitioner).  What this means is that this unit test being developed drives what is being designed.  The reason is that the test really drives what you need to do in an application.  In a test, you know you need X, Y, and Z pieces of information, and you know you need to perform action A and B, so the unit test fleshes those out in advance.  So from this unit test, it let me know that I needed a FirstTimeVisible and LastTimeVisible properties, a TimeInterval to note the unit of time between each line.  I've also made the decision in the test to use a table tag, and when the first time visible is 8:00 AM and the last is 4:00 PM, and the interval is an hour long, there should be 8 TD tags.  Creating the test first doesn't waste time creating objects, properties, or methods you end up not needing in the end, because you work through the solution in advance.

From this test, this led me to create the following:

protected override void Render(HtmlTextWriter writer)
{
 base.AddAttributesToRender(writer);
 writer.RenderBeginTag(HtmlTextWriterTag.Table);
 writer.RenderBeginTag(HtmlTextWriterTag.Thead);

 writer.RenderEndTag(); //thead
 writer.RenderBeginTag(HtmlTextWriterTag.Tbody);

 this.RenderCalendar(writer);

 writer.RenderEndTag(); //tbody
 writer.RenderEndTag(); //table
}

protected virtual void RenderCalendar(HtmlTextWriter writer)
{
 TimeSpan currentTime = this.FirstTimeVisible;
 int index = 0;

 while (currentTime < this.LastTimeVisible)
 {
  CalendarDayViewItemStyle style = (index % 2 == 0) ? this.GetItemStyle() : this.GetAlternatingStyle();
  this.RenderDayRow(writer, style);

  currentTime = this.AddIncrement(currentTime);
  index++;
 }
}

protected virtual void RenderDayRow(HtmlTextWriter writer, CalendarDayViewItemStyle itemStyle)
{
 writer.RenderBeginTag(HtmlTextWriterTag.Tr);

 writer.AddAttribute(HtmlTextWriterAttribute.Height, itemStyle.Height.ToString());
 if (itemStyle.Width != Unit.Empty)
  writer.AddAttribute(HtmlTextWriterAttribute.Width, itemStyle.Width.ToString());
 ControlRenderingUtility.RenderBorderStyle(writer, itemStyle);
 writer.RenderBeginTag(HtmlTextWriterTag.Td);

 writer.Write("TEST");

 writer.RenderEndTag(); //td
 writer.RenderEndTag(); //tr
}

The Render method sets up the table, the RenderCalendar method actually performs the inside looping/calculation work, while RenderDayRow actually renders a row for a specified timeslot (I think I'll be refactoring that name soon as I think about it).  However, my test fails.  My test calls the RenderCalendar method, which doesn't write XHTML compliant content; instead, it leaves out the beginning table tag, and so the LINQ-to-XML load statement fails, because there isn't a valid root level element.

I also don't think this is the best structure of code also because of separation of concerns, which is defined by Wikipedia as: "separation of concerns (SoC) is the process of breaking a computer program into distinct features that overlap in functionality as little as possible".  In my mind, these methods are too interdependent; RenderDayRow and RenderCalendar are dependent on the table structure setup by Render, while RenderCalendar performs most of the work and expects RenderDayRow to render the entire row.

This will lead me to move the RenderCalendar functionality into the Render method or vice versa; I haven't decided yet.  By the way, in Martin Fowler's Refactoring book, this is one of his defined refactorings, but I don't remember what the name of the Refactoring is!  Anyway, I hope that maybe this is helpful for you to understand that TDD starts out with creating unit tests, even failed ones, and defines the class structures from these tests.  This creates more useful code.  Also, other techniques associated with TDD, such as refactoring, help make code better.

 I've come up with some preliminary design specs of the initial functionality that I want in this control.  I've included some of the interactions that can happen in the control, and the basic view (once I figure out how to attach an image, I'll make that available on this post).  I want to recreate the Outlook style single day view functionality, while making it functional in a rich AJAX sense.  With a TDD approach, I'll create a series of unit tests to test the server-side functionality, and I'll have to come up with some sort of client-side test functionality.  To test the client-side functionality, I've seen others develop their own utilities for testing (test harnesses) to test the client-side rendering.

I'm really excited about a new technology coming out nicknamed Ivonna.  This framework allows you to test ASP.NET pages at a server-level, which is something that wasn't always easily done before.  I can't wait for this to be fully developed.  If you haven't heard of TypeMock Isolator, TypeMock is a very powerful tool that allows you to mock objects, the results returned from it's properties and methods, and even affect the path that the code takes.  It's really dynamic in how it works, and what makes it really great is that it isn't dependent on interfaces; it can mock any object, unlike other mock frameworks.

With that said, I'm also glad that I should be able to utilize ExactMagic TestMatrix to perform my tests; TestMatrix allows me to compile and run my tests directly in Visual Studio, without having to run NUnit.  It also provides code coverage to show me what code wasn't executed through my unit tests.  This makes unit testing a lot easier.

In addition, a calendar often works with scheduling items; I do already have a framework in place for scheduling events, which is very similar in nature. I'm going to try to reuse this code, instead of recreating new code, and we'll see as we get into it.  I may try to minimize the cost by creating a little bit of abstraction to hide those details.  I hope that my posts will be informative and help you in some way understand TDD, agile, and control development.

To start off requirements gathering, I mentioned about a couple of sketches, but really it should start off from a series of stories.  Some of the stories for this project include:

  • User can view their calendar day.
  • User can add new entries to the calendar day.
  • User can scroll up and down the calendar day view.

However, some sources recommend a more formal story approach, as shown below:

  • As a developer, I want to configure the time interval, so I can change the way the calendar renders.
  • As a user, I want to be able to click in the calendar time slot, so I can create a new entry.
  • As a user, I want to be able drag the appointment date to expand the time, so I can adjust the appointment.

You can find some examples of stories here:

I'm not going to go to the point of performing an estimation, because I am not able to put consistent hours into this that it will be harder to track, but for each story, a level of difficulty and a priority is assigned to it; the priority is assigned by the customer, and from the difficulty or risk level is assigned by the developer.  This is what specifies priority.

Posted by bmains | with no comments

I really like some of the components you see in computer magazines.  They have a visually appealing, yet functional approach to being able to schedule work items and tasks, similar to what you can do in Outlook.  I haven't done this yet; it's not coded at all; rather, I'm going to try to blog my progress as I develop this control, and I'm going to try to leverage the newer technologies.

Note all my blog posts won't be related to this, as I do other things that I like to blog about, so I'll prefix my posts with the name of the component (undecided at the moment).  But I hope to put some effort into it using ASP.NET, as well as leveraging the ASP.NET AJAX framework, and using TDD practices as much as possible.  Note two things: it's hard to leverage TDD in a web environment, and that I'm still trying to learn TDD, but generally my TDD practices and methodologies are yet-to-be-desired.

I hope that you may find this beneficial, and that we all learn something about .NET.

Posted by bmains | with no comments
Filed under: ,

Customers are an important part to Agile development.  A portion of the Agile Manifesto reads: "Business people and developers must work together daily throughout the project."  This is a key part ot the software development process, and I'm starting to see why.  As developers, we have to make assumptions about certain aspects of the business process; however, the less assumptions we make and the more we have backed up by fact from the customer, the better.  Communication is key to a healthy application.  Having the customer directly involved in the software development process helps reduce the number of assumptions about the business process.

Assumptions aren't aways bad, but sometimes they can be.  And when assumptions are made out of assumptions, that can cause a trickling effect.  By having the customer available to discuss with at any moment, it weeds out the faulty assumptions about the business process.  It also strengthens design because as we know, customers are UI-driven and so customers can see the development of the product as it is being performed, which also helps to eliminate rework.

If you are a customer and you are reading this, I must warn you to make the development of an agile product your top priority.  I know that every business user usually has a full schedule, and that some users want to be able to pass along the information and then not be involved in any of the future details.  It may seem like the direct communication, which may be frequent, is an annoyance.  But communication, however frequent, is the key to developing a good software product, and all of those correspondences are an attempt by us developers to make sure we stay on track.  So I implore business users to make any questions that come across from an agile project seriously, because it will directly impact the future of the application.

Posted by bmains | with no comments
Filed under:

I'm going to stray from LINQ to SQL to talk a little bit about software development in nature.  In software development, developers are trying to achieve a goal of the customer you are working with.  During requirements gathering, you find out all the particular details and aspects about the goal.  When developing the architecture, you wonder what is the best way to get to the goal without making it too complicated or time-consuming, while making sure that the appropriate functionality is present.  Hopefully, security, scalability, and maintainability are factors in heading in the direction of that goal.  It is during this phase that you make certain choices about how the software should work, feel, and look, all for the purpose of achieving the goal that the customer needs and that your team needs (in the aspects of security, performance, scalability, maintainability, time consumption, etc.).

Software development is often about staying the course because as us developers think about the problem, we tend to think we have a better answer for the a small piece of the architecture at hand, or because it's the easier option.  Easier is never a good solution because it often strays from maintainability.  For instance, it's easier to hard-code values in an application, but for maintainability it's good to put constant data in a central place.  It may be easier to embed SQL code in the UI for a challenging query, but it's better, more maintainable, more performant, to put it in a proc.  It may be better to code your piece of the application a different way, but from the perspective of maintanability, it's better if the code is more uniform than not.

In application development, you have to stay the course sometimes and stick to the game plan.  It's often for the good of the application.

Posted by bmains | with no comments
Filed under: