Tutorial :Beautifying C# Syntax



Question:

In my C#/ASP.NET project I have an object which has certain categories of behavior. Each behavior category is physically dependent on a root object but to make the code read better i want to clearly differentiate the categories. I think it would be interesting to see how my implementation compares to what others might write to solve the same problem.

In the example below i have a class which generates URLs to different places on the website. The website has a storefront which has it's own set of links which should be accessed differently from the urls such as the homepage.

public class WebsiteURLs  {     // One category of urls on the website is the store.     public class StoreURLs     {       private WebsiteURLs _website;       public class StoreURLs(WebsiteURLs website)       {         _website = website;       }       public string BestSellers       {           get { return _website.ResolveURL("~/store/bestSellers.html"); }       }     }     private StoreURLs _store;     public StoreURLs Store // property for generating store urls     {       get       {          if (_store == null ) {            _store = new StoreURLs(this);          }          return _store;       }     }       public string Homepage     {         get { return ResolveURL("~/default.aspx"); }     }       // .. Other Categories Here     protected string ResolveURL(string url)     {       return HttpContext.Current.Response.ApplyAppPathModifier(url);     }  }  

Using this code would look similar to the following

WebsiteURLs website;  Console.WriteLine(website.Store.BestSellers);  

Robert:

The example itself is only one scenario where I have found myself trying to more explicitly organize the functionality. Have you ever found yourself using a prefix around related methods. String.TrimStart(), String.TrimEnd(), String.Trim() is an example that comes to mind from the C# framework.

My attempt to orgnaize the code above (from a readability standpoint) suffers from the inabilty of nested classes to access outer classes members. There is extra work involved in constructing the inner class because i must pass a reference of the WebsiteURLs instance to the constructor of the StoreURLs class, it is almost a violation of C# coding practices because this closure behavior is not the behavior of nested classes within the language. I'm curious what C# code others would use in situations where there exists lots of related functionality (think tens or hundreds of methods). (Note: The code above is much more fluid to write in Java where nested classes do have access to their outer classes members).


Solution:1

My immediate response when I see your example is to think that you're binding something relatively static - a set of types - to something relatively dynamic - a bunch of URLs belonging to a web site. That smells wrong to me. Doing this tightly couples your code to the structure and function of the web site. Any change to any URL anywhere in the web site that you're binding to forces you to rebuild and redeploy your software.

So if you're going to do that, you have to have a pretty good reason. What are you getting out of this? The ability to use type-checking (and IntelliSense, probably) on a hierarchy of web pages. You're paying a really significant cost to get this.

Is it worth it? Is this:

url = website.Store.BestSellers;  

really so much better than this:

url = website.GetUrl("Store.BestSellers");  

that it's worth the amount of work you're going to have to put in just to achieve it?

There are certainly circumstances under which the answer to that question could be "yes." But I wouldn't spend another minute on this design without being sure I knew it.


Solution:2

I'm not sure that I understand the goal. But...

I believe I would just create an interface or base class that does most of the generation work and just derive from it for each category.

Or, create a factory class that responds to a category enumeration.


Solution:3

Use C# Regions. Regions will categories your code properly.

public class WebsiteURLs  {     #region StoreURLs sub-class     // One category of urls on the website is the store.     public class StoreURLs     {       private WebsiteURLs _website;       public class StoreURLs(WebsiteURLs website)       {         _website = website;       }       public string BestSellers       {           get { return _website.ResolveURL("~/store/bestSellers.html"); }       }     }     





        
Previous
Next Post »