Tuesday, November 9, 2010

Abstract Factory pattern in simple terms

Just tried out abstract factory pattern... One of my colleague had issues coming up with the pattern.. Just helped him with the sample below;

Invocation point:
var obj = FactoryManager.GetFactory(1);

Implementation:

namespace ConsoleApplication2
{
    internal class RootDO
    {

    }

    internal sealed class SubDO1 : RootDO
    {

    }

    internal sealed class SubDO2 : RootDO
    {

    }

    internal abstract class RootClass<T> where T: RootDO ,new ()
    {

    }

    internal sealed class SubClass1<T> : RootClass<T> where T: RootDO,new ()
    {

    }

    internal sealed class SubClass2<T> : RootClass<T> where T: RootDO, new ()
    {

    }
    internal interface IFactory<S, T>
    {
         S GetObject();
    }

    internal class SubClass1Factory : IFactory<SubClass1<SubDO1>,SubDO1>
    {
        public SubClass1<SubDO1> GetObject()
        {
            return new SubClass1<SubDO1>();
        }

        internal static SubClass1<SubDO1> GetFactory()
        {
            SubClass1Factory s = new SubClass1Factory();
            return s.GetObject();
        }
    }

    public class FactoryManager
    {
        public static object GetFactory(int type)
        {
            return SubClass1Factory.GetFactory();
        }
    }
}
 



Monday, November 8, 2010

TFS2010 Team build automation - workaround


The builds in TFS2010 will work smoothly for .NET 4.0 and even .NET 3.5, .NET 2.0 solutions. But there is a catch here. The build of solutions in .NET 3.5 and below will fail with the issue saying “GenerateResource task failed unexpectedly..… FileTracker.dll missing….” when they have resource files.
This is the known issue in TFS2010. Microsoft tried to introduce a new concept of Incremental builds in TFS2010. This has caused this known issue.

The solution is to add "TrackFileAccess = false" in the GenerateResource task. This is the work around suggested by Microsoft. 
But, what to do if need to enable the build of Setup & Deployment projects? MSBuild do not support the build of .vdproj files which are nothing but setup & deployment projects. So to enable this, we need to call devenv.exe process to do this. But “TrackFileAccess” property is not supported in .NET 3.5 Microsoft.Common.tasks.dll and we will get build error :(

To solve both these issues, the following is the approach which can be helpful.

1) Go to the .NET 3.5 framework folder in the build server box
 
2) Locate the Microsoft.Common.targets file. Copy-Paste this file and rename to Microsoft.Common.targets.CSharp

3) Open the file “Microsoft.Common.targets.CSharp” and locate the “GenerateResource” task in the file. Add the attribute “TrackFileAccess = false” in there as shown below


4) Locate the files “Microsoft.CSharp.targets” and “Microsoft.VisualBasic.targets” files and update the “Import” tag as shown below

“Microsoft.CSharp.targets” file is for C#.NET builds and “Microsoft.VisualBasic.targets” file is for VB.NET builds
5)  Adding the MS Build arguments
a.    Go to TFS Builds
b.    Select the build
c.    Edit build definition and then go to “Process” section
d.    Expand “Advanced” build process parameters
e.    Locate “MS Build Arguments”
f.    Add this statement “/p:CSharp=.CSharp”





Bingo!!! That’s it. Now we are ready to build any .NET 3.5 solutions without any issues

 what actually we are trying to do here is, whenever we initiate team build, we are passing the value for MSBuild argument "$(CSharp)", so the imported file will be Microsoft.Common.targets.CSharp which contain TrackFileAccess = false property in GenerateResource task. When we build the solution using devenv.com or devenv.exe commands, we don's pass the value for that MSBuild argument which in turn import the file Microsoft.Common.targets which do not contain TrackFileAcess property in GenerateResource task.