Make Your Object a Celebrity

Back Draft

 

Make Your Object a Celebrity

 

By Jonathan Goodyear

 

Have you ever noticed that the more popular a person gets, the more secretive they become and the harder it is to get in contact with them? These celebrities have agents and lawyers that speak and act on their behalf. Everything gets filtered, so that the public only sees and hears what is intended (well, unless the tabloids step in). Most of the time, you get a consistent message of who the celebrity is, what they stand for, etc. Basically, you get only what the celebrity thinks you need to know.

 

In the case of real celebrities, this can be highly annoying; but when debugging a program, I think it would be darn convenient if the objects I had built had their own agents that would concisely tell me only what I needed to know. Luckily, you can enable just such a feature in Visual Studio 2005 (or Visual Studio Express) by creating a type proxy. A type proxy is an internal class that you implement in your business objects that becomes the face of your object when it is viewed in the debug window. Basically, this view doesn t show all the internal fields and other complexities that make your object difficult to interpret.

 

As a simple example, take a look at the Car object in Figure 1.

 

[DebuggerTypeProxy(typeof(CarProxy))]

class Car

{

 private string _make = string.Empty;

 private string _model = string.Empty;

 private int _year = 0;

 public string Make

 {

     get { return _make; }

     set { _make = value; }

 }

 public string Model

 {

     get { return _model; }

     set { _model = value; }

 }

 public int Year

 {

     get { return _year; }

     set { _year = value; }

 }

 public Car()

 {

 }

 internal class CarProxy

 {

     private Car _car;

     public CarProxy(Car car)

      {

         _car = car;

     }

     public string Car

     {

         get {return _car.Year + " " + _car.Make +

   " " + _car.Model;}

     }

      [DebuggerDisplay("{ValidateObject()}")]

     public string ValidationErrors

     {

         //overridden by DebuggerDisplay attribute

         get { return string.Empty; }

     }

     private string ValidateObject()

     {

         List violations = new List();

         if (0 == _car.Make.Length)

         {

           violations.Add("Make has not been specified");

         }

         if (0 == _car.Model.Length)

         {

           violations.Add("Model has not been specified");

         }

         if (0 == _car.Year)

         {

           violations.Add("Year has not been specified");

         }

         return string.Join(", ", violations.ToArray());

     }

 }

}

Figure 1: Our sample Car object.

 

Note that you ll need to import the System.Diagnostics namespace for the code in Figure 1 to work. Inside the Car class is an internal CarProxy class whose constructor accepts an instance of the Car class. It then has a public Car property that constructs a friendly view of the properties of the Car class that will be displayed in the debug window. Of course, this type proxy can have more than one property if you desire, but I kept this example simple. The DebuggerTypeProxy attribute that decorates the Car class declaration wires the internal CarProxy class to represent the Car class when it is viewed in the debug window.

 

The next thing that you might notice is that I implemented a ValidationErrors property of type string, and decorated it with the DebuggerDisplay attribute. The DebuggerDisplay attribute allows you to override the data that will be displayed for a particular item in the debug window. It can be applied to either a member of a type proxy (as in this example) or to a member of its containing class. Anything contained within the DebuggerDisplay attribute will be rendered in the debug window.

 

Code can be inserted into the expression by enclosing it in curly braces. While simple validations can be performed inline in the attribute itself, I find it preferable to reference a private method that does the heavy lifting. The ValidateObject method checks the status of various properties of the Car object and adds messages to the violations variable when it finds problems with its state. It then concatenates the messages (separated by commas) and returns that as a result of the method.

 

That message then gets displayed in the debug window, giving you a concise view of anything that is wrong with the object s state. It may not be much of a time saver for a simple object like this. However, if your object is very large, with nested objects and collections, it could save you a lot of hunting to find problems. You instantly know whether your object is in a valid state or not.

 

The following code shows a potential implementation of the Car class:

 

Car c = new Car();

c.Year = 2004;

c.Make = "Porsche";

 

The Model property of the Car class was not populated with a value. When viewed in the debug window, the Car class would look like Figure 2.

 


Figure 2: The Car class viewed in the debug window.

 

The CarProxy class is used when the Car object instance is viewed in the debug window. The Car property of the CarProxy class shows a concise view of the underlying Car object and the ValidationErrors property displays the error that is reported by the ValidateObject method. For demonstration purposes I ve expanded the Raw View node, which gives you access to all the underlying fields and properties of the Car class. This is what would have appeared in the debug window had I not implemented a type proxy. It doesn t take long for the Raw View to get large and unwieldy, so a type proxy is definitely the way to go.

 

As you can see, it is not that hard to turn your objects into celebrities by using type proxies and the DebuggerDisplay attribute. They ll filter out all the information that you usually don t need to see, and quickly give you the information that you deem important. The Raw View can be equated to the tabloids that will let you see your object s deepest darkest secrets. Now that I have given you this overview, go ahead and take a closer look at all that the System.Diagnostics namespace has to offer in Visual Studio 2005. You ll be amazed at what you find.

 

Jonathan Goodyear is president of ASPSoft (http://www.aspsoft.com), an Internet consulting firm based in Orlando, FL. Jonathan is Microsoft Regional Director for Florida, a Microsoft Certified Solution Developer (MCSD), and author of Debugging ASP.NET (New Riders). Jonathan also is a contributing editor for asp.netPRO. E-mail him at mailto:[email protected] or through his angryCoder eZine at http://www.angryCoder.com.

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish