Bilal+and+Abner+Project+3

SSE-659 Project 3
toc

1.0 Objective
Patterns are used to make cleaner codes and also are the basis for building Object-Oriented projects. This project is about refactoring using pattern methods. The methods and Ideas listed in this project is found in the Refactoring to Patterns article written by Joshua Kerievsky. This project covers an Object-Oriented method when it comes to refactoring code and also testing of the code to ensure functionality with NUnit.

2.0 Chain constructors
Chain Constructors is used when you have multiple constructors that have duplicated code. Duplicated code is one of the bad smells that you can find in code according to the Refactoring, Improving the design of existing code book. When a programmer sees duplicated code its first instinct should be how he could combine all the duplicated code. Chain Constructors method takes the duplicated code from multiple constructors in a class then simplifies it by having one of the constructors as the catch-all constructor, which is the last constructor in the chain. Below is a snippet of code from the ObjectCreateRule.cs class from the NDigsister application. code format="csharp" public ObjectCreateRule(string typeName) : this(typeName, null) {           // use this constructor }

///        /// Initializes a new instance of the ObjectCreateRule class with a specified /// type of the object to be created. ///        /// The type of the object to be created. public ObjectCreateRule(Type type) : this(type, null) {           // use this constructor }

///        /// Initializes a new instance of the ObjectCreateRule class with a specified /// name of the object's type to be created and attribute name that can override the /// specified type name. ///        /// The name of the object type to be created. /// The element's attribute name that optionally overrides /// the default type to be created. /// The typeName of the object to create must be a fully qualified type name /// in the format "MyCompany.MyProduct.MyType, MyAssembly". public ObjectCreateRule(string typeName, string attribute) {           this.type = Type.GetType(typeName, true, true); this.attribute = attribute; }       ///         /// Initializes a new instance of the ObjectCreateRule class with a specified /// type of the object to be created and attribute name that can override the /// specified type. ///        /// The type of the object to be created. /// The element's attribute name that optionally overrides /// the default type to be created. public ObjectCreateRule(Type type, string attribute) {           this.type = type; this.attribute = attribute; }

code The class has a total of 4 constructors and is using the chain constructor method. The first constructor is chained with the 3rd constructor, and the second constructor is chained with the 4th constructor. The first constructor and third constructor share the string typeName field, to get rid of the duplicate code. The 1st constructor calls the third constructor by replacing the attribute field with a null object. code format="csharp" public ObjectCreateRule(string typeName) : this(typeName, null) {           // use this constructor }

public ObjectCreateRule(string typeName, string attribute) {           this.type = Type.GetType(typeName, true, true); this.attribute = attribute; }

The wrong way to have this code would have been not using constructor chaining as shown below. The public ObjectCreateRule(string typeName)

{           This._typeName= typeName; }

public ObjectCreateRule(string typeName, string attribute) {           this.type = Type.GetType(typeName, true, true); this.attribute = attribute; }

code Below are the 2nd and the 4th constructor. The second and 4th constructor has the type field in common and the 2nd constructor is used to call the 4th constructor by using a null object to replace the attribute object. code format="csharp" public ObjectCreateRule(Type type) : this(type, null) {           // use this constructor }

public ObjectCreateRule(Type type, string attribute) {           this.type = type; this.attribute = attribute; }

code

2.1 Encapsulate SubClasses with Creation method
This section covers the Encapsulate Subclasses with Creation Method. This method is used to protect the constructors of the subclasses from being instantiated by the client. This method protects the constructors of the subclasses and lets the client instantiate the subclasses from the super class. Protecting the subclasses from the client makes sure that the client code is not changing or adding special methods to the subclasses that are supposed to be under on super class. Below is a code from the rules abstract class.

code format="csharp" using System; using System.Collections.Specialized;

namespace DotnetPark.Commons.NDigester {   ///     /// Concrete implementations of this class implement actions to be taken when /// a corresponding nested pattern of XML elements has been matched. ///    public abstract class Rule {       /// The Digester with which this Rule is associated. protected Digester digester;

/// The namespace URI for which this Rule is relevant, if any. protected string namespaceURI;

///        /// Initialize a new instance of the Rule class. ///        public Rule {           digester = null; namespaceURI = String.Empty; }

///        /// Initialize a new instance of the Rule class with the Digester specified. ///        /// The Digester that is associated with this Rule. public Rule(Digester digester) : base {           this.digester = digester; }

///        /// Sets or gets the Digester with which this Rule is associated. ///        public Digester Digester {           get {               return digester; }           set {               digester = value; }       }

///        /// Sets and gets the namespace URI for which this Rule is relevant, if any. ///        public string NamespaceURI {           get {               return namespaceURI; }           set {               namespaceURI = value; }       }

///        /// This method is called when the beginning of a matching XML element /// is encountered. ///        public virtual void OnBegin {           // The default implementation does nothing }

///        /// This method is called when the body of a matching XML element /// is encountered. If the element has no body, this method is       /// not called at all. ///        public virtual void OnBody {           // The default implementation does nothing }

///        /// This method is called when the end of a matching XML element /// is encountered. ///        public virtual void OnEnd {           // The default implementation does nothing }

///        /// This method is called when the parsing process was finished. /// It primary used for disposing resources that was locked by a rule. ///        public virtual void OnFinish {           // The default implementation does nothing }   } }

code

This class is the super class and it has subclass that uses its method. To implement the current method, we would have to first protect the constructor of the subclasses. Below is the code showing that all the constructors in the CallMethodRule class have the protected sign in front of it.

code format="csharp" public class CallMethodRule : Rule {       private string methodName = null; private int paramCount = -1; private Type[] paramTypes = null; private string body = null;

///        /// Initializes a new instance of the CallMethodRule class with a specified mathod name. ///        /// The name of the method to be called. /// When only a single methodName specified rule will try to find /// a method without parameters in case of many overloads of the specified method. protected CallMethodRule(string methodName) : this(methodName, -1, null) {           // use this }

///        /// Initializes a new instance of the CallMethodRule class with a specified /// mathod name and a number of parameters to be used. ///        /// The name of the method to be called. /// The number of parameters used in method invoking. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call. protected CallMethodRule(string methodName, int paramCount) : this(methodName, paramCount, null) {           // use this }

///        /// Initializes a new instance of the CallMethodRule class with a specified /// mathod name and a number of parameters to be used. ///        /// The name of the method to be called. /// The number of parameters used in method invoking. /// The mixed array of objects any of type System.Type /// or System.String that describes the types of the input parameters and helps to find /// method with an appropriate signature in case of miltiple overloads. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call. protected CallMethodRule(string methodName, int paramCount, params object[] paramTypes) {           this.methodName = methodName; this.paramCount = paramCount;

code

The next step is to add a way for the client to instantiate the subclass from the super class. The code below is what the client would use to instantiate the callMethodRule subclass. The client class can only instantiate it from the super class.

code format="csharp" public static Rule NewCallMethodRule {           return new CallMethodRule; }

code

2.2 Replace hard-coded notifications with Observer
This method is about applying the Observer pattern to your code if you are using hard-coded notifications. Hard-coded notifications are used in a code if the client class needs to know or update the status to or from another class. For example, you could have a class that searches for what each investor’s response is based on the price of a stock. A hard-coded design gets complicated when you start having multiple investors. Every time you add a new investor, you would have to hard-code it in, which takes time and makes for sloppy coding. Below is what the diagram looks like for a Hard-Coded Notification using the investor program:

Looking at the diagram it would be very difficult to add new investors or new stocks to the design. Using the Observer pattern gives us the flexibility to achieve both of these goals. The pattern below shows the observer pattern diagram for the investor program:

The above code shows that in the observer pattern you would have a stocktrader class that attaches new investors to the observer, the concrete subject is the gold class, but you could add other subjects without having to change any other class, The observer class holds the obersver state after knowing the concrete subject’s state and updates the concrete subject with its result. **Subject** (Stock Trader)**:**This class knows the number of observers that’s following the subject, and it also provides an interface to add, delete and notify all the current observers. The class below shows the responsibilities of the subject class. code format="csharp" abstract class StockTrader {       private string symbol; private double _price; private string name;

public List investors = new List;

public StockTrader(string symbol, double price) {           this.symbol = symbol; this._price = price; }

public void Attach(IInvestor investor) {           investors.Add(investor);

}

public void Detach(IInvestor investor) {           if(investors.Contains(investor)) investors.Remove(investor); }

public void Notify {           foreach (IInvestor investor in investors) {               investor.Update(this); }       }

// Gets or sets the price public double Price {           get { return _price; }

set {               if (_price != value) {                   _price = value; Notify; }           }        }

public string Symbol {           get { return symbol; } }

}

code

**Concrete Subject** (Gold Class)**:** This class stores the state of interest for concrete observers. Sends notification when it states changes. In the current application the Gold class stores the state of the symbol and the price of the stock, if any of those changes the Investor class will get a notice of the change. The concrete subjects gets all its method from the subject class shown in the code below: code format="csharp" class Gold : StockTrader {

public Gold(string symbol, double price) : base(symbol, price) {       }    }

code code format="csharp" class Investor : IInvestor {       public string name; public double PriceToBuy; public double PriceToSell; private StockTrader stock;
 * Concrete Observer** (Investor Class)**:** This Class maintains a reference to the concrete subject object, which in our case is the Gold class. It holds the current state of the symbol and price of the gold stock, and also uses the Update method to stay current with the subject.

public Investor(string name, double PriceToBuy, double PriceToSell) {           this.name = name; this.PriceToBuy = PriceToBuy; this.PriceToSell = PriceToSell; }

public void Update(StockTrader stock) {           if (PriceToBuy >= stock.Price) {               Console.WriteLine("{0} is willing to buy {1} stocks at the {2:C} price", name, stock.Symbol, stock.Price); }           else if (PriceToSell <= stock.Price) {                   Console.WriteLine("{0} is willing to sell {1} stocks at the {2:C} price", name, stock.Symbol,                    stock.Price); }               else Console.WriteLine("{0} is holding on making a decision on the {1} stocks at the {2:C} price", name,                  stock.Symbol, stock.Price);

}

public StockTrader Stock {           get { return stock; } set { stock = value; } }       public string Name {           get { return name; } set { name = value; } }   }

code

2.3 Replace multiple constructors with Creation method
If there are multiple constructors, the programmers will have to decide which constructor to utilize by studying which parameters are expected by the program. Multiple constructors don’t communicate their intention effectively since it is easier for programmers to mistakenly select the wrong constructor. As systems mature, programmer often add more and more constructors to classes without first removing dead constructor code which make the code harder to follow. This refactoring technique focuses on replacing the constructors with Creation Methods which are intention-revealing methods and they return object instances.

The first step is to identify the class with multiple constructors that take abundant parameters and can easily makes it harder for developer to decide which constructor to call to obtain an instance. I utilize CallMethodRule.cs class from open source software called NDigester. This class contains the following multiple constructors with many parameters as shown below: code format="csharp" using System; using System.Text; using System.Reflection;

namespace DotnetPark.Commons.NDigester {   ///     /// Rule implementation that calls a method on the top (parent) /// object, passing arguments collected from subsequent /// CallParamRule</c> rules or from the body of this /// element. /// By using CallMethodRule(String methodName)</c> /// a method call can be made to a method which accepts no arguments. ///    public class CallMethodRule : Rule {       private string methodName = null; private int paramCount = -1; private Type[] paramTypes = null; private string body = null;

///        /// Initializes a new instance of the CallMethodRule class with a specified mathod name. ///        /// <param name=”methodName”>The name of the method to be called. /// When only a single methodName specified rule will try to find /// a method without parameters in case of many overloads of the specified method. public CallMethodRule(string methodName) : this(methodName, -1, null) {           // use this }

///        /// Initializes a new instance of the CallMethodRule class with a specified /// mathod name and a number of parameters to be used. ///        /// <param name=”methodName”>The name of the method to be called. /// <param name=”paramCount”>The number of parameters used in method invoking. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call. public CallMethodRule(string methodName, int paramCount) : this(methodName, paramCount, null) {           // use this }

///        /// Initializes a new instance of the CallMethodRule class with a specified /// mathod name and a number of parameters to be used. ///        /// <param name=”methodName”>The name of the method to be called. /// <param name=”paramCount”>The number of parameters used in method invoking. /// <param name=”paramTypes”>The mixed array of objects any of type System.Type</c> /// or System.String</c> that describes the types of the input parameters and helps to find /// method with an appropriate signature in case of miltiple overloads. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call. public CallMethodRule(string methodName, int paramCount, params object[] paramTypes) {           this.methodName = methodName; this.paramCount = paramCount;

if(paramTypes != null) {               this.paramTypes = new Type[paramTypes.Length]; for(int i=0; i<paramTypes.Length; i++) {                   object type = paramTypes[i]; if(type is String) {                       this.paramTypes[i] = Type.GetType((string)type); }                   else if(type is Type) {                       this.paramTypes[i] = (Type)type; }                   else {                       throw new Exception(“You must specify only objects of type \”System.String                                                \” and \”System.Type\” here!”); }               }            }        }

code The next step is to identify the catch-all constructor and make it private or protected. There are three constructors in CallMethodRule.cs and I selected the third constructor to be the catch-all constructor since it takes more parameters and I made it protected as shown below:

code format="csharp" protected CallMethodRule(string methodName, int paramCount, params object[] paramTypes) {           this.methodName = methodName; this.paramCount = paramCount;

if(paramTypes != null) {               this.paramTypes = new Type[paramTypes.Length]; for(int i=0; i<paramTypes.Length; i++) {                   object type = paramTypes[i]; if(type is String) {                       this.paramTypes[i] = Type.GetType((string)type); }                   else if(type is Type) {                       this.paramTypes[i] = (Type)type; }                   else {                       throw new Exception("You must specify only objects of type                                                \"System.String\" and \"System.Type\" here!"); }               }            }        }

code The third step is to identify the types of objects that can be created using one of CallMethodRule constructors and in this case I identify the following types:


 * 1) Method Rule with default parameter count
 * 2) Method Rule with custom parameter count
 * 3) Parameter type with default parameter count
 * 4) Parameter type with custom parameter count

I begin by writing a test for a new Creation Method which will return a default method name as shown below:

code format="csharp" // Writing a test for a new Creation Method

public void testMethodRule {

CallMethodRule methodRule = CallMethodRule.newRuleWithParamCount("FirstMethod", paramCount); Assert.NotNull(methodRule); Assert.AreEqual(methodRule.paramCount, methodRule.GetType);

}

code The static method called newRuleWithParamCount is utilized for the program to compile or run. code format="csharp" static CallMethodRule newRuleWithParamCount(string methodName, int paramCount) {          return new CallMethodRule(methodName, -1, null);

}

code The method shown above delegates to the protected catch-all constructor and therefore I create several more intention-revealing Creation Methods for the remaining object types. The public CallMethodRule constructors can now be eliminated one at a time and the following refactored CallMethodRule.cs is shown below: code format="csharp" using System; using System.Text; using System.Reflection;

namespace DotnetPark.Commons.NDigester {   ///     /// Rule implementation that calls a method on the top (parent) /// object, passing arguments collected from subsequent /// CallParamRule</c> rules or from the body of this /// element. /// By using CallMethodRule(String methodName)</c> /// a method call can be made to a method which accepts no arguments. ///    public class CallMethodRule : Rule {       private string methodName = null; private int paramCount = -1; private Type[] paramTypes = null; private string body = null;

/// <param name="methodName">The name of the method to be called. /// <param name="paramCount">The number of parameters used in method invoking. /// <param name="paramTypes">The mixed array of objects any of type System.Type</c> /// or System.String</c> that describes the types of the input parameters and helps to find /// method with an appropriate signature in case of miltiple overloads. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call.

//catch-all constructor protected CallMethodRule(string methodName, int paramCount, params object[] paramTypes) {           this.methodName = methodName; this.paramCount = paramCount;

if(paramTypes != null) {               this.paramTypes = new Type[paramTypes.Length]; for(int i=0; i<paramTypes.Length; i++) {                   object type = paramTypes[i]; if(type is String) {                       this.paramTypes[i] = Type.GetType((string)type); }                   else if(type is Type) {                       this.paramTypes[i] = (Type)type; }                   else {                       throw new Exception("You must specify only objects of type                                                \"System.String\" and \"System.Type\" here!"); }               }            }        }

// intension-revealing Creation Methods static CallMethodRule newMethodRule(string methodName) {           return new CallMethodRule(methodName, -1, null);

}

static CallMethodRule newRulewithParamCount(string methodName, int paramCount) {           return new CallMethodRule(methodName, paramCount, null); }

static CallMethodRule newParameterTypewithParamCount(string methodName) {           return new CallMethodRule(methodName,-1, null); }

static CallMethodRule newTypewithParamCount(string methodName, int paramCount, params object[] paramTypes) {           return new CallMethodRule(methodName, -1, null); }

code

2.4 Extract Creation Class
As more Creation Method gets added into a class, it makes the code harder to manage and organize since lots of Creation Methods obsure the responsibilities of a class. A Creation Class can then be created whose primary responsibility is to create various objects from a related set of objects and it manages all Creation Methods.



I utilized the CallMethodRule.cs which contain lots of code along with Creation Methods and therefore I moved all the Creation Methods into its new class called MethodRuleCreator.cs. The code for CallMethodRule.cs which manages the responsibilities of calling method is shown below:

code format="csharp" using System; using System.Text; using System.Reflection;

namespace DotnetPark.Commons.NDigester {   ///     /// Rule implementation that calls a method on the top (parent) /// object, passing arguments collected from subsequent /// CallParamRule</c> rules or from the body of this /// element. /// By using CallMethodRule(String methodName)</c> /// a method call can be made to a method which accepts no arguments. ///    public class CallMethodRule : Rule {       private string methodName = null; private int paramCount = -1; private Type[] paramTypes = null; private string body = null;

/// <param name="methodName">The name of the method to be called. /// <param name="paramCount">The number of parameters used in method invoking. /// <param name="paramTypes">The mixed array of objects any of type System.Type</c> /// or System.String</c> that describes the types of the input parameters and helps to find /// method with an appropriate signature in case of miltiple overloads. /// If a target object contains several overloaded versions of one method /// the number of parameters helps to define an appropiate overloaded method to call.

//catch-all constructor protected CallMethodRule(string methodName, int paramCount, params object[] paramTypes) {           this.methodName = methodName; this.paramCount = paramCount;

if(paramTypes != null) {               this.paramTypes = new Type[paramTypes.Length]; for(int i=0; i<paramTypes.Length; i++) {                   object type = paramTypes[i]; if(type is String) {                       this.paramTypes[i] = Type.GetType((string)type); }                   else if(type is Type) {                       this.paramTypes[i] = (Type)type; }                   else {                       throw new Exception("You must specify only objects of type                                                \"System.String\" and \"System.Type\" here!"); }               }            }        }

///        /// Process the start of this element. ///        public override void OnBegin {           // Push an array to capture the parameter values if necessary if (paramCount > 0) {               string[] parameters = new string[paramCount]; for (int i = 0; i < parameters.Length; i++) {                   parameters[i] = null; }               digester.PushParameters(parameters); }       }

///        /// Process the body text of this element. ///        public override void OnBody {           if(paramCount == 0) {               body = digester.Body.Trim; }       }

///        /// Process the end of this element. ///        public override void OnEnd {

// Retrieve or construct the parameter values array string[] parameters = null; if(paramCount < 0) {               parameters = new string[0]; }           else if(paramCount == 0) {               parameters = new string[1]; parameters[0] = body; if(body == null) return; }           else if(paramCount > 0) {               parameters = (string[])digester.PopParameters;

// In the case where the parameter for the method // is taken from an attribute, and that attribute // isn't actually defined in the source XML file, // skip the method call if (paramCount == 1 && parameters[0] == null) {                   return; }           }

// .... more methods for dealing with responsibilites of CallMethodRule not shown

// All Creation Methods moved to a new Creation Class

code

I created MethodRuleCreator.cs and moved all the Creation Methods from CallMethodRule.cs to this new class and provided appropriate protection level it needs to instantiate method rule.

code format="csharp" using System; using System.Collections.Generic; using System.Text;

namespace DotnetPark.Commons.NDigester {  public class MethodRuleCreator {      public static CallMethodRule newMethodRule(string methodName) {           return new CallMethodRule(methodName, -1, null); }

public static CallMethodRule newRulewithParamCount(string methodName, int paramCount) {           return new CallMethodRule(methodName, paramCount, null); }

public static CallMethodRule newParameterTypewithParamCount(string methodName) {           return new CallMethodRule(methodName, -1, null); }

public static CallMethodRule newTypewithParamCount(string methodName, int paramCount, params object[] paramTypes) {           return new CallMethodRule(methodName, -1, null); }

} }

code To complete this refactoring technique, I change calls of the form; for example, I change the call in digester.cs as shown below:

code format="csharp" public void AddCallMethod(string pattern, string methodName) {           AddRule(pattern, new CallMethodRule(methodName));

}

code TO

code format="csharp" public void AddCallMethod(string pattern, string methodName) {           AddRule(pattern, MethodRuleCreator.newMethodRule(methodName)); }

code

A Composed Method is a method which focuses on transforming the logic into a small number of intention-revealing steps to remove code duplication and to group related code together. This refactoring technique organizes the program by simplifying the code and optimizing it for later use. I begin with the MainClass.cs which perform various tasks such as match for the order, item, client and address as shown below:

code format="csharp" using System; using System.Diagnostics;

using DotnetPark.Commons.NDigester;

namespace OrdersParser {   ///     /// The main class of the application ///    class MainClass {       ///         /// The main entry point for the application. ///        [STAThread] static void Main(string[] args) {           UseConfiguredDigester;

Console.WriteLine("Setting up Digester..."); // create Digester instance Digester dig = new Digester;

// adding rules for orders parsing

// match for the "OrdersHistory" // it will be our root object dig.AddObjectCreate("ordersHistory", typeof(OrdersHistory));

// match for the "Order" dig.AddObjectCreate("*/order", typeof(Order)); dig.AddSetNext("*/order", "AddOrder"); dig.AddSetProperties("*/order"); dig.AddPropertySetter("*/order/total", "Total");

// match for the "Client" dig.AddObjectCreate("*/client", typeof(Client)); dig.AddSetProperties("*/client"); dig.AddPropertySetter("*/client/notes", "Notes"); dig.AddSetNext("*/client", "SetClient");

// match for the client "Address" dig.AddObjectCreate("*/client/address", typeof(Address)); dig.AddSetProperties("*/client/address"); dig.AddSetNext("*/client/address", "SetAddress");

// match for the order "Item" dig.AddObjectCreate("*/order/items/item", typeof(Item)); dig.AddSetProperties("*/order/items/item"); dig.AddSetNext("*/order/items/item", "AddItem");

// invoke parsing and returning objects tree Console.WriteLine("Parsing file..."); OrdersHistory orders = (OrdersHistory)dig.Parse("Orders.xml");

Console.WriteLine("\nParsed orders:"); Console.WriteLine(orders.ToString); }

code

I simplify the MainClass.cs and make it easier to read by utilizing an Extract Method and turning the fragment for order, item, client and address into it’s own method as shown below: code format="csharp" // match for the "Order" private static void MatchOrder {

dig.AddObjectCreate("*/order", typeof(Order)); dig.AddSetNext("*/order", "AddOrder"); dig.AddSetProperties("*/order"); dig.AddPropertySetter("*/order/total", "Total"); } // match for the order "Item" private static void MatchItem {           dig.AddObjectCreate("*/order/items/item", typeof(Item)); dig.AddSetProperties("*/order/items/item"); dig.AddSetNext("*/order/items/item", "AddItem"); }  // match for the "Client" private static void MatchClient {           dig.AddObjectCreate("*/client", typeof(Client)); dig.AddSetProperties("*/client"); dig.AddPropertySetter("*/client/notes", "Notes"); dig.AddSetNext("*/client", "SetClient"); }   // match for the client "Address" private static void MatchAddress {           dig.AddObjectCreate("*/client/address", typeof(Address)); dig.AddSetProperties("*/client/address"); dig.AddSetNext("*/client/address", "SetAddress"); }

code

The MainClass.cs is now simpler and better organized, but the code inside each method can be simplified even further by creating a method called AddData which handle various type of data as shown below:

code format="csharp" private void AddData(string data) {           if (typeof(Order) == data) {               dig.AddObjectCreate("*/order", typeof(Order)); dig.AddSetNext("*/order", "AddOrder"); dig.AddSetProperties("*/order"); dig.AddPropertySetter("*/order/total", "Total");

}

if (typeof(Item) == data) {               dig.AddObjectCreate("*/order/items/item", typeof(Item)); dig.AddSetProperties("*/order/items/item"); dig.AddSetNext("*/order/items/item", "AddItem"); }

if (typeof(Client) == data) {               dig.AddObjectCreate("*/client", typeof(Client)); dig.AddSetProperties("*/client"); dig.AddPropertySetter("*/client/notes", "Notes"); dig.AddSetNext("*/client", "SetClient"); }           if (typeof(Address) == data) {               dig.AddObjectCreate("*/client/address", typeof(Address)); dig.AddSetProperties("*/client/address"); dig.AddSetNext("*/client/address", "SetAddress"); }

}

code

The AddData method can now be utilized in order, item, client and address methods as shown below:

code format="csharp" // match for the "Order" private static void MatchOrder {           AddData(Order);

}

code

2.6 Using NUnit on CallMethodRule class
NUNIT is an open source unit testing framework for .NET programming which can be used for .NET projects and in testing .dll files using a unit test class. Each testing method consists of the fixture (the thing to be tested such as Item), some operation to be tested such as, checking the item and evaluating the results as expected. The following is the test case for CallMethodRule.cs:
 * 1) The program verifies whether correct method name and parameter count is utilized appropriately by the user.
 * 2) The program tests the method called ToString in CallMethodRule class and verifies the method name and parameter count.

The above test case is implemented using Nunit and it contains the following attributes:
 * 1) The [TextFixture] is used to indicate the test code written in a class.
 * 2) The [Test] is used to indicate a test to be performed.
 * 3) The StringAssert.AreEqualIgnoringCase is utilized to verify method rules.

The following classes TestMethodRule.cs and CallMethodRule.cs are shown below: code format="csharp" using System; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework;

namespace TestCases {   [TestFixture] public class TestMethodRule {       CallMethodRule CheckRule;

private string result; private string methodName; private int paramCount; private object[] paramTypes;

[Test] //Testable method public void VerifyfirstRule {           CheckRule = new CallMethodRule; CheckRule.MethodName = "FirstMethod"; CheckRule.Parameter = 1;

StringBuilder sb = new StringBuilder("CallMethodRule["); sb.Append("methodName="); sb.Append(methodName); sb.Append(", paramCount="); sb.Append(paramCount); sb.Append(", paramTypes={");

sb.Append("}"); sb.Append("]");

result = sb.ToString;

StringAssert.AreEqualIgnoringCase(sb.ToString, result);

}

[Test] //Testable method public void VerifySecondRule {           CheckRule.MethodName = "SecondMethod"; CheckRule.Parameter = 2;

StringBuilder sb = new StringBuilder("CallMethodRule["); sb.Append("methodName="); sb.Append(methodName); sb.Append(", paramCount="); sb.Append(paramCount); sb.Append(", paramTypes={");

result = sb.ToString;

StringAssert.AreEqualIgnoringCase(sb.ToString, result);

}   } } //CallMethodRule.cs using System; using System.Collections.Generic; using System.Linq; using System.Text;

namespace TestCases {   class CallMethodRule {       private string methodName; private int paramCount; private object[] paramTypes;

public CallMethodRule {       }        public int Parameter {           get { return paramCount; } set { paramCount = value; } }

public string MethodName {           get { return methodName;} set { methodName = value; }

}

public object[] ParamTypes {           get { return paramTypes; } set { ParamTypes = value; } }

public override string ToString {           StringBuilder sb = new StringBuilder("CallMethodRule["); sb.Append("methodName="); sb.Append(methodName); sb.Append(", paramCount="); sb.Append(paramCount); sb.Append(", paramTypes={");

sb.Append("}"); sb.Append("]"); return (sb.ToString); }   } }

code