Monday, November 21, 2011

Abstract Factory Design Pattern

This is some sample code from C# 3.0 Design Patterns by Judith Bishop outlining the Abstract Factory Design Pattern:

using System;

namespace AbstractFactoryPattern {
  //  Abstract Factory        D-J Miller and Judith Bishop Sept 2007
  //  Uses generics to simplify the creation of factories
  
  interface IFactory<Brand>
    where Brand : IBrand {
    IBag CreateBag();
    IShoes CreateShoes();
  }

  // Conctete Factories (both in the same one)
  class Factory<Brand> : IFactory<Brand>
    where Brand : IBrand, new() {
    public IBag CreateBag() {
      return new Bag<Brand>();
    }

    public IShoes CreateShoes() {
      return new Shoes<Brand>();
    }
  }

  // Product 1
  interface IBag {
    string Material { get; }
  }

  // Product 2
  interface IShoes {
    int Price { get; }
  }

  // Concrete Product 1
  class Bag<Brand> : IBag
    where Brand : IBrand, new() {
    private Brand myBrand;
    public Bag() {
      myBrand = new Brand();
    }

    public string Material { get { return myBrand.Material; } }
  }

  // Concrete Product 2
  class Shoes<Brand> : IShoes
    where Brand : IBrand, new() {
      
    private Brand myBrand;
      
    public Shoes() {
      myBrand = new Brand();
    }

    public int Price { get { return myBrand.Price; } }
  }

  interface IBrand {
    int Price { get; }
    string Material { get; }
  }

  class Gucci : IBrand {
    public int Price { get { return 1000; } }
    public string Material { get { return "Crocodile skin"; } }
  }

  class Poochy : IBrand {
    public int Price { get { return new Gucci().Price / 3; } }
    public string Material { get { return "Plastic"; } }
  }

  class Groundcover : IBrand {
    public int Price { get { return 2000; } }
    public string Material { get { return "South african leather"; } }
  }

  class Client<Brand>
    where Brand : IBrand, new() {
    public void ClientMain() { //IFactory<Brand> factory)
      IFactory<Brand> factory = new Factory<Brand>();

      IBag bag = factory.CreateBag();
      IShoes shoes = factory.CreateShoes();

      Console.WriteLine("I bought a Bag which is made from " + bag.Material);
      Console.WriteLine("I bought some shoes which cost " + shoes.Price);
    }
  }

  static class Program {
    static void Main() {
      // Call Client twice
      new Client<Poochy>().ClientMain();
      new Client<Gucci>().ClientMain();
      new Client<Groundcover>().ClientMain();
    }
  }
} 
 
Based on the above code, we can readily notice that this does not differ significantly from the 
Factory Method Design Pattern in that it is still heavily reliant on Interfaces.  In this case,
however, the usage of C# Generics has further simplified the process of specifying
concrete class implementations, thus allowing a Class Name to be specified as a 
parameter rather than an actual concrete class instance.
The Abstract Factory Design pattern primarily differs from the Factory Method class in that
the individual classes or "factories" are responsible for handling the business
logic for processing, whereas in the Factory Method Design Pattern, this is wholly contained
within the logic of a single method.  In addition, the Abstract Factory Design Pattern
is leverage to create a group of related products (in this case, bags and shoes) whereas
the Factory Method also concerned itself with the instantiation of only a single
class based on a common Interface.  Therefore, the abstraction in this case is to the 
level of encapsulating the internal details and logic of creating a "factory" 
rather than creating a specific single class instance.

Factory Method Design Pattern

This is some sample code from C# 3.0 Design Patterns by Judith Bishop outlining the Factory Method Design Pattern:

using System;
  using System.Collections;

  class FactoryPattern {
  
  // Factory Method Pattern       Judith Bishop 2006
  //  Example of exporting from different suppliers
    
  interface IProduct {
    string ShipFrom();
  }

  class ProductA : IProduct {
    public String ShipFrom () {
      return " from South Africa";
    }
  }
  
  class ProductB : IProduct {
    public String ShipFrom () {
            return "from Spain";
    }
  }

  class DefaultProduct : IProduct {
    public String ShipFrom () {
            return "not available";
    }
  }

  class Creator {
    public  IProduct FactoryMethod(int month) {
      if (month >= 4 && month <=11)
        return new ProductA();
      else 
      if (month == 1 || month == 2 || month == 12)
        return new ProductB();
      else 
        return new DefaultProduct();
    }
  }
  
    static void Main() {
      Creator c = new Creator();
      IProduct product;
        
      for (int i=1; i<=12; i++) {
        product = c.FactoryMethod(i);
        Console.WriteLine("Avocados "+product.ShipFrom());
      }
    }
  }

So by looking at the code, you can probably get a good feel for what the code is trying to accomplish.

There are 3 products which all need to implement common shipping functionality but need to ship from 3 different locations. Therefore, this is a perfect candidate for implementing an Interface across all of the class implementations. By implementing a common Interface, the classes can easily be swapped for one another (called "polymorphism"). Since all of the classes are interchangeable, there only needs to be a set of criteria which dictates which class is actually instantiated and utilized within the Main method.

In this case, the Factory method is responsible for accepting that parameter (in this case, the month) and then returning the appropriate instance of the class based on the internally developed logic which has been conveniently encapsulated into a single method. The Main method can now simply be oblivious to the actual instance of the class that is required. The class is returned as an instance of an Interface and the only parameter that is required to be known is the month. The Factory Method in this manner also assists in the principles of encapsulation and decoupling.

Thursday, November 17, 2011

Converting from one version of Visual Studio version to another

If you work with a large number of developers that may have different versions of Visual Studio on their local workstations, you may have to constantly deal with version conflicts in projects and solutions.

Fortunately, a tool exists for allowing you to convert from versions of Visual Studio 2010 back to versions of Visual Studio 2008 or Visual Studio 2005 (with the disclaimer that all functionality will not be guaranteed to work by switching between the various versions).  You can download the tool here: http://www.emmet-gray.com/Articles/ProjectConverter.htm

Unfortunately, the tool is written entirely in VB.Net which makes it difficult to work with if your preferred development language is C# (like me).

I used a tool called Instant C# from Tangible Software Solutions (http://tangiblesoftwaresolutions.com/Product_Details/Instant_CSharp.html) to convert the VB.Net source over to C#.





In addition, I heavily refactored the code to make it more flexible for future Visual Studio support and additional future features and capabilities:
http://vsprojectconverter.codeplex.com

Working with 3rd party assemblies in Sandboxed solutions

If you are attempting to utilize 3rd party assemblies in SharePoint Sandboxed Solutions, you may encounter error messages when attempting to deploy your SharePoint project.

The reason this does not work is because Sandboxed Solutions run in partial trust, therefore, any assemblies that you utilize need to support a partial trust model.

If you are fortunate enough to have the source code for the assembly, then you can add the following attribute to the AssemblyInfo.cs file (in the case of C# source code): [assembly:AllowPartiallyTrustedCallers].  You can read more about this attribute here:  http://support.microsoft.com/kb/839300
You can then re-compile the source code and use the resultant assembly within your Sandboxed Solution. 

NOTE: When you add the Reference to your Visual Studio project, make sure that the property for "Copy Local" is set to True.  This will force the assembly to be copied to your bin directory and thereby include it in the WSP (SharePoint Solution Package) for deployment to your Site Collection.

As you can probably guess, if you do not have the source code to the assembly and it is not already marked to support partial trust, you are out of luck and will have to deploy your solution as a Farm Level Solution instead.  This is extremely unfortunate since online hosted solutions of SharePoint such as SharePoint Online/Office 365 only support Sandboxed Solutions--thereby making more complex application development solutions impossible.