Tag Archives: Visual Studio

Configure Visual Studio 2010 environment in PowerShell

Instead of using the “Visual Studo Command Prompt (2010)” i wanted to use PowerShell instead. I found this post which does it for VS2008. Extending it for VS2010 was pretty easy:

function SetVS2008()
{
    $vs90comntools = (Get-ChildItem env:VS90COMNTOOLS).Value
    $batchFile = [System.IO.Path]::Combine($vs90comntools, "vsvars32.bat")
    Get-Batchfile $BatchFile
    [System.Console]::Title = "Visual Studio 2008 Windows PowerShell"
}

function SetVS2010()
{
    $vs100comntools = (Get-ChildItem env:VS100COMNTOOLS).Value
    $batchFile = [System.IO.Path]::Combine($vs100comntools, "vsvars32.bat")
    Get-Batchfile $BatchFile
    [System.Console]::Title = "Visual Studio 2010 Windows PowerShell"
}

function Get-Batchfile($file) 
{
    $cmd = "`"$file`" & set"
    cmd /c $cmd | Foreach-Object {
        $p, $v = $_.split('=')
        Set-Item -path env:$p -value $v
    }
}

Build your solution with Visual Studio from MSBuild

Unfortunately MSBuild and BIDS Helper are not able to build an .asdatabase from our Analysis Services project (.dwproj). Here is a task which invokes Visual Studio to build such a solution:

<Target Name="DevEnvBuild">
 <Error Condition="'$(SolutionFile)'==''" Text="Missing SolutionFile" />
 <PropertyGroup>
  <DevEnvTool Condition="'$(DevEnvTool)'==''">C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe</DevEnvTool>
  <DevEnvSwitch Condition="'$(DevEnvSwitch)'==''">Build</DevEnvSwitch>
  <DevEnvBuildCommand>"$(DevEnvTool)" "$(SolutionFile)" /$(DevEnvSwitch)</DevEnvBuildCommand>
 </PropertyGroup>
 <Exec Command="$(DevEnvBuildCommand)" />
</Target>

What i dislike about the Web.config Transformation in VS2010

There are a couple of things that i strongly dislike about the Web.config transformation in VS2010:

  • Only works with XML files (eg: Can’t be used to generate a release notes.txt file)
  • Does not seem to support externalized sections, eg: log4net.config in a separate file
  • No support to copy/paste transform files
  • Only works when Visual Studio 2010 is installed (And i am still not convinced a build server should have this).
  • Ties environment to build configuration

Lesson learned: Don’t trust your co-workers, always double-check!

  • Having multiple transformations is easy-peasy, just invoke the TransformXml task for all your config files and make sure your transformation files are correct. For log4net this would look like:
  • <log4net xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
     <root>
      <level value="ERROR" xdt:Transform="Replace"/>
     </root>
    </log4net>
    
  • The support for copy/paste can be achieved by removing the DependentUpon tag in your proj file (At the cost that you don’t have the + sign in solution explorer which ‘hides’ the transforms files)

Add "Run as administrator" to .sln files

Another trick i learned from the “How-To Geek” is how to add a “Run as administrator” option in the windows shell for .sln files which makes life considerably easier ;)

MSTEST tip: Add 'Full Class Name' column to results view

I firmly believe that adding the ‘Full Class Name’ column to MSTEST’s result view makes it a lot easier to clarify the requirements:

screenshot of mstest result view with full class name column added

About the design of a fluent interface

Now that i have presented a simple ControlStateMachine i can raise the bar a little. A statemachine that handles commands. Here is how a developer should be able to initialize this machine:

sut.WhenIn(States.Loading)
 .On(Commands.Next)
  .Do(() => Console.WriteLine("got next command while loading..."))
  .Do(() => Console.WriteLine("doing it again..."))
 .On(Commands.Previous)
  .Do(() => Console.WriteLine("got previous command while loading..."));

sut.WhenIn(States.Ready)
 .On(Commands.Previous)
  .Do(() => Console.WriteLine("got previous command while ready..."));

So how should we define our methods to accomplish this initialization style? Let’s begin with identifying the methods we need.

  • WhenIn(TSTate state)
  • On(TCommand command)
  • Do(Action action)

Next thing to do is analyze in which sequence these methods can be called:

From -> To WhenIn On Do
WhenIn X
On X
Do X X

Ok, now that we have clarified the requirements a little we can start working on a solution. Let’s start with defining an interface for each of the methods:

interface IChooseState<tstate, TCommand> { Q1 WhenIn(TState state); }
interface IChooseCommand<tstate, TCommand> { Q2 On(TCommand command); }
interface IChooseAction<tstate, TCommand> { Q3 Do(Action action); }

From WhenIn we need to be able to call On. Thus Q1 = IChooseCommand<TState, TCommand>. Q2 is also easily solved because from On we only have to be able to call Do, thus Q2 = IChooseAction<TState, TCommand>.

From Do we should be able to call both On and Do. We can do that by defining another interface which has both methods:

interface IChooseCommandAndAction<tstate, TCommand> : IChooseCommand<tstate, TCommand>, IChooseAction<tstate, TCommand> { }

Now that we have found answers for Q1, Q2 and Q3 we can define the API for initializing our StateMachine as following:

IChooseCommand<tstate, TCommand> WhenIn(TState state);
IChooseAction<tstate, TCommand> On(TCommand command);
IChooseCommandAndAction<tstate, TCommand> Do(Action action);

Now tell me about your strategy for implementing a fluent interface!

VS2010: Unable to insert a breakpoint by clicking next to the line number

For some reason i was unable to insert a breakpoint by clicking next to the line number in VS2010. Anyway, here is the trick that made the problem disappear for me: Go to “Tools > Import and export settings… ” and choose “Reset all settings”.

Another reason for not using mstest

As you can read in CA1001: Types that own disposable fields should be disposable. Pretty solid advice, but for some reason the mstest runner does not dispose of classes that implement IDisposable. A possible workaround is to apply a TestCleanupAttribute to the Dispose method, but this is really contradictory with the “Shared test fixture” approach mstest uses. Imho, there is only one clean solution: use a decent testing framework instead.

Presenting MyTestRunner

Here are a couple of reasons why i dislike the Unit Testing Framework that comes with Visual Studio Team System:

  • Not all versions of Visual Studio are capable of running the tests.
  • Test inheritance is not supported.
  • Running tests via mstest.exe is slow.
  • Visual Studio creating tens of .vmsdi files.

There are already a couple of better frameworks out there, and currently MbUnit is my favorite one, certainly in combination with TestDriven.NET.

I have created a custom implementation of the Microsoft.VisualStudio.QualityTools.UnitTestingFramework assembly. Actually, the assembly only has a couple of Attributes for the moment but contributions are always welcome ;)

In order to achieve better performance i decided to implement a custom test runner. Currently Gallio uses mstest.exe but there might be a day that i decide to write a plugin so that mytestrunner can be used instead.

I was inspired by Creating Self-testing Assemblies and decided to use that approach but for some odd reason visual studio insists on running unit tests although the assembly is a console application :( Anyway, i can still invoke mytestrunner via the external tools as following:

screenshot of external tools dialog

The source code is available at http://code.google.com/p/mytestrunner/.

Revisited the int and string ValueObject templates

After reading The Compare Contract last week i realized that my templates for int and string ValueObjects did not comply with the contract so i decided to add a unittest that reproduces the faulty behavior (and then corrected the implementation):

/// <summary>
/// When comparing instance with null, instance should be greater.
/// </summary>
[TestMethod]
public void ShouldReturnPositiveWhenComparedWithNull()
{
 $classname$ value = new $classname$("0");
 Assert.IsTrue(value.CompareTo(null) > 0);
}

Anyway, feel free to download the corrected IntValueObject and StringValueObject templates.