Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Overview

Download

Right click “Save as…”

Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready -Overview

We’re now on the ninth installment of Extreme ASP.NET Makeover. In part 8, we discovered that the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can lead to unexpected NullReferenceExceptions after apparently innocuous changes to the code. We refactored AuthorizationChecker to eliminate the dependency problems, but we did not address the elephant in the room—ScrewTurn.Wiki.Host. This article confronts the problems of ScrewTurn.Wiki.Host head-on in an effort to tame its wild ways.

Another Look at Host

Host’s primary purpose is to act as a facade between ScrewTurn Wiki’s plug-ins (aka “Providers”) and ScrewTurn Wiki itself. Host allows plug-ins to do everything from retrieving settings values to sending emails to handling backups to finding users, Wiki pages, namespaces, categories, and more, as shown in Figure 1.

 

Figure 1 IHostV30

The plug-ins, which implement IProviderV30, are initialized with a Host instance and a configuration string through their Init method:

public interface IProviderV30 {
    void Init(IHostV30 host, string config);
    void Shutdown();
    ComponentInformation Information { get; }
    string ConfigHelpHtml { get; }
}

Looking at Host’s constructor, no dependency problems are immediately evident:

public class Host : IHostV30 {
    public Host() {
        customSpecialTags = new Dictionary<string, CustomToolbarItem>(5);
    }
    ...
}

The plug-in system seems fairly innocuous, but the devil is in the details. Let’s dig a little deeper and see what we find.

The First Step is Realizing You Have a Problem

Given Host’s role as a facade object for the plug-in system and its overly simplistic constructor, I suspect that there is a dependency problem lurking beneath the surface. So I have enrolled Host in Dependency-aholics Anonymous. The first step in this twelve-step program is to make Host’s dependencies obvious, just as we did in part 8 when working with AuthorizationChecker.

I’m not too concerned at the moment about static helper classes, such as ScrewTurn.Wiki.Tools or ScrewTurn.Wiki.Formatter. Static helper classes are often a rich source of inspiration for domain concepts. For example, if you have helper methods for performing arithmetic operations on currency, introduce a Money class to encapsulate the data and behavior. If you have helper methods comparing whole dates, introduce a Date class. Yes, .NET has a DateTime class, but it includes both the date and the time. Don’t be afraid to create a Date or Time class that is tailored to the needs of your application. If you deal with financial data, working with a strongly-typed FiscalPeriod class is going to be a lot easier than passing around DateTime objects and remembering to call Helpers.ConvertToFiscal(someDate) to ensure that the DateTime is properly aligned to a fiscal period.

But static helpers aren’t our concern at the moment because these are most often simple stateless methods that have little to no coupling to the rest of the application. We are looking for hidden dependencies that wind their tentacles insidiously throughout the application. The dependencies that have dependencies that have dependencies ad infinitum, resulting in unnecessary coupling and rigidity in the codebase. To find these, we need look no further than the Singletons to which Host delegates much of its responsibilities.

Other videos from this article

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx

Tags:

Follow the Discussion

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.