comments edit

One of the hidden gems in ASP.NET 2.0 is the new expression syntax. For example, to display the value of a setting in the AppSettings section of your web.config, you can do this:

<asp:Label Text="<%$ AppSettings:AnotherSetting %>"
    ID="setting" 
    runat="server" />

Notice that the value of the Text property of the Label control is set to an expression that is similar to the DataBinding syntax (<%#), but instead of a pound sign (#) it uses a dollar sign ($).

Expressions are distinguished by the expression prefix. In the above example, the prefix is AppSettings.  The following is a short list of built in expression prefixes you can use. I am not sure if there are more:

  • Resources
  • ConnectionStrings
  • AppSettings

But like most things in ASP.NET, this system is extensible, allowing you to easily build your own custom expressions. In this blog post, I’ll walk you through building a query string expression builder. This will allow you to display a query string value like so:

<asp:Label Text="<%$ QueryString:SomeParamName %>"
    ID="setting" 
    runat="server" />

The first step is to create a class that inherits from System.Web.Compilation.ExpressionBuilder. Be sure not to confuse this with System.Web.Configuration.ExpressionBuilder

using System.Web.Compilation;

[ExpressionPrefix("QueryString")]
public class QueryStringExpressionBuilder : ExpressionBuilder
{
  //Implementation goes here...
}

ExpressionBuilder is an abstract class with a single abstract method to implement. This method returns an instance of CodeExpression which is part of the System.CodeDom namespace. For those not familiar with CodeDom, it’s short for Code Document Object Model. It is an API for automatic code generation. The CodeExpression class is an abstract representation of code that gets executed each time your custom expression is evaluated.

You’ll probably use something similar to the following implementation 99% of the time though (sorry for the ugly formatting, but this pretty much mimics the implementation in the MSDN documentation).

public override CodeExpression GetCodeExpression(
    BoundPropertyEntry entry
    , object parsedData
    , ExpressionBuilderContext context)
{
  Type type = entry.DeclaringType;
  PropertyDescriptor descriptor = 
    TypeDescriptor.GetProperties(type)
      [entry.PropertyInfo.Name];
  CodeExpression[] expressionArray = 
    new CodeExpression[3];
  expressionArray[0] = new 
    CodePrimitiveExpression(entry.Expression.Trim());
  expressionArray[1] = new 
    CodeTypeOfExpression(type);
  expressionArray[2] = new 
    CodePrimitiveExpression(entry.Name);

  return new CodeCastExpression(descriptor.PropertyType
    , new CodeMethodInvokeExpression(
        new CodeTypeReferenceExpression(GetType())
        , "GetEvalData"
       , expressionArray));
}

So what exactly is happening in this method? It is effectively generating code. In particular, it generates a call to a static method named GetEvalData which needs to be defined in this class. The return value of this method is then cast to the type returned by descriptor.PropertyType, which is why you see the CodeCastExpression wrapping the other code expressions.

The arguments passed to GetEvalData are represented by the CodeExpression array, expressionArray. The first argument is the expression to evaluate (this is the the part after the prefix). The second argument is the target type. This is the type of the class in which the expression is being evaluated. In our case, this would be the type System.Web.UI.WebControls.Label as we are using this expression within a Label control. The final argument is entry. This is the name of the property being set using the expression. In our case, this would be the Text property of the Label.

You could really build any sort of code tree within this method, but as I said before, most of the time, you will follow a similar pattern as this. In fact, I would probably put this method in some sort of abstract base class and then make sure to define the static GetEvalData method in your inheriting class.

Note, if you choose to move this method into an abstract base class as I described, you can’t make GetEvalData an abstract method in that class because we generated a call to a static method.

You could consider changing the above method to build a call to an instance method, but then you the generate code would have to create the instance everytime your expression is evaluated. It would not have access to an instance of the expression builder automatically. The choice is yours.

Here is the GetEvalData method we need to add to QueryStringExpressionBuilder.

public static object GetEvalData(string expression
    , Type target, string entry)
{
    if (HttpContext.Current == null 
      || HttpContext.Current.Request == null)
        return string.Empty;

    return HttpContext.Current
      .Request.QueryString[expression];
}

With the code for the builder completed, you simply need to add an entry within the compilation section under the system.web section of web.config like so:

<system.web>
  <compilation debug="true">
    <expressionBuilders>
      <add expressionPrefix="QueryString" 
        type="NS.QueryStringExpressionBuilder, AssemblyName"/>
    </expressionBuilders>
  </compilation>
</system.web>

This maps your custom expression class to the expression via its prefix.

In the MSDN examples, they tell you to drop your expression class file into the App_Code directory. This works when you are using the Website Project model. Fortunately, you can also use custom expressions with Web Application Projects. Simply compile your builder into an assembly and make sure to specify the AssemblyName as part of the type attribute when declaring your expression builder.

If you are using the WebSite project model and the App_Code directory, you should leave off the AssemblyName portion of the type.

comments edit

No, this is not a bait and switch post where I try to recruit you to work on Subtext.  A while ago I mentioned that I was participating in The Hidden Network.  So far, I really like it, though I think there is still room for improvement.

If you visit my site (since many of you are reading this in an RSS aggregator), you might have noticed a Jobs link at top.  The link will take you to a full listing of jobs.

The neat thing about this job listings page is that it is hosted by The Hidden Network. I simply added a CName to redirect jobs.haacked.com to hidden network.  They made it extremely easy for me to add a jobs section to my website.

Being bored, I figured I’d take a look through the list to see what kind of job opportunities are available.  Frankly, I am a little bit disappointed.  Many of the jobs sound like yaaaawners.  Perhaps more employers should read my guide, The Art Of The Job Post (If that came across as arrogant, whoops)

The Hidden Network is still pretty young, but over time I’d like to see a lot more jobs listed.  That would make using Geolocation to list jobs that are local to the reader more useful. I also think it’d be neat if I could annotate job postings.

There were a few that did catch my attention…

Sr. Admin, Programmer at Chuck E. Cheese I don’t know if the job itself sounds interesting, but hey! It’s Chuck E. Cheese!  Where a kid can be a kid! I’d ask for a signing bonus that includes free Pizza and  the passcode to play video games onsite for free.

Net, SQL, ASP Developer at Y! Music I have a buddy who works at Yahoo! in Santa Monica and loves it. In a bit of personal trivia, I actually worked on the original Launch.com website, which was later bought by Yahoo! (many iterations later).  I interviewed with Yahoo! in Santa Monica, but chose to go to SkillJam instead.

.NET Software Engineer at IGN If you’re into gaming, this could be alot fun.

The Motley Fool have several jobs listed.  Not sure what they’d be like to work for, but at least you’d get good investment advice while on the job.

There may well be others in there worth mentioning. I wasn’t that bored that I would read the details of every one.  The good thing about these listings is they appear to be real jobs, and not phishing expeditions by head hunters.

This may be a longshot to even ask, but if you end up actually applying for a job because you saw it on my blog, would you let me know? 

If you are an employer, consider posting a job.

comments edit

Participating in the comments section of particularly interesting blog posts is a lot of fun and helps build community.  But one of the annoyances in doing so is that there’s really no good way to keep track of comments.  Unlike new posts in someone’s RSS Feed, most aggregators won’t tell you when there is a new comment.

Sure, there is coComment, but since I like to post comments using my RSS Aggregator via the CommentAPI, coComment isn’t such a help there.

But help is on the way.  Dare Obasanjo recently announced the beta release of Jubilee, the code name for RSS Bandit 1.5.  One of the more interesting features (and my favorite) included in this release is comment watching.

When reading an interesting post, you can right click on the post and select the Watch Comments option.  The following screenshot demonstrates.

Watch
Comments

In a stroke of pure vanity, I will select a blog post in Andrew Stopford’s blog that makes a reference to me and click Watch Comments.

Now if I wait long enough, someone will eventually leave a comment on that post.  Of course, why leave it to chance? I went ahead and left a comment via the browser (sorry Andrew).

When RSS Bandit updates, it shows me that someone left a comment in my Developers category by turning that category green.

New
Comment!

Expanding that node, I can dig down to the post and read the new comment.

New
Comment!

Of course, this only works for blogs that support wfw:commentRss.  Unfortunately, one of my favorite blogs, CodingHorror, which happens to always have lively conversation in the comments section, doesn’t support it.  Jeff, it’s time to move to Subtext!

Kudos go out to Dare and Torsten!  Unfortunately, I’ve been overcommitted and have not been able to contribute to RSS Bandit lately.

comments edit

Now this is a stroke of genius.  If you want people to consider making their .NET applications work on Mono, give them a tool that informs them ahead of time how much trouble (or how easy) it will be to migrate to Mono.

That is exactly what Jonathan Pobst did with the Mono Migration Analyzer (found via Miguel de Icaza).  This tool analyzes compiled assemblies and generates a report identifying issues that might prevent your application from running on Mono.  This report serves as a guide to porting your application to Mono.

Having Subtext run on Mono is a really distant goal for us, but a tool like this could advance the timetable on such a feature, in theory.

I tried to run the analyzer on every assembly in the bin directory of Subtext, but the analyzer threw an exception, doh!  That’s my “Gift Finger” at work (I could not find where to submit error reports so I sent an email to Mr. Pobst. I hope he doesn’t mind).

Moma
Exception

I then re-ran the analyzer selecting only the Subtext.* assemblies.

Subtext Moma
Results

As you can see, we call 12 methods that are still missing in Mono, 23 methods that are not yet implemented, and 13 on their to do list.  Clicking on View Detail Report provides a nice report on which methods are problematic.

In a really smart move, Moma also makes it quite easy to submit results to the Mono team.

Submit
Results

This is a great way to help them plan ahead and prioritize their efforts.  Just for fun, I ran Moma against the BlogML 2.0 assembly and it passed with flying colors.   Moma Blogml
results

Nice!

asp.net, code comments edit

One of the benefits of writing an ASP.NET book is that it forces me to spend a lot of time spelunking deep in the bowels of ASP.NET uncovering all sorts of little gems I never noticed the first time around.

Many of these little morsels should end up in the book, but I thought I would blog about a few of them as I go along. 

This is all part of the weird situation I find myself in while writing this book. I thought I would just sit down and all the words would flow. Instead, no matter how motivated I am, everytime I sit down to write I spend two hours procrastinating for every one hour of writing.  What gives!?

In any case, one of the gems I discovered is the ClientScriptManager.RegisterExpandoAttribute method.  This method allows you to add custom properties to a control.  These properties are not rendered in the HTML as attributes, but simply attached to the control in the DOM via javascript.

This is nice for control authors who want to make a custom control client scriptable, but still maintain XHTML compliance, since XHTML compliance doesn’t allow arbitrary attributes for tags.

The following is a really simple example.  I present here a custom control that inherits from Label.

public class ExpandoControl : Label
{
    //Code to be filled in.
}

The AddAttributesToRender method is the appropriate place to call RegisterExpandoAttribute.

protected override 
    void AddAttributesToRender(HtmlTextWriter writer)
{
    Page.ClientScript.RegisterExpandoAttribute(this.ClientID
                , "contenteditable", "true");
    base.AddAttributesToRender(writer);
}

Now we can access the contenteditable property of this control via client script. The following javascript demonstrates.

var expando = document.getElementById('expando');
alert('Content editable: ' + expando.contenteditable);

This is a good approach to take to develop a client-side api for your custom controls.

comments edit

UPDATE: In my original example, I created my own delegate for converting objects to strings. Kevin Dente pointed out that there is already a perfectly fine delegate for this purpose, the Converter delegate. I updated my code to use that instead. Thanks Kevin!  Just shows you the size and depth of the Framework libraries.

My recent post on concatenating a delimited string sparked quite a bit of commentary.  The inspiration for that post was some code I had to write for a project.  One constraint that I neglected to mention was that I was restricted to .NET 1.1.  Today, I revisit this topic, but with the power of .NET 2.0 in my pocket.

Let’s make our requirements a bit more interesting, shall we?

In this scenario, I have a new class creatively named SomeClass.  This class has a property also creatively named, SomeDate (how do I come up with these imaginative names?!). 

class SomeClass
{
    public SomeClass(DateTime someDate)
    {
        this.SomeDate = someDate;
    }

    public DateTime SomeDate;
}

Suppose I want to concatenate instances of this class together, but this time I want a pipe delimited list of the number of days between now and the SomeDate value.  For example, given the date 11/23/2006, the string should have a “1” since that date was one day ago.  Yes, this is a contrived example, but it will do.

Now I’ll define a new Join method that can take in a delimiter, an enumeration, and an instance of the Converter delegate.  The Converter delegate has the following signature.

delegate TOutput Converter<TIn,TOutput> (TIn input)

As an argument to my Join method, I specify that TOutput should be a string, leaving the input to remain generic.

public static string Join<T>(string delimiter
                             , IEnumerable<T> items
                             , Converter<T, string> converter)
{
    StringBuilder builder = new StringBuilder();
    foreach(T item in items)
    {
        builder.Append(converter(item));
        builder.Append(delimiter);
    }
    if (builder.Length > 0)
        builder.Length = builder.Length - delimiter.Length;

    return builder.ToString();
}

Now with this method defined, I can concatenate an array or collection of SomeClass instances like so:

SomeClass[] someClasses = new SomeClass[]
{
  new SomeClass(DateTime.Parse("1/23/2006"))
  , new SomeClass(DateTime.Parse("12/25/2005"))
  , new SomeClass(DateTime.Parse("5/25/2004"))
};

string result = Join<SomeClass>(|, someClasses
  , delegate(SomeClass item)
    {
        TimeSpan ts = DateTime.Now - item.SomeDate;
      return ((int)ts.TotalDays).ToString();
    });

Console.WriteLine(result);

Notice that I make use of an anonymous delegate that examines an instance of SomeClass and calculates the number of days that SomeDate is in the past.  This returns a string that will be concatenated together.

This code produces the following output.

305|334|913

This gives me a nice reusable method to concatenate collections of objects into delimited strings via the Converter generic delegate. This follows a common pattern in .NET 2.0 embodied by such methods as the List.ForEach method which uses the Action generic delegate and the Array.Find method which uses the Predicate generic delegate.

comments edit

Update: I also wrote a more generic version using anonymous delegates for .NET 2.0 as a followup to this post.

Here’s one for the tip jar. Every now and then I find myself concatening a bunch of values together to create a delimited string.  In fact, I find myself in that very position on a current project. In my case, I am looping through a collection of objects concatenating together three separate strings, each for a different property of the object (long story).

Usually when building such a string, I will append the delimiter to the end of the string I am building during each loop.  But after the looping is complete, I have to remember to peel off that last delimiter.  Let’s look at some code, simplified for the sake of this discussion.

The first thing we’ll define is a fake class for demonstration purposes. It only has one property.

internal class Fake
{
    public Fake(string propValue)
    {
        this.SomeProp = propValue;
    }

    public string SomeProp;
    
    public static Fake[] GetFakes()
    {
        return new Fake[] {new Fake("one")
                , new Fake("two")
                , new Fake("three")
            };
    }
}

Now let’s look at one way to create a pipe delimited string from this array of Fake instances.

Fake[] fakes = Fake.GetFakes();

string delimited = string.Empty;
foreach(Fake fake in fakes)
{
    delimited += fake.SomeProp + "|";
}

delimited = delimited.Substring(0, delimited.Length - 1);
Console.WriteLine(delimited);

I never liked this approach because it is error prone. Do you see the problem? Yep, I forgot to make sure that delimited wasn’t empty when I called substring. I should correct it like so.

if(delimited.Length > 0)
    delimited = delimited.Substring(0, delimited.Length - 1);

When I write code like this, I almost always add a little disclaimer in the comments because I know someone down the line is going to call me an idiot for not using the StringBuilder class to concatenate the string. However, if I know that the size of the strings to concatenate and the number of concatenations will be small, there is no point to using the StringBuilder.  String Concatenations will win out. It all depends on the usage pattern.

But for the sake of completeness, let’s look at the StringBuilder version.

Fake[] fakes = Fake.GetFakes();

StringBuilder builder = new StringBuilder();
foreach(Fake fake in fakes)
{
    builder.Append(fake.SomeProp);
    builder.Append("|");
}

string delimited = builder.ToString();
if(delimited.Length > 0)
    delimited = delimited.Substring(0, delimited.Length - 1);
Console.WriteLine(delimited);

Aesthetically speaking, this code is even uglier because it requires more code. And as I pointed out, depending on the usage pattern, it might not provide a performance benefit. Today, a better approach from a stylistic point of view came to mind. I don’t know why I didn’t think of it earlier.

Fake[] fakes = Fake.GetFakes();

string[] delimited = new string[fakes.Length];
for(int i = 0; i < fakes.Length; i++)
{
    delimited[i] = fakes[i].SomeProp;
}

string delimitedText = String.Join("|", delimited);
Console.WriteLine(delimitedText);

Since I know in advance how many items I am concatenating together (namely fakes.Length number of items), I can fully allocate a string array in advance, populate it with the property values, and then call the static String.Join method.

From a perf perspective, this is probably somewhere between string concatenation and StringBuilder, depending on the usage pattern. But for the most part, String.Join is quite fast, especially in .NET 2.0 (though my current project is on .NET 1.1.  Boohoo!).

Performance issues aside, this approach just feels cleaner to me.  It gets rid of that extra check to remove the trailing delimiter.  String.Join handles that for me.  To me, this is easier to understand.  What do you think?

comments edit

Here in the good ole U.S. and A, soccer doesn’t yet have the huge following or celebrity status that it does overseas. On one level, this is a good thing, as it means getting tickets for a game the day before is never too big a challenge.  On the downside, the quality of the game is often lacking especially when compared to watching a team like FC Barcelona.

However that may change in the future as it is one of the largest, if not largest, sports among kids today.  So while soccer players (excuse me, footballers) in the US don’t have the celebrity status of a Basketball player, there are plenty of fans interested in knowing what it’s like to be a professional player.

My buddies Donny and Cory (past soccer teammates) figured the same thing so they came up with an idea for a show that would highlight pro soccer players in the U.S. (and probably beyond at some point).  The show would basically be a sort of Day In The Life type of format.  I’ve been hearing Donny go on and on about this show for a while now, and it’s great to see it really happening.

Check out this promo video for the show called Beyond the Pitch.  My only contribution to this was to say I thought it was a brilliant idea. Something I’d definitely watch.  This video is a short cut from a pilot they filmed with Kevin Hartman. It’s used to sell the show and may never actually air as an episode.  Keep that in mind, as the final product will probably be even more polished.

comments edit

K. Scott Allen, famous for his OdeToCode blog signed on to be the fourth co-author. His expertise and writing ability will help to compensate for our lack of such things.

A little while ago I wrote an email to the subtext-devs mailing list mentioning that I will be cutting back my day-to-day involvement in Subtext until around spring/summer of the new year.  I will still be involved, of course, but I cannot spend as much time writing code as I have been in the past.

However, my Subtext recruiting post was quite successful and many new developers have joined in to keep Subtext humming along. Not only that, developers who have long been involved with Subtext have also picked up the slack with major contributions.  For that, I am appreciative to see things moving forward toward the best release of Subtext yet sometime in the new year.

So what exactly is keeping me so busy? 

I will be writing a Cook Book style book on ASP.NET 2.0 with my co-authors Jon Galloway and Jeff “CodingHorror” Atwood.  The three of us have long talked about writing a book together, and this opportunity from SitePoint came along at the right time.  We just signed the contract recently and already I am panicking about the various deadlines. Wink

It’s good to get the panic and self-doubts over with early (everyone will hate the book…no worse, they’ll be indifferent to the book and hate me, spitting on me at Mix 09 when I finally release the book years late for rotting their brains just reading a synposis) so I can get to the business of writing a fantastic book.

I’ve contributed a couple of sections to a book before (Windows Developer Power Tools), but that was nothing compared to co-authoring and writing a full third of a book.  I will be looking to my capable co-authors to make me look good.

So you may notice the frequency of blogging drop off for a bit, but I plan to pick it up a bit as I write the book, focusing on little pieces that relate to the book.  Wish us luck!

comments edit

Silver Bullet: From
http://www.tejasthumpcycles.com/Parts/LeversGripsctrls/Silver_Bullet/Silver_Bullet_Shift_Brake.jpg In a recent post I talked about how good design attempts to minimize the impact of changes to a system, often through Design Patterns.

When used appropriately, Design Patterns are a great tool for building a great design, but there is an important caveat to keep in mind anytime you apply a pattern. A Design Pattern might minimize the impact of one kind of change at the expense of amplifying another type of change.

What do I mean by this? One common pattern is the Abstract Factory pattern which is often manifested in .NET code via the Provider Model pattern. The Provider Model abstracts access to an underlying resource by providing a fixed API to the resource. This does a bang up job of insulating the consumer of the provider when changing the underlying resource.

The MembershipProvider is one such implementation of the provider model pattern. The consumer of the MembershipProvider API doesn’t need to change if the SqlMembershipProvider is swapped in favor of the ActiveDirectoryMembershipProvider. This is one way that the provider pattern attempts to minimize the impact of changes. It insulates against changes to the underlying data store.

However there is a hidden tradeoff with this pattern. Suppose the API itself changes often. Then, the impact of a single API change is multiplied across every concrete implementation of the provider. In the case of the MembershipProvider, this is pretty much a non-issue because the likelihood of changing the API is very small.

But the same cannot be said of the data access layer for software such as a blog (or similar software). A common approach is to implement a BlogDataProvider to encapsulate all data access so that the blog software can make use of multiple databases. The basic line of thought is that we can simply implement a concrete provider for each database we wish to support. So we might implement a SqlBlogDataProvider, a MySqlBlogDataProvider, a FireBirdBlogDataProvider, and so on.

This sounds great in theory, but it breaks down in practice because unlike the API to the MembershipProvider, the API for a BlogDatabaseProvider is going to change quite often. Pretty much every new feature one can think of often needs a backing data store.

Everytime we add a new column to a table to support a feature, the impact of that change is multiplied by the number of providers we support. I discussed this in the past in my post entitled Where the Provider Model Falls Short.

Every Design Pattern comes with inherent tradeoffs that we must be aware of. There is no silver bullet.

The key here when looking to apply patterns is to not follow a script for applying patterns blindly. Look at what changes often (in this case the database schema) and figure out how to minimize the impact of that change. In the above scenario, one option is to simply punt the work of supporting multiple databases to someone else in a more generic fashion.

For example, using something like NHibernate or Subsonic in this situation might mean that a schema change only requires changing one bit of code. Then NHibernate or Subsonic is responsible for making sure that the code works against its list of supported databases.

One might object to these approaches because they feel these approaches cannot possibly query every database they support as efficiently as database specific SQL as one would do in a database specific provider. But I think the 80/20 rule applies here. Let the dynamic query engine get you 80% of the way, and use a provider just for the areas that need it.

So again, this is not an indictment of the provider model. The provider model is extremely useful when used appropriately. As I mentioned, the Membership Provider is a great example. But if you really need to support multiple databases AND your database schema is succeptible to a lot of churn, then another pattern may be in order.

comments edit

This one is probably old news to many of you, but I just recently ran across it. Every time I want to add a new control to a new page, I get annoyed because I have to remember that annoying syntax for registering a control.

Let’s see…how does it go again? Do I have to add a TagName attribute? No, that’s for user controls. Hmmm, forget it, I’ll just dynamically add it! Well in the interest of reducing future angst, here are two examples of the syntax, one for a custom control and one for a user control.

<%@ Register TagPrefix="st" Namespace="Subtext.Web.Controls" 
  Assembly="Subtext.Web.Controls" %>
<%@ Register TagName="SomeControl" TagPrefix="st" 
  Src="~/Controls/SomeControl.ascx" %>

The first one registers the tag prefix st with the Subtext.Web.Controls namespace in the Subtext.Web.Controls assembly. The second one registers the tag name SomeControl with the user control SomeControl.ascx

Add this to the top of your page or user control and you can reference a control from this assembly like so:

<st:HelpToolTip id="blah" runat="server" HelpText="Blah!" />
<st:SomeControl id="foo" runat="server" />

A most helpful tooltip!

Fortunately, starting with ASP.NET 2.0, we can register a tag prefix within the Web.config file. This basically makes all the controls within that namespace and assembly available to all pages without having to add that ugly Register declaration.

<system.web>
    <pages>
      <controls>
        <add assembly="Subtext.Web.Controls"
                namespace="Subtext.Web.Controls"
                tagPrefix="st" />
        <add src="~/Controls/SomeControl.ascx"
                tagName="SomeControl"
                tagPrefix="st" />
      </controls>
    </pages>
</system.web>

Thanks to the ASP.NET 2.0 MVP Hacks book for this one.

comments edit

Blue Skies from
Stock.xchng We’ve all been there.  Your project stakeholder stands in your doorway with a coffee mug in hand and asks for one more teeny tiny change.

Yeeeaaah. It’d be great if you could just change the display to include the user’s middle name.  That’s pretty easy, right?

No problem!  Let’s see.  I’ll just need to modify the database schema to add the column, update several stored procedures to reflect the schema change, add a new property to the User class, update the data access code to reflect the new property, and finally update the various user controls that render or take in input for this information.

That’s quite a number of changes to the codebase for one measly little change.

The goal of good software design is to minimize the impact of changes in the code.  Many of you might be having the same reaction to this that you would if I just told you the sky is blue.  Well no duh!  Even so, I think this bears repeating again and again, because this principle is violated in subtle ways, which I will discuss in a follow-on post.

This is one reason that duplicate code is considered such an odoriferous code smell.  When a snippet of code is repeated, a change to the code affects every location in which that snippet is located.

Many Design Patterns focus on minimizing the impact of changes by attempting to look at what varies in a system and encapsulate it

For example, suppose you develop a class that monitors the power level of your Universal Power Supply (UPS) device.  When a power level change occurs, several UI widgets need to be updated.

A naïve implementation might have the UPS class keep a reference to each widget that needs to be updated and directly makes a call to various methods or properties of each widget to update the widget’s state.

The downside of this approach becomes apparent when you need to add a new widget or change a widget.  You now need to update the UPS class because of changes to the UI.  The UPS class is not insulated to changes in the UI

The Observer pattern addresses this issue by changing the direction of the dependency so that the UPS class (the observed) does not have direct knowledge of the UI widgets (the observers).  The widgets all implement a comment observer interface and the UPS class only needs to know about that one interface.  Add a new widget and the code for the class does not need to be updated.  Now the UPS class is insulated from changes to the UI.

Another example of code that is not resilient to change is a class with several methods that contain a similar switch statement.  Going back to the example of the UPS class, suppose the class has several operations it must do every few seconds.  But how it implements each operation is dependent on the current power state.

A naïve implementation might have a switch statement in each method that contains a case for each possible power state.  The problem with this approach is that when we need to add a new power state or edit how an existing state behaves, we have to update multiple existing methods.  The State pattern addresses this problem by encapsulating the behavior of a state in a class.  Thus each power state would be encapsulated in a class and the UPS class would simply delegate calls to its member state instance.

So where is the downside in all this? Seems like these patterns provide a win-win situation for us.  Well in these contrived examples it sure does, but not in every situation.  When used improperly, a pattern in one scenario can actually increase the impact of change in another.  Stay tuned.

comments edit

Subtext Logo I put up a short three question survey on the Subtext website.  If you are a subtext user or thinking about using Subtext, please take a moment and fill it out. It’ll only take a second.

For the first question, if you choose Other, please be kind and comment on this post what that other hosting provider is. Thanks!

The third question bears a bit of explanation.  If you use the web admin to enter a blog post, the Advanced Options allow you to enter a short excerpt for the blog post.  My hunch is that nobody uses it.

This excerpt is displayed when listing posts within a category.  I think we might be better served by having some means to automatically generate an excerpt OR to allow users to mark up their blog posts when using a 3rd party tool so that we can extract an excerpt.

After I get in some results to this survey, I’ll talk about that some more.  Over time I may add some more questions.  So please, if you have a moment, take the survey.

comments edit

Telligent, the hyper-caffeinated people behind Community Server, have just released their latest online service, blogmailr.  This service allows you to post to your blog via email.

Leading up to the unveiling, the Telligenti have been a bit coy about keeping this product shrouded in secrecy.  But with a name like blogmailr, removing the last “e” isn’t quite obfuscating enough to prevent anyone from guessing. ;)

We’ve been working on a mail-to-weblog feature for Subtext, but if you can’t wait for that, you can always give blogmailr a try.  I gave it a quick try and it does indeed work with Subtext. One nice feature of the service is that they support Really Simple Discovery (RSD), popularized by Windows Live Writer, so it is easy to configure.

If you are a fanatic about clean valid semantic markup, you should consider sending your email using plain text.  All the markup gunk that Outlook puts in for rich text emails will make your validator’s head spin.  After posting this very blog post with BlogMailr, I went in and cleaned up the markup.  I’m just anal that way.

If this service takes off, beware of spammers attempting to email random blocks of *@blogmailr.com email addresses.  That would be a particularly effective SPAM attack if they were able to post to your blog via email.

Fortunately, the service generates a random email address used to post to your blog.  It also allows you to specify which email addresses it will accept as a from address.  So a spammer would have to spoof your allowed address and guess your blogmailr address.  Not easily accomplished.

One downside of this approach is it may be difficult for users to remember the generated blogmailr email address. 

Published with BlogMailr

comments edit

Rob Conery just announced the 2.0 release of the Commerce Starter Kit. If you are planning to build a commerce site, it is well worth checking out as it is a full featured modular application built on top of ASP.NET 2.0 and Subsonic.

I know Rob and his team worked hard to get this release ready and Rob especially has poured his heart and soul into the project, building a thriving community around it in that time.  Congratulations to everyone involved!

This good news is tempered by the news that Rob’s father passed away recently.  The announcement of the CSK release includes a heartfelt dedication to his father. I wish you and your family well Rob.

comments edit

Source:
http://www.solarviews.com/raw/earth/earthx.jpg Total world domination has always been a small goal of mine. It’s not that I have an unquenchable thirst for power, it just sounds like a challenging goal and I love challenges.

It’s why I got into software development really. I figure he who controls the computers, can control the world.

But lately, all this involvement in running a company and an open source project leaves me very little time for plotting.  I realized I need help.  I need a minion. Someone to help me carry on my work.  Another Haacker.  So my wife and I hatched a plan and the incubation process has begun.

Sometime in June, the incubation period ends and phase 2 will begin as we add another member to our domination plans.  A baby Haack.

Initially, this new Haacker will actually slow our progress in achieving world domination as we put him or her through an orientation period.  It will take some time to get up to speed on essential skills such as speech, motor coordination, and control over bowel movements - which we’ve dubbed milestone 1.

But soon enough, our progress will increase as the newest member of our plot infiltrates the school system sowing the seeds of revolution. 

Yep, good times are ahead.

code, open source comments edit

I have a few great openings available that I have to share with you.  These are really great positions working with really interesting and smart people all over the world. 

Some of the outstanding benefits include:

  • Work from home.
  • Work for a great project lead (me!).
  • Work with an international team of really great developers.
  • Work on a product used by thousands of people and seen by many more.
  • Work tasks are pretty much self-directed.  Nobody is looking over your shoulder.
  • Set your own schedule and work at your own pace.
  • Interesting cutting-edge ASP.NET work. 
  • Gain great experience working on a product and increase your marketable skills.

Some of the interesting projects include:

  • Building a next-gen plugin architecture.
  • Localization and Internationalization.
  • Advanced Skinning architecture.
  • General application architecture and API improvement.
  • Streamlined UI design using AJAX.
  • Advanced Bayesian statistical analysis coding.
  • Windows CardSpaces and Infocard.

For such a great opportunity, I must warn you about a few of the downsides.

  • No health care
  • No Pay

I have a gut feeling that second downside is going to be a bit of a deal breaker for a lot of people.  But did I mention you can work as many or as few hours as you wish?

As you probably figured out already, I am attempting to recruit people to contribute to the Subtext Project.  I have to cut down the number of hours I put into the project for the rest of the year and into the first couple months of the next year for a couple reasons I will mention later.  I’ll still be heavily involved, but won’t be able to contribute as much code as I have been.

Why Accept No Pay For Work?

I’ve written on this a bit before.

In truth, there are many reasons people work on open source software, and they are not all the same. Many just find it fun to work on something more interesting than the boring data-in data-out systems they build at work. Some want to have a hand in building a better mousetrap. Many enjoy participating in a community and perhaps gaining a bit of recognition among their peers.

However there is another angle I want to promote.  It can help you get a better job.  On one hand, it helps you get experience in skillsets you might not otherwise exercise at your current job.

37signals, that über hot company right now, see Open Source contributions as a great way to judge a potential candidate.

Open source is a gift to those who need to hire technical people. With open source, you can track someone’s work and contributions — good and bad — over a lengthy period of time.

That means you can judge people by their actions instead of just their words. You can make a decision based on the things that really matter:

In fact, they only hire people they know through open source. Most companies aren’t that extreme, but trust me, it’s a serious turn on to a potential employer.

Hmmm… I’m Intrigued. What Do You Need?

Great!  Glad you asked!

We have a great team as it stands, but we can always use more help in any and every area.  Everyone is welcome to contribute to anything. Even so, I would like to have a few people step up and become responsible for a few areas.  That person doesn’t necessarily have to do the work in the respective area, but just take ownership of getting people to contribute and get it down.  Basically I want to decompose Subtext into multiple smaller projects. Here are some of our needs: 

Documentation Guru:We need someone to be in charge of documentation.  This would include making sure our project website is up to date.  It can also include generating NDoc documentation and posting it on our site, etc…  In fact, it’d be nice to have our project website redesigned to be a better resource for Subtext users.

Build and Deployment Master: Right now, this has been handled by a combination of Me, Steve Harman, and Simone (Simo) Chiaretta.  Unless Simo wants this title, I think it’d be nice to have one person be responsible for maintaining our Continuous Integration and built scripts as well as our final deployments.

QA Manager and Testers: We need more people to help out with QA before we release builds, but one person to manage this process. I have someone in mind for this, but I thought I’d put it out there since we could use more help in this area.  This would include helping us increase our unit test coverage and start getting WATIR tests going.  After the last error plagued release (my fault), I want to get more serious in this area.

Developers, Developers, Developers: And of course, we need more developers!  We have several ongoing mini-projects we could use help in.  Simo is chugging away on our new plugin framework, but I know he’d appreciate some help as well as someone to start writing some initial plugins to deploy with Subtext.

I have a new skinning architecture I want to get in place, but I won’t have the time to implement it, though I can describe it to anyone who will listen in great detail.

Robb Allen is working on our new membership provider.  I’m sure he’d love to have some help finishing the integration with Subtext.

And there are many more minor tasks that we’d like to get done such as general bug fixes, feature requests, code refactorings.  I’d like to clean up some of our data access architecture to streamline it a bit. Maybe even evaluate using Subsonic.

Wrap Up

To be clear, any and all contributions are worthy and helpful.  I may be ambitious asking for volunteers to take on these specific management roles, but it’s worth a try.

However, if you have some time to contribute, but don’t want to take on a management role, don’t let this dissuade you.  For example, if you don’t have time to help manage the QA process, but can do testing for a bit here and there when we are preparing a release, please jump on in! 

If you are interested in joining in the efforts, start by subscribing to thesubtext-devs mailing list and we’ll get you going.

comments edit

A while ago I mentioned that my company, in collaboration with Shepard Associates built two websites for a medical device company using DotNetNuke (aka DNN).

Well we just learned that the client’s websites we built won three WebAwards from the Web Marketing Association. Cool!

I will admit, I don’t know much about the association or their awards.  It just feels good to see our hard work (by our I mean everyone involved including the client and Shepard) recognized.  Especially considering the torturous work it took to coerce, fight, and bend DNN to obey our will in order to implement these sites.

comments edit

I love Halloween because it makes for great parties. What makes a party great? Costumes! This past weekend I drove up from Los Angeles to San Jose to stay with my friend Kyle and his wife Cara. That evening we drove up to San Francisco to attend a house party in a large four story house in the hills. It was about the perfect size for the 100+ people in attendance, and they hade a few top-notch local DJs spinning.

Unfortunately, I didn’t bring my camera so I had to rely on “donated pics”. I usually am a total shutterfly. Of course, not having my camera gave me more time to enjoy the party. Click on a pic for a larger version.

Hunter S. Thompson and Noam
Chomsky Group of people outside the
house

My buddy Kyle went as Noam Chomsky, which was a hit of a costume, as simple as it was. It’s rather freaky to see a black and white 2-D face on a normal body. The face looked almost disembodied. The first pic with Hunter S. Thompson just cracks me up. What a literary powerhouse! I went as the thoroughly unimaginative “Kung-Fu guy”. The necklace I’m wearing is made up of miniature skulls of my enemies. Yes, I fight those crazy Lilliputians.

The DEA agent was probably one of my favorite costumes, just for the chill he sent down the spine of some partygoers.

Steve Irwin, the Crocodile
HunterCartman
and
Snack

As expected, someone with showed up in a Crocodile Hunter costume, though I don’t understand the red wig. We also had Cartman and his favorite snack in attendance.

Inside the
party The
Governator

Finally, the governator showed up, but he was inappropriately dressed. I had to black out that portion of his costume. Let’s just say, it took a pretty big circle to black that portion out. Good going Guv’nor!

BeakerCount
Pimpula and
Cheerleader

The beaker costume above was one of my favorites.  She and her boyfriend both were beakers. Apparently the sight of them making out was disturbing.  That’s my friend Jason aka Count Pimpula on the right with his girl Rocel.