Critical Success Factors to Agile .NET Development
In this article I will cover material that includes absolutely critical Microsoft .NET Best Practices that are core to the implementation of patterns and the everyday work of just about any effective .NET Leader.
- Damon W. Carr, CEO and Chief Technologist of agilefactor

August 23, 2005

Introduction
In this article I will cover material that includes absolutely critical Microsoft .NET Best Practices that are core to the implementation of patterns and the everyday work of just about any effective .NET Leader. Here are core concepts covered (which are not all-inclusive but cover the most critical and those I have seen cause the most damage and even the failure of projects). It is assumed you will be working in an Agile environment but if not, these concepts will still work, however you will not reach near the productivity you would with Agile practices (as proven by many studies which can be provided on request as they are too numerous to list) work for any developer wanting to embrace best practices):
  1. 'Design by Contract': 'Design by Contact' as a rule, not an exception, and implement your code where concrete classes are engaging in relations with 'Abstract Classes and Interfaces' most of the time for maximum agility. When you have concrete classes having any knowledge or relations with other concrete classes you dramatically limit your application’s future decisions for expandability. As a rule reduce as much as possible any concrete class to concrete class hard coded knowledge.
  2. Generalization Rules: A child of an abstract class must obviously implement every abstract declared item, but for items marked virtual, you may find it is not needed in the child class. Always try to remember to override the virtual member as well (nothing will force you)to take appropriate action (throw an exception, etc) when the item is not appropriate in the child (if there are many of these I would start to question the semantics of the Generalization relationship).
  3. Refactoring: A progressive refactoring, which is systemic to your work and as natural as breathing, improving your code and your design as you go.
Our Reference Example
Here is code that implements a basic implementation we will follow for the entire article. I will then enhance it to support the DCMR rules of Design by Contract, Metadata and Reflection with continued refactoring:

Here is the abstract Class:

Here are two Children. One is a 'standard' CorporateCustomer:

And here is an interesting and different sub-type:

First Steps
Now there is something quite serious missing: The ability to retrieve an instance of one of these two child classes. YOU DO NOT WANT TO INSTANTIATE THESE DIRECTLY. The typical case I see in practice globally is to create a static 'Instance Factory' in the Abstract Parent. Many people call this a Factory as in the Design Pattern 'Factory' or 'Abstract Factory' and that is incorrect. That's another story...

It is not a good practice to add an 'Instance Creating' method (often mistakenly called a 'Factory Pattern', and typically manifested as a static method living in an Abstract class), that returns a concrete child instance you want via a hard-coded switch statement (unless you knew there would never be additional children off this parent class, a rare occurrence, such a Male and Female as children off of Person, but even then you face complexities, as I have found living in New York (grin)). However the vast majority of developers do just that, by passing in some kind of identifier, with the switch statement making hard coded instantiations via early binding. The addition of new children would require a new compilation and deployment to UAT and Production as you would be forced to modify your hard-coded switch statement (or other conditional logic) and do a completely new deployment to production. You can avoid all that with the practices I show in this article which are key to achieving ‘Agile’ Development optimization. You want to be able to add new children and not have the parent have any knowledge of the children it is supporting. We do this with metadata and reflection, the two immutable cornerstones of expert level .NET Development.

For example, this is NOT how you should create instances of the CorporateCustomer class (as one example):

CorporateCustomer oCustomer = new CorporateCustomer();

Are there times when you have a simple solution and there will never be more then two children (perhaps you have ‘sex’ abstract parent and ‘male’ and ‘female’ children. You could probably just code these, but you should still refer in your code to ‘sex’ not the Types male or female as I will describe shortly.

Instead of direct instantiation (something we will actually make impossible later) there is a static method in the abstract class with the following interface:

public static CustomerAbstract GetCustomer(String CustomerTypeName)

We typically also create an overloaded method which also allows an Assembly Name to be passed in.

So instead of the typical case I see:

CorporateCustomer oCustomer = new CorporateCustomer();

We leverage best practice Object Oriented design and say:

CustomerAbstract oCorporateCustomer = CustomerAbstract.GetCustomer("CSharpPatternsExample.AbstractClassExample.CorporateCustomer");

You are probably thinking 'Refactor'! That Type Name needs to be abstracted as it is so long and hard to remember, but before I get there let me show you the pattern (you cannot use this in all cases as sometimes you need a class like this to have a default constructor with no parameters, but it works in many if not most cases). For each child we add a new Constructor and modify the default constructor (and add a new protected property to the parent):

To be added to the Abstract Parent:

protected bool CreatedFromInstanceFactory = false;

We also add a new constructor for each child:

Then the default constructor becomes:

You can always add a Boolean condition to see if you want to enforce this.

So now when we call:

CorporateCustomer oCustomer = new CorporateCustomer();

We get:

An unhandled exception of type 'System.Exception' occurred in CSharpPatternsExample.exe

Additional information: This child should be instantiated from the static method off the parent called GetCustomer

Very Nice!

So you might be thinking why you returned the type 'CustomerAbstract' from this instantiation method:

CustomerAbstract oCorporateCustomer = CustomerAbstract.GetCustomer("CSharpPatternsExample.AbstractClassExample.CorporateCustomer");

This goes back to the basic statement I made in the beginning about coding to Abstract Classes and Interfaces instead of Concrete classes. Why do we care? Well for one, we have dramatically expanded the flexibility of our application as you will shortly see. We can return other classes we had not anticipated and our code will still work, as we have not bound ourselves to implementation. Instead bind yourself to Interfaces (Abstract Classes or Literal Interfaces). In the original Design Patterns by the ‘Gang of Four’ (GoF) they focus on this but it is Interface Driven. This hurts you as although Interfaces are a critical part of the story, Abstract Classes are often a better choice in C# when implementing patterns.

Using The Core Agility Ratio and Other Metrics
The simple but critical metric that we use and is catching on globally is the ‘Core Agility Ratio’ for agile project development. It is simply a summation in the numerator of all (UML Defined) concrete to concrete class relationships and dependencies (bidirectional counts as 2) and the denominator is the summation of all non-trivial types (an enumeration for example would not be counted).

The goal is to be below 1. Consider an application where we didn’t introduce this abstract base class. Not only would we have to add ‘GetType()’ logic to our application, we would not have the flexibility to add new types after we enter production with no code changes. First let’s create and refactor the code that creates our instance and returns us the one we asked for. Using "CSharpPatternsExample.AbstractClassExample.CorporateCustomer" is long and easy to forget, so it would be nice to just say “CorporateCustomer”. First let’s examine the existing code that we have added to support the dynamic ‘Instance Creation’ via reflection:

We now add a simple configuration file and resolve a new ‘friendly’ name to retrieve the fully qualified name making our code much easier to write. This also allows us to change classes if required (an incredibly powerful capability) so a new assembly could be added to our deployment and it could replace the existing ‘CorporateCustomer’ class with the addition of an overloaded static method that also takes in a metadata defined Assembly Name (shown near the end of the article).

First we add the configuration in appSettings (although you could add your own configuration section or even a separate file as I often do for read-only lookups like a list of states) with the use of the .NET WeakReference type, a very useful type to get in the habit of using.

We want to modify our instance creation to look like:

CustomerAbstract oCorporateCustomer = CustomerAbstract.GetCustomer("CorporateCustomer");

Instead of:

CustomerAbstract oCorporateCustomer = CustomerAbstract.GetCustomer("CSharpPatternsExample.AbstractClassExample.CorporateCustomer");

Here is the metadata in App.Config:

Next we modify the static method in our abstract class to use this metadata instead of always having the verbose string (however as stated before, we could always add a Boolean parameter which would determine if we use this or not).

I have also refactored the static method to be more concise, and I am also using an alternative technique of determining if the instance I am creating in indeed a child instance of the concrete parent (just to illustrate the technique).

Here is the new static Instance Factory in the abstract parent:

You can see that I have added a new private static helper method called GetTypeFromMetadataStringKey. This method takes in the key for the metadata value we are after and returns us a valid Type instance assuming all goes well. Here is the code for this method:

As stated, an interesting thing to note is I have added an alternative way to determine if the instance we created indeed is a child of the abstract parent. This is accomplished on this line:

if (CastChild.GetType().IsSubclassOf(AbstractParentType))

So I call the GetType() method, which provides many helpful properties and methods about the type, one of them being the IsSubclassOf method. I take the extra step of also getting a .Net Type for the Abstract Parent (also in Metadata) and convert the fully qualified name from the constant:

const string CONST_ABSTRACT_PARENT_EASY_NAME = "AbstractCustomer";

So obviously this is not a preferred solution based on all the additional work, but I wanted to illustrate it. Let’s change it back now so it becomes the following (with some additional refactoring to improve the code):

You will notice I introduced a new method called ‘GetInfoFromMetadata’. This is important as I didn’t want to bind my design on the appSettings location. In refactoring this further I would probably introduce a ‘MetadataLocation’ abstract class and have the appSettings be one of many possible subclasses (others could be XML files, Database Calls (although they would be expensive so that should only be done for highly volatile data, etc.).

Here is the new method which simply abstracts the appSettings location:

So at this point our basic code is in place to retrieve children from the Abstract Parent and the Abstract Parent has no knowledge in any of its code of this child (which is a very good thing). We are also free to add new children at will AFTER deployment, by adding an overloaded method to handle children in other Assemblies. This would be a perfect way for an API you expose to your customers to be used so they can build their own children and then add them to the app by adding them to the metadata.

Handling Inherited Members That Are Not Appropriate for a Type
Let’s go back and now get an instance of the TaxExemptCustomer class and illustrate one of the early points of this article : The correct handling of an inherited members that are not appropriate for a type.

First let’s get an instance of this Child Type (remember we use the name of the variable to represent the data type, not the literal type of the Child, as it should always (or next to always) be the Abstract Class.

Here is the line:

CustomerAbstract oExemptCustomer = CustomerAbstract.GetCustomer("ExemptCustomer");

Oops! I forgot to add the Constructor code to not allow users to directly instantiate the type. I see an opportunity to leverage the Abstract Base Class so as a refactoring I move the ‘NotFactoryCreated’ into the CustomerAbstract class and mark it as protected so all children can access it:

This is great, as I can now also move the NotFactoryCreated() check from the constructor of each child and only have it declared once in the constructor of the CustomerAbstract class (as it will always be called when my child instance is called). So the constructor of CorporateCustomer can be empty (as all the children’s can be) and I still get the access protection of guaranteeing my child classes are being created via the ‘Instance Factory’:

So let’s test the original case where we throw an exception for the TaxExemptCustomer class.

First I must add the new constructor to the TaxExemptCustomer class:

public TaxExemptCustomer(bool IsCreatedFromInstanceFactory) : base(IsCreatedFromInstanceFactory)
{}

Now here is the line again we call:

CustomerAbstract oExemptCustomer = CustomerAbstract.GetCustomer("ExemptCustomer");

To verify I indeed have an instance of TaxExemptCustomer I call this line:

Debug.Assert(oExemptCustomer.ToString() == "CSharpPatternsExample.AbstractClassExample.TaxExemptCustomer");

That passes. Now let’s try to set the GovernmentTaxId property:

oExemptCustomer.GovernmentTaxId = "12-432-65427";

We get as expected:

An unhandled exception of type 'System.InvalidOperationException' occurred in CSharpPatternsExample.exe

Additional information: The Tax Exempt Customer Type does not Support or Need this Property

Now let’s do the same on the CorporateCustomer class:

CustomerAbstract oCorporateCustomer = CustomerAbstract.GetCustomer("CorporateCustomer");

oCorporateCustomer.GovernmentTaxId = "12-432-65427";

No problem at all (as expected).

This example can be expanded in many different best case examples. I hope this has cleared up how to take advantage of the power of Metadata, Reflection, and “Design by Contract”.

Summary
If in the future I want to replace either of these classes I only need to change the value of an attribute in an XML file. There are many enhancements that we could make to this sample, and if you are interested we are exploring them in the global ‘C# Design Patterns Expert Group’. If you would like to be a member simply send me an email.

For example, if you are interested in how to evolve this to work with new assemblies or other topics simply email me directly at damon@agilefactor.com.

About the Author
Damon W. Carr
CEO and Chief Technologist agilefactor.

Damon Carr is the CEO and Chief Technologist of agilefactor, based in NY, New York. The company continues its growth via Microsoft.NET Leadership, Software Engineering best practices Agile Process Evolution and the new book by Mr. Carr covering "Agile Software Factories" to be published in early 2006 by Addison-Wesley. Prior to joining agilefactor, Damon was the CTO and Co-Founder of Monetaire, a global company with offices in Europe and the US, where he spearheaded all technical innovation, including their flagship product which was named a 'top three solution' in Europe by Forrester Research. Damon continues to speak at the software industry's most prestigious conferences including the upcoming 'Better Software Conference' (http://www.sqe.com/bettersoftwareconf/) where he is a featured speaker on 'Agile Processes and Software Factory Evolution', he also leads various high profile global user groups.

Contact the author.



  Privacy Statement