Wednesday, November 11, 2009

How much does it cost to resolve with Unity?

The following sample shows how expensive it is to resolve types using a DI container. On my notebook it showed the following:

00:00:00.0040000
00:00:01.7080000
00:00:00.1640000

As you can easily see resolving a type with Unity is something like at least 40 times slower. Is it worth it? I believe yes because you'll catch up with the performance on good design.

using System;
using System.Linq;
using Microsoft.Practices.Unity;

static class Program
{
  static IUnityContainer container = new UnityContainer();

  static void Main(string[] args)
  {
    //create instance without unity
    var lc1 = DateTime.Now;

    for (int i = 0; i < 100; i++)
    {
      new Log();
    }

    var lc2 = DateTime.Now;

    Console.WriteLine(lc2 - lc1);

    //create instance with unity using delegates
    var la1 = DateTime.Now;

    for (int i = 0; i < 100; i++)
    {
      container.RegisterInstance>(i.ToString(),
        () => container.Resolve());
    }

    for (int i = 0; i < 100; i++)
    {
      Func fLog = container.Resolve>(i.ToString());
      ILog log = fLog();
    }

    var la2 = DateTime.Now;

    Console.WriteLine(la2 - la1);

    //create instance with unity
    var lb1 = DateTime.Now;

    for (int i = 0; i < 100; i++)
    {
      container.RegisterType(i.ToString());
    }

    for (int i = 0; i < 100; i++)
    {
      ILog log = container.Resolve(i.ToString());
    }

    var lb2 = DateTime.Now;

    Console.WriteLine(lb2 - lb1);

    Console.ReadLine();
  }
}

public interface ILog { }
public class Log : ILog { }

Hints: migration from VS2008SP1 -> VS2010Ultimate

1. The 2nd line of the project file has being changed
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">



<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


When you try to open the migrated project with VS2008 you simply get the following warning:

Project file contains ToolsVersion="4.0", which is not supported by this version of MSBuild. Treating the project as if it had ToolsVersion="3.5".

...all the rest work fine!

2. A whole set of new elements has being added to the default PropertyGroup of the project; all these are not breaking when you try to open the migrated project with VS2008.

<FileUpgradeFlags> 
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>http://localhost/Utilities/</PublishUrl>
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>true</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>


3. A new element has being added on the PropertyGroup of each configuration; also nothing breaking... VS2008SP1 ignores them.

<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> 


4. A new ItemGroup have being added; also nothing breaking... VS2008SP1 ignores them.

<ItemGroup> 
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
<Visible>False</Visible>
<ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>


5. If your projects have being set to "Treat warnings as errors" then VS2010 is much more sensitive, especially to xmldocumentation mistakes.

Fail: VS2010 Setup


Monday, November 9, 2009

Functional programming using Unity

C# 3.0 comes with functional programming capabilities that can become very handy if combined with a dependency injection framework as Unity.
Take a look at the following example. The function ‘doThis’ can be register in the unity container just like any other instance of a type. At the time of registration the function ‘doThis’ isn’t called yet. It’s not even called at the time of resolving the function ‘doThis’ from the container. This idea is very useful when doing lazy things with Unity.
//create a unity container
IUnityContainer container = new UnityContainer();   
//define a function
Func<bool> doThis = delegate 
{ 
Debugger.Break(); 
return true; 
}; 
//register the function as instance
//function will not execute during registration 
container.RegisterInstance(doThis);
//resolve the function from the container
//function will not execute during the resolving
var f = container.Resolve<Func<bool>>();
//will execute here:-) 
f();

Tuesday, November 3, 2009

UnityContainer Lifetime Management extension methods

The following code snippet  registers the type MySingletonObject to the IMyObject interface as a singleton. The problem is that in order to get the UnityContainer type you need a references to the Microsoft.Practices.Unity.dll and in order to get the ContainerControlledLifetimeManager type you will need a reference to the Microsoft.Practices.ObjectBuilder2.dll
// Register a default (un-named) type mapping with a singleton lifetime
myContainer.RegisterType(new ContainerControlledLifetimeManager());
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve();

Now if the case is that you need more that ContainerControlledLifetimeManager type from Microsoft.Practices.ObjectBuilder2.dll then it’s worth the reference… if not then the following extension method could help you do the same as before without the need for a reference to Microsoft.Practices.ObjectBuilder2.dll (in a large project you will most likely have some base class library dll with common and shared types; create the extension method there…)

public static void RegisterSingleton(this IUnityContainer container)     
where TTo : TFrom
{    
container.RegisterType(new SingletonLifetimeManager());
}

Using the extension method the code now looks like this:

// Register a default (un-named) type mapping with a singleton lifetime
myContainer.RegisterSingleton();
// Following code will return a singleton instance of MySingletonObject
// Container will take over lifetime management of the object
myContainer.Resolve();

Same idea can be applied for  ExternallyControlledLifetimeManager.

Note that Chris Tavares (from the p&p team) has mentioned in the p&p summit 2009 last month that the next release of Unity will have the Microsoft.Practices.ObjectBuilder2.dll most likely merged into the Unity assembly.

NUnit 2.4.* to NUnit 2.5.* migration / Rhino.Mocks

NUnit 2.5 has changed quite substantially compared with the previous 2.4.8 release, as outlined in the NUnit 2.5 release notes
The problems that I had when migrating tests to NUnit 2.5 were:

  • Assert.IsInstanceOfType has been replaced by Assert.IsInstanceOf
  • NUnit.Framework.SyntaxHelpers namespace no longer exists. All classes that were in this namespace have been moved to the NUnit.Framework namespace
  • Many alias conflicts if using Rhino.Mocks
    using RIs = Rhino.Mocks.Constraints.Is;
    using NIs = NUnit.Framework.Is;
    using RProperty = Rhino.Mocks.Constraints.Property;
    using NProperty = NUnit.Framework.Property;
    using RAssert = NUnit.Framework.Assert;
    using NAssert = NUnit.Framework.Assert;
    using NList = NUnit.Framework.List;
    using RList = Rhino.Mocks.Constraints.List;
  • Has.Length(2); has been replaced by Has.Length.EqualTo(2));
  • Has.Count(1); has been replaced by Has.Count.EqualTo(1);
  • Has.Property("Length", 20) has been replaced by Has.Property("Length")
  • Error 243 Warning as Error: 'NUnit.Framework.Text' is obsolete: 'Use Is class for string constraints'
Good luck migrating

Saturday, October 17, 2009

Developing a Solution Generator (EasySolutions)

Considerations for large projects (Dynamic solutions)

The information is based on practices learned from my 4 year tenure as SW architect of a large (60 developers) team. I will show you how to get the most out of Visual Studio 2008 to help improve the effectiveness of your team-based software development using a tool that I am about to develop EasySolutions

A large project typically differs from a smaller project:
  • You need to partition your project into multiple (100+) Visual Studio projects.
  • You shouldn’t have to wait for several minutes before your IDE is responsive due to the fact that your solution is getting too big.

Building your projects for development

Something that I have learned is that you should never use solutions to build your project. Solutions are evil, really evil. You need them in order to work with Visual Studio, but that’s about it. You should never use them elsewhere and you should never commit solutions with the sources. Instead you should use MSBuild to build your project and you should dynamically generate the required solutions using a tool. Developing such a tool is no big deal. I will drop some bits explaining the idea and hopefully drop a first version of the tool in the next month or two.

What you will get meanwhile is the outcome of some work I did waiting for my flight to Zurich returning from the p&p summit!

Building a Solution Generator

This idea is very appealing since the projects files are in xml and usually also in MSBuild format thus they are very simply to parse.

The basic flow of such a tool is the following:

Search for project files (example *.csproj) recursively.
Load with XDocument each project and search for project references.

var projectReferences = 
from element in xdoc.Descendants(xNameSpace + "ProjectReference")
select Path.GetFullPath(Path.Combine(projectDirName, (string) element.Attribute("Include")));


Create an object graph with all the project references per project and serialize it to xml for convenience. You will use this cache in order to avoid unnecessarily parsing the project files again. The schema of your xml is based on the following fragment…
[XmlRoot(ElementName = "Projects")]
public class Projects : List { }

public class ProjectBase
{
  [XmlAttribute]
  public Guid ProjectGuid { get; set; }
}

public class Project : ProjectBase
{
  public Project() { }

  public List ProjectReferences { get; set; }
}

You can now start querying that Projects instance typically using Linq. Generating a solution file is quite easy; the solution schema is very simple. {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") is the id of csprojects… Similarly you find id’s for all projects types supported.

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj", "{CD06FCD6-9F1A-4736-A034-925C24F628C3}"
EndProject


What you get from such tool:
  1. You are able to open only the necessary projects each time.
  2. You are able to make structural changes to your projects (add, rename, delete projects) without the fear that you will break other solutions.
  3. You don’t need to store the solution files in the source control.

Getting the tool one step further

Another point of pain is synchronizing all project properties across many studio projects (Some examples the output dirs should much, the build configurations should much, flags such generate doc and warnings should much and so on). The first problem is to find out the mistakes and there are tools around that will do this like BuildCop. The second problem is to go and manually alter all mistakes... fun job to do in a large project don't you agree? Well we could reuse the above idea, craft a simple gui to maintain project settings from all projects in one view and then directly save the changes into the visual studio project files. After all it's quite simple to alter XML...

Friday, September 11, 2009

Validation for Windows 7 is coming soon!

I am ALWAYS so glad to install new releases of Microsoft Windows. So I have installed the Windows 7 RTM. Today (11.09.2009) I got a very bad surprise! Windows poped up a warning that my copy is not genuine with a link to validate my copy of Windows 7. So I try to validate at http://www.microsoft.com/genuine/ .... and during the validation process I get the following message:

Validation for Windows 7 is coming soon!
Microsoft constantly strives to update our technologies to help protect our customers from the risks of counterfeit software. Right now, we are working hard to improve the way that validation checks to see whether Windows 7 running on your PC is genuine.
Shortly after Windows 7 is available for purchase beginning October 22, you will be able to validate Windows 7 running on your PC to help you determine that it’s genuine.

The problem is that some win7 features have being meanwhile disabled:-(

Friday, September 4, 2009

Visual Studio 2008 SP1 on Windows 7

I have installed VS2008 on Win7 and it works just great. The only problem that I had was related to the VSTO.

Knowledge base number: KB949258MSI (s) (F0:5C) [18:27:43:876]: Windows Installer installed an update. Product Name: Visual Studio Tools for the Office system 3.0 Runtime. Product Version: 9.0.30729. Product Language: 0. Manufacturer: Microsoft Corporation. Update Name: KB949258. Installation success or error status: 1603.

To overcome follow these steps.

1. Install VS2008
2. Install the
Make sure that before running the Microsoft Visual Studio Tools for the Microsoft Office System (version 3.0 Runtime) Service Pack 1 (x86)
http://www.microsoft.com/downloads/details.aspx?FamilyID=d8eb4921-891a-4b5e-973f-0b96e6ccf376&DisplayLang=en
3. Install the VS2008 SP1

This should work!

Sunday, August 9, 2009

Install Windows 7 on a vhd file

Please have in mind that you can only boot from vhd files on the Ultimate and Enterprise editions of Windows 7. The instructions bellow work on all editions but you will be only able to logon if you are running Ultimate or Enterprise due to licensing issues.

  1. Boot from the Windows 7 dvd and select “repair your computer”.
  2. Select “use recovery tools”
  3. Select “command prompt”

x:\sources> diskpart
diskpart> create vdisk file="c:\images\win7.vhd" maximum=64000
diskpart>select vdisk file="c:\images\win7.vhd"
diskpart>attach vdisk
diskpart>exit
x:\sources>setup

Good luck!