Archive

Archive for the ‘CodeProject’ Category

Strategy Pattern at work

March 8th, 2010 Nizar 2 comments

We recently ran into a challenging design issue at work. We are working on a web application that must support internationalization since we have customers in many different countries. The profile for each customer has different settings and configurations based upon the customer’s country.

These settings/configurations overlap and differ across countries. The goal, of course, is to design/implement the code in a way that enables us to reuse code that is common across countries. Below is the scenario that we are dealing with,

  • USCustomer.FeatureA() is the same as CACustomer.FeatureA()
  • USCustomer.FeatureB() is the same as KRCustomer.FeatureB()
  • CACustomer.FeatureC() is the same as KRCustomer.FeatureC()
  • KRCustomer.FeatureA() differs from USCustomer.FeatureA()
  • CACustomer.FeatureB() differs from USCustomer.FeatureB()
  • USCustomer.FeatureC() differs from CACustomer.FeatureC()

The first attempt was of course to try and solve this via sub-classing. Let’s look at the different options that we have for sub-classing:

  1. Make CA & KR sub-classes of US. This allows us to re-use USCustomer.FeatureA() for CA and USCustomer.FeatureB() for KR. But it doesn’t allow us to re-use CACustomer.FeatureC() for KR.
  2. Okay, no problem, you say. We’ll just make KR a sub-class of CA. So, CA is a sub-class of US and KR is a sub-class of CA. But then we run into the issue that USCustomer.FeatureB() can no longer to be re-used for KRCustomer.FeatureB().

Now imagine this kind of situation spread across 15 different countries. Ouch! So sub-classing clearly is not the answer.

It sounds like we need some sort of “strategy” that’ll let us swap/differ settings and configurations across countries without all this coupling. Well the strategy is to apply the Strategy design pattern. Below is the overall strategy:

  1. Encapsulate the features: Each feature gets its own class. So we end up with the following classes:

    Customer
    CACustomer
    KRCustomer
    FeatureA : IFeatureA
    FeatureB : IFeatureB
    FeatureC : IFeatureC
    FeatureA1 : IFeatureA
    FeatureB1 : IFeatureB
    FeatureC1 : IFeatureC
    
  2. Setup the constructor of the Customer class to take in the concrete class that is specific to the feature that they require as a parameter. For instance,

    public class Customer
    {
       public Customer() : 
         this(new FeatureA(), new FeatureB(), new FeatureC())
       {  }
     
       public Customer(IFeatureA a, IFeatureB b, IFeatureC c)
       {
          featureA = a;
          featureB = b;
          featureC = c;
       }
     
       public void DoInitialSetup()
       {
          SetupFeatureA(featureA);
          SetupFeatureB(featureB);
          SetupFeatureC(featureC);
       }
     
       private IFeatureA featureA;
       private IFeatureB featureB;
       private IFeatureC featureC;
    }
     
    public class CACustomer : Customer
    {
       public CACustomer() : 
         base(new FeatureA(), new FeatureB1(), new FeatureC1())
       {  }
    }
     
    public class KRCustomer : Customer
    {
       public KRCustomer() : 
         base(new FeatureA1(), new FeatureB(), new FeatureC1())
      {  }
    }

And voila! We can now swap implementations across countries and add different implementations for different countries as needed.

The above example was simplified to effectively demonstrate the Strategy pattern without confusing the reader. In particular, in the above example, the customer classes directly instantiate the features that they need. This is generally a bad idea in practice for at least two reasons:

  1. It makes it difficult to unit test the Customer class.
  2. Each type of customer is still coupled to the specific feature-set that it is using. In other words, the features cannot be changed dynamically.

Instead of directly instantiating the classes, we should be using an IOC container to handle the object instantiations and configurations.

For instance, for our application, we are using an XML file to tie concrete implementations with their respective countries. Below is an example:

DefaultLocalization.xml

<interface name="IFeatureA">
  <class name="FeatureA">
</interface>
 
<interface name="IFeatureB">
  <class name="FeatureB">
</interface>
 
<interface name="IFeatureC">
  <class name="FeatureC">
</interface>

CALocalization.xml

<interface name="IFeatureB">
  <class name="FeatureB1">
</interface>
 
<interface name="IFeatureC">
  <class name="FeatureC1">
</interface>

KRLocalization.xml

<interface name="IFeatureA">
  <class name="FeatureA1">
</interface>
 
<interface name="IFeatureC">
  <class name="FeatureC1">
</interface>

Based on the current country, the right classes get instantiated. If we ever need change KR to use FeatureC instead of FeatureC1, all we do is make the change in the XML file and we’re done.

So, in conclusion, the key to the strategy pattern is encapsulation: Remove the logic that differs from the logic that stays the same via encapsulation.

Kick It on DotNetKicks.com Shout it

Refactoring Code to enable Unit Testing

February 1st, 2010 Nizar 6 comments

Imagine the following (which you’ve very likely run into in the past):

You join a new company and inherit a humongous existing code base. You are told to add some new functionalities without of course breaking existing functionality. “No problem”, you say! “I’ve done this before.”

You’ve got clear requirements and complete access to the existing code base. After some investigation, you figure out that you need to add a few methods to an existing class. One of these methods is:

CustomerService.CanPurchaseProduct(int productId)

The existing CustomerService class looks somewhat like the following:

public class CustomerService
{
   public CustomerService(int customerId)
   {
      custManager = new CustomerManager();
      cust = custManager.GetCustomer(customerId);
   }
 
   ...other methods...
 
   private CustomerManager custManager;
   private Customer cust;
}

You will also be utilizing an existing class named ProductService. Below is a bare-bones outline of this class:

public class ProductService
{
   public ProductService(int productId)
   {
      prodManager = new ProductManager();
      prod = prodManager.GetProduct(productId)
   }
 
   ... other methods below .....
 
   private ProductManager prodManager;
   private Product prod;
}

Your requirements state the following:

– Product must be in stock
– Customer must be a member IF product is for members only

Being the good developer that you are, you start, of course, by writing the unit tests. They look something like the following:

[TestCase]
public void CanPurchaseProduct_InStockAndForAll()
{
      int customerId = 123;
      int prodId = 1;
 
      //TODO: Mock this scenario
      CustomerService svc = new CustomerService(customerId); 
     Assert.IsTrue(svc.CanPurchaseProduct(1));
}
 
[TestCase]
public void CanPurchaseProduct_NotInStock()
{
      int customerId = 123;
      int prodId = 1;
 
      //TODO: Mock this scenario
      CustomerService svc = new CustomerService(customerId); 
     Assert.IsFalse(svc.CanPurchaseProduct(1));
}
 
[TestCase]
public CanPurchaseProduct_NotAMember()
{
      int customerId = 123;
      int prodId = 1;
 
       //TODO: Mock this scenario
      CustomerService svc = new CustomerService(customerId); 
     Assert.IsFalse(svc.CanPurchaseProduct(1));
}

Your initial implementation of the CanPurchaseProduct() method looks like the following:

public class CustomerService 
{
    public bool CanPurchaseProduct(int productId)
    {
       ProductService prodService = new ProductService(productId);
       if(!prodService.IsInStock())
         return false;
 
       if(prodService.IsMembersOnly() && !custService.IsMember())
         return false;
 
      return true;
    }
}

If you’re familiar with unit tests, you’ll recognize an issue right away: The way the implementation currently stands, it is impossible to mock out the different scenarios that we have coded for in our test cases. The reason for this is tight coupling and lack of abstraction. The CustomerManager, ProductService and ProductManager classes are being directly instantiated by the classes that use them – an example of tight coupling. Furthermore, the classes do not implement an interface thus making it impossible to substitute mock versions for them – a direct result of lack of abstraction. So how do we fix this with minimal changes to the existing classes? Below is one strategy:

1. Account for dependencies

The first step is figure out the dependencies. A dependency is any class, resource file, configuration file, etc. that your code is using either directly or indirectly. In our case, we have the following dependencies:

- CustomerManager
- ProductService
- ProductManager (used by ProductService).

2. Make the dependencies “plug-and-play”

Now that we know what the dependencies are and the places where they exist, our next step is to remove all the “knots” so that we can make them plug and play. By “knots”, I refer to statements like the following:

   - custManager = new CustomerManager()
   - productService = new ProductService()  
   - prodManager = new ProductManager()

Instead of the classes directly instantiating dependencies, the idea is to provide it to them. This technique is know as Dependency Injection. There are multiple ways of doing this. Keeping in mind that we need make a minimum number of changes to the existing code base, we’ll go with the simplest one:

Modify the constructors/methods to take in the dependencies as parameters.

This is illustrated below:

public class CustomerService
{
   //Instead of directly instantiating, we pass in the dependency.
   //All new classes can now start using this one to allow for unit      
   //testing.
   public CustomerService(int customerId,  
     CustomerManager custManager)
   {
      cust = custManager.GetCustomer(customerId);
   }
 
   //Original constructor becomes empty.  
   //We still need to keep it around since it is probably used other
   //existing classes
   public CustomerService(int customerId) : 
       this(customerId, new CustomerManager())
   { }
 
   ...
 
   //Note that the method is now taking ProductService as a parameter
   //instead of directly instantiating it.
   public bool CanPurchaseProduct(int prodId, 
        ProductService prodService)
   {...}
}
 
public class ProductService
{
   //Instead of directly instantiating, we pass in the dependency.
   //All new classes can now start using this one to allow for unit      
   //testing.
   public ProductService(int productId, ProductManager prodManager)
   {
 
   }
 
   public ProductService(int productId) : 
     this(productId, new ProductManager()) {}
}

Note: When it comes time to re-factor/re-design/re-architect (whatever you want to you call) your entire application, you should go with a better alternative to handle dependency injection instead of the approach shown here. I would recommend using a tool such as Spring .NET.

3. Abstract them away!

The final step then is create an interface for each of the concrete classes and replace all references to the concrete classes with their associated interfaces.

public interface ICustomerService
{
  bool CanPurchaseProduct(int customerId, IProductService  
    prodService);
}
 
public interface ICustomerManager {...}
 
public interface IProductService {...}
 
public interface IProductManager {...}
 
public class CustomerService : ICustomerService 
{
  public CustomerService(int customerId, ICustomerManager)
  {...}
 
  public bool CanPurchaseProduct(int prodId, IProductService 
    prodService) 
  {...}
}
 
public class CustomerManager : ICustomerManager {...}
 
public class ProductService : IProductService 
{
  public ProductService(int prodId, IProductManager) 
  {...}
}
 
public class ProductManager : IProductManager {...}

Now, we can finally substitute our mocks for the dependencies in our unit tests as shown below. Note that in the test cases below I am using the Moq Unit Testing Framework to setup the mocks but you could use any other framework that you’d like or none at all (if you wish to create the mocks manually).

[TestCase]
public void CanPurchaseProduct_InStockAndForAll()
{
   int customerId = 123;
   int prodId = 1;
 
   //create mocks
   Mock<ICustomerManager> custManager = 
     mockFactory.Create<ICustomerManager>();
 
   Mock<IProductService> prodService = 
      mockFactory.Create<IProductService>();
 
   Customer cust = new Customer(123);
   cust.IsMember = false;
 
   //setup mocks
   custManager.Setup(cm => cm.GetCustomer(123)).Returns(cust);
 
   prodService.Setup(ps => ps.IsInStock()).Returns(true);
   prodService.Setup(ps => ps.IsMembersOnly()).Returns(false);
 
   //run test
   CustomerService svc = new CustomerService(customerId, custManager.Object); 
   Assert.IsTrue(svc.CanPurchaseProduct(1, prodService.Object));
}
 
[TestCase]
public void CanPurchaseProduct_NotInStock()
{
   int customerId = 123;
   int prodId = 1;
 
   //create mocks
   Mock<ICustomerManager> custManager = 
      mockFactory.Create<ICustomerManager>();
 
   Mock<IProductService> prodService = 
      mockFactory.Create<IProductService>();
 
   Customer cust = new Customer(123);
   cust.IsMember = false;
 
   //setup mocks
   custManager.Setup(cm => cm.GetCustomer(123)).Returns(cust);
   prodService.Setup(ps => ps.IsInStock()).Returns(false);
 
   //run test
   CustomerService svc = new CustomerService(customerId, custManager.Object); 
   Assert.IsFalse(svc.CanPurchaseProduct(1, prodService.Object));
}
 
[TestCase]
public CanPurchaseProduct_NotAMember()
{
   int customerId = 123;
   int prodId = 1;
 
   //create mocks
   Mock<ICustomerManager> custManager = 
      mockFactory.Create<ICustomerManager>();
 
   Mock<IProductService> prodService = 
      mockFactory.Create<IProductService>();
 
   Customer cust = new Customer(123);
   cust.IsMember = false;
 
   //setup mocks
   custManager.Setup(cm => cm.GetCustomer(123)).Returns(cust);
 
   prodService.Setup(ps => ps.IsInStock()).Returns(true);
   prodService.Setup(ps => ps.IsMembersOnly()).Returns(true);
 
   //run test
   CustomerService svc = new CustomerService(customerId, custManager.Object); 
   Assert.IsFalse(svc.CanPurchaseProduct(1, prodService.Object));
}

And there you have it. We were able to take an existing code base that had no support for unit-testing and re-factor it so that the additional methods that we added could be unit-tested. Furthermore, we did this without requiring us to make any sweeping architectural changes to the existing code base.

One could argue if the additional work is really worthwhile. If you’re already a test-driven developer then I don’t need convince you that it is definitely worthwhile. But if you’re not then I’ll highlight a few long-term benefits that result from the additional work:

- The code base is now more extensible. It can work with other implementations for ICustomerManager and IProductService.
- At any given time one can run the test cases and know if anything has been broken.
- Unit-testing forces us to think about the dependencies and code in a manner that leads to clean and easy-to-understand code.
- The test cases serve as an up-to-date documentation on what the code does and how it is being used.

I hope that the above points will encourage you to investigate the pros/cons of test driven development more fully.

Kick It on DotNetKicks.com Shout it

WCF over HTTPS

August 26th, 2009 Nizar No comments

I have been working on a WCF web service that I finally deployed to our staging server which runs over HTTPS. Everything seemed fine. I was able to hit it and generate the WSDL. However, when I tried running the svcutil.exe on it, I got the following error:

Error: Cannot add the transport element 'httpTransport'. Another transport eleme
nt already exists in the binding 'System.ServiceModel.Configuration.HttpTranspor
tElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=
b77a5c561934e089'. There can only be one transport element for each binding.

Upon investigation, I realized that when deploying a WCF web service over HTTPS, you must set the ‘Security’ mode to ‘Transport.’. Below are the steps to do this:

1. Add the following inside the section:

<bindings>
  <wsHttpBinding>
     <binding name="webBinding">
       <security mode="Transport"></security>
     </binding>
  </wsHttpBinding>
</bindings>

2. Add the following attribute to the element:

bindingConfiguration="webBinding"

That should be all.

Below is a sample section:

<system.serviceModel>
  <services>
    <service name="MyWebService"
        behaviorConfiguration="ServiceBehavior">
	<!-- Service Endpoints -->
	<endpoint address="" binding="wsHttpBinding"
           bindingConfiguration="webBinding" contract="IMyWebService">
	</endpoint>
       <endpoint address="mex" binding="mexHttpBinding" 
         contract="IMetadataExchange" />
   </service>
</services>
<bindings>
  <wsHttpBinding>
     <binding name="webBinding">
       <security mode="Transport" />
     </binding>
  </wsHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>
Kick It on DotNetKicks.com Shout it

What the heck was I working on??

August 24th, 2009 Nizar 2 comments

Does it ever happen to you that you go to work in the morning, look at the screen and then ask yourself : What the heck was I working on?? Happens to me all the time. Maybe I was in the middle of debugging some code the previous day, or writing a unit-test or finishing up the implementation of a class or going through existing code to understand what it’s doing or something else. Given the detailed nature of software development, it’s sometimes hard to remember where you left off and from where you need to pick things up again.

Below is an approach that’s worked quite well for me:

Tells me where I left off

Tells me where I left off





I write myself a little MS Outlook note and put right in the middle of the screen. Simple, but very effective!

Kick It on DotNetKicks.com Shout it

Am I officially a “nerd”??

August 11th, 2009 Nizar 2 comments

okay i know this is lame.. but i am seriously getting a high from writing unit test cases.. seriously it’s such a rush to see 243 test cases all run AND pass in a matter of seconds… if i don’t stop i am afraid i’ll turn into a “testaholic”

Tags:
Kick It on DotNetKicks.com Shout it

Cast<> to the rescue!

March 3rd, 2009 Nizar 2 comments

Just learn’t something today that I’d like to share.

Say you’ve got a generic list of

IQueryable<Person> persons;

that you’d like to convert to

IQueryable<IPerson> iPersons;

where Person : IPerson.

How do you do this? Very simple:

IQueryable<IPerson> iPersons = persons.Cast<IPerson>();

Note that:

IQueryable<IPerson> iPersons = (IQueryable<IPerson>)persons;

won’t work.

Kick It on DotNetKicks.com Shout it

Fix to Mock.SetupAllProperties() – Not working in Moq 3.0

March 3rd, 2009 Nizar 1 comment

If you download the latest version of Moq, you’ll notice that the Mock.SetupAllProperties() method does not work. Try it in Debug mode and you’ll notice that the method just gets skipped.

Upon inspection, I discovered that a conditional attribute that was being applied to the method which was causing it to be skipped. I am assuming that attribute was meant to be removed but got overlooked.

Anyways, to fix it, here is what you do:

1. Download the source code for Moq and open up the file Mock.Generic.cs
2. Find the method SetupAllProperties() and remove the conditional attribute:
[Conditional("DESKTOP")]
3. Re-build and overwrite for existing Moq.dll that your project is referencing with the new one.

Cheers!

Kick It on DotNetKicks.com Shout it

Integrating TypeMock with ASP .NET Unit tests

February 16th, 2009 Nizar 6 comments

When it comes to writing unit tests for your ASP .NET pages, there isn’t much help out there. I experimented with a few open source testing tools and found some major limitations.

Both NUnitAsp and WaitN, for instance, are “client-side” tools. In other words, you have to write your tests against the actual HTML output. For example, to get the value of a textbox, you have to specify the actual HTML id of the textbox. That’s painful! Especially, since ASP .NET ends up assigning long and complicated ID’s to your controls. Plus NUnitAsp is no longer being maintained or supported.

Unlike NUnitAsp and WaitN, VS Studio ASP .NET Unit testing let’s you examine the actual HttpRequest object. What this means is that you can call methods on your Page and get access to the controls within the page. VS Studio ASP .NET is a pretty decent tool and maybe the answer for you. IF you don’t need to use TypeMock that is. But if you do, then tough luck because VS Studio ASP .NET unit tests don’t work with TypeMock. If you give it try, you’ll get the following exception:

Test method AzAsh.WebApp.Tests.DefaultTest.LoginNotRequiredTest threw exception:  TypeMock.TypeMockException:
*** Typemock Isolator is not currently enabled.
To enable do one of the following:

* To run Typemock Isolator as part of an automated process you can:
   - run tests via TMockRunner.exe command line tool
   - use 'TypeMockStart' tasks for MSBuild or NAnt

* To work with Typemock Isolator inside Visual Studio.NET:
        set Tools->Enable Typemock Isolator from within Visual Studio

For more information consult the documentation (see 'Running' topic).

Check the enable property as they have suggested and you’ll notice that Typemock is enabled! So, what gives? I have no idea. But I do know that Ivonna – a ASP .NET testing tool that is being developed in partnership with TypeMock WILL let you work in conjunction with TypeMock. Like VS Studio, it allows you to examine the intrinsic objects, such as the Page object. In addition, it’s got another neat feature that let’s you inject setup code and assertions into your page’s lifecycle event handlers – very handy especially during type mocking. The only drawback is that it’s a little slow. The unit tests take a while to run.

So if you’ve been scratching your head trying to figure how to develop ASP .NET tests that can work with TypeMock, Ivonna is probably the tool you’ve been waiting for!

Kick It on DotNetKicks.com Shout it

LINQ : Implementing IN and NOT IN

February 12th, 2009 Nizar 8 comments

I got tried of typing

  var result = from s in source
                  where items.Contains(s)
                  select s;

and so I implemented the IN and NOT IN methods as extension methods:

public static IQueryable<T> In<T>(this IQueryable<T> source, 
                            IQueryable<T> checkAgainst)
{
   return from s in source 
            where checkAgainst.Contains(s) 
            select s;
}
 
public static IQueryable<T> NotIn<T>(this IQueryable<T> source, 
                                  IQueryable<T> checkAgainst)
{
   return from s in source 
            where !checkAgainst.Contains(s) 
            select s;
}

Thus, I can now just do the following:

  var result = source.In(items);

What do you think – Good idea, Bad idea, Useless idea?

Kick It on DotNetKicks.com Shout it

Update Panels dont play well with Validators in Chrome

February 12th, 2009 Nizar No comments

If your page uses ASP .NET custom validators and an UpdatePanel, you will notice that your UpdatePanels will not work in Chrome. In order to fix this, you will have disable client script on the custom validators by setting EnableClientScript=false.

Hopefully this tip will save others the headache that I went through!

Happy Coding!

Kick It on DotNetKicks.com Shout it