Thursday, May 27, 2010

Customized Drop Folder in Team Build 2010

In my experience, build output that's ready to be deployed is rarely flat. Meaning that there are many components and layers in a system and having the binaries all be in one directory is pretty useless. In my situation, I had a custom MSBuild script that took the outputs from many different solutions and projects and organized them into a final output folder. I did this so that local builds outside of Team Build would benefit from the same folder structure. The problem is that Team Build 2010 was not playing nice when it came to my custom build script doing all of the output folder structuring. Organizing the output in prior versions of Team Build could be done by overriding the [TargetName] target in your TFSBuild.proj file. In Team Build 2010 however, things are different. 2010 uses Windows Workflow 4.0 for build orchestrating and MSBuild for the actual build, therefore there's not a target to override.

The solution is to clear the OutDir property so that projects built will use their default output location. You can then pass in the "would be" output location as another property and use that in your build script.

Find the MSBuild activity in the workflow and select it.

Clear the value in the OutDir property and update the CommandLineArguments property.

When setting the CommandLineArguments, you can pass in the value that used to be passed into the OutDir property.

String.Format("/p:SkipInvalidConfigurations=true;MyOutputDir=""{0}"" {1}", outputDirectory, MSBuildArguments)

The fact that the OutDir property is now empty keeps the default output directories for your projects in tact. You can then use your custom MyOutputDir to manually structure your output. The final drop site is created from a full copy of the output directory, so as long as your output directory looks right, the drop site will as well!

Monday, May 24, 2010

MSBuild Batching & Item Metadata

When it comes to build scripts, I'm in the NAnt camp. However, I recently found a scenario where it made more sense to use MSBuild and found the basics easy to understand because the ideas are the same as NAnt. One of the more interesting things in MSBuild is batching. Batching allows you to execute a task over a set of items in a foreach loop style.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Sample">
  
  <Target Name="Sample">
    <ItemGroup>
      <MyItem Include="#1">
        <Name>Item 1</Name>
        <Description>Description for Item 1</Description>
      </MyItem>
      <MyItem Include="#2">
        <Name>Item 2</Name>
        <Description>Description for Item 2</Description>
      </MyItem>
      <MyItem Include="#3">
        <Name>Item 3</Name>
        <Description>Description for Item 3</Description>
      </MyItem>
      <MyItem Include="#4">
        <Name>Item 4</Name>
        <Description>Description for Item 4</Description>
      </MyItem>
    </ItemGroup>

    <Message Text="-- Using '@' --"/>
    <Message Text="@(MyItem)" />
    <Message Text=" "/>
    <Message Text="-- Using '%' --"/>
    <Message Text="%(MyItem.Identity): %(MyItem.Name) - %(MyItem.Description)" />
  </Target>
  
</Project>
Running the above gives you:
-- Using '@'--
  #1;#2;#3;#4

  -- Using '%' --
  #1: Item 1 - Description for Item 1
  #2: Item 2 - Description for Item 2
  #3: Item 3 - Description for Item 3
  #4: Item 4 - Description for Item 4

The difference in the two is how the item group is prefixed. The '%' character tells MSBuild to expand the batch and iterate over each item in the batch; the '@' symbol tells MSBuild to join the items into one list. Also notice how I've used metadata (i.e. Name, Description) to have properties associated with each item that can be used in each iteration. The built in property 'Identity' returns whatever is in the 'Include' attribute of the item. One thing you should know is that the 'Include' attribute must be unique and is required if you are going to execute a batch.

Usefulness
In my scenario, I had a set of files that I needed copied from one location to another using xcopy.
<Target Name="RealWorldScenario">
    <ItemGroup>
      <Component Include="ProjectA" />
      <Component Include="ProjectB" />
      <Component Include="ProjectC" />
    </ItemGroup>

    <Exec Command="xcopy /Y $(BaseDir)\bin\%(Component.Identity)\*.dll $(Output)" />
    <Exec Command="xcopy /Y $(BaseDir)\bin\%(Component.Identity)\*.xml $(Output)" />
    <Exec Command="xcopy /Y $(BaseDir)\bin\%(Component.Identity)\*.config $(Output)" />
    
  </Target>

In my situation, I didn't want to duplicate the 3 copy commands for each component. I wanted to make it so that as new components are developed, you only have to add it to the item group.

Tuesday, May 11, 2010

Supporting Multiple Logins in a Windows Application

One of the issues that can come up when you're developing a line of business application is the ability to support a user logging out, then logging back in as a different user. This really only becomes an issue when you're trying to access resources that require an IPrincipal to be set. The first thing someone does in this situation is make a call to AppDomain.CurrentDomain.SetThreadPrincipal  with the principal of the user who just logged in. However, the second time you call this method (i.e. the user logged out and logged back in), you'll get a PolicyException: Default principal object cannot be set twice.

Don't even try it
You can always set the current thread's principal by calling Thread.CurrentPrincipal. So why can't you just set this on the UI thread each time the user logs in? This trick will not work because the .NET framework captures the execution context (i.e. credentials and other stuff) every time something is dispatched to the UI thread. It then restores that execution context when the message is being handled, and throws away the context when it's done. In other words you can set the principal, but it will be thrown away before the next UI event. .NET does this because it could be a potential security flaw. What if someone handled a UI event in your application and decided to post some work to be done that you didn't want them to have permission to do? Trapping the execution context keeps the security of the code that posts the work, the same as the code that executes the work.

My Solution
There are many solutions to this problem, and coming up with them is not hard. I just thought I'd share one that you might find elegant. The idea is to store the IPrincipal of the logged in user in your own class, and set the current thread's principal before making any calls that require that authentication. This sounds like a pain, but it doesn't have to be. You can setup an IDisposable object that when created, sets the current thread's IPrincipal and then restores the previous value when the object is disposed of.
public class ClientSecurityContext
{
    public static IPrincipal CurrentPrincipal
    {
        get;
        set;
    }

    public static IDisposable CreateSecurityContext()
    {
        //
        // Save a copy of the previous IPrincipal so we 
        // can restore it when the caller is finished.
        //
        IPrincipal previous = Thread.CurrentPrincipal;

        //
        // Set the current thread's principal.
        //
        Thread.CurrentPrincipal = CurrentPrincipal;

        //
        // Return a notifier that will call the action 
        // when the caller disposes of it. This will be 
        // used to restore the previous IPrinicpal back 
        // on the current thread.
        //
        return new DisposeNotifier(
            () => Thread.CurrentPrincipal = previous);
    }
}

The above code makes use of a handy DisposeNotifier object that calls a delegate when it's disposed of. It's really just my laziness in creating a special class just for this purpose. You can see how a call using this would look in action.
private string[] GetEmployeesUsingService()
{
    using (ClientSecurityContext.CreateSecurityContext())
    {
        //
        // This is where you would make a call that 
        // requires a particular IPrincipal.
        //
        return new string[]
        {
            Thread.CurrentPrincipal.Identity.Name,
            "Ben Bernanke",
            "Tim Geithner"
        };
    }
}

Download the sample project here if you're needing to support something like this.

Thursday, May 6, 2010

Javascript and 'this' keyword

One of the most confusing things about javascript is function scope the this keyword. I mostly use it for setting fields and accessing member functions from within my javascript class. Depending on how you call the methods, this be something you wouldn't expect.

For those of you who don't know what the this keyword is, it always points back to the object that owns the function your in. Most problems come up when you think your getting the owning object, but instead your getting the current window object. Huh? Taking the example in this article, notice the different behaviors depending on how the methods are being called.
function  foo()
{
    var privateVal = "Private Val";
    this.publicVal = "Public Val";

    var privateAlert = function(str)
    {
        alert(str + this.publicVal);
        alert(str + privateVal);
    }

    this.Run = function()
    {
        privateAlert("Private Call: ");

        this.publicAlert = privateAlert;
        this.publicAlert("Public Call: ");
    }
}

var bar = new foo();
bar.Run();
And here is the output from that:
Private Call: undefined
Private Call: Private Val
Public Call: Public Val
Public Call: Private Val
The interesting behavior is that we're calling the same function, but in two different ways. When calling the function from the this keyword, the interpreter is correctly setting this inside the scope of the function. When calling without the this keyword, it uses the global (window) scope. The reasoning behind this can be found in the javascript spec, or you could take a look at the above referenced article. In short, if you call a function without a preceding object (i.e. this.aFunction(), or MyClass.aFunction()), then this gets defaulted back to window.

So what are you suppose to do? The article mention above proposes a solution to create a private class field call me that is initialized to point to this. The object that this points to at the time me is initialized will what you would expect. That way you can always use me instead of this throughout your class implementation. That's definitely a simple solution, but my VB nightmares scare me away from anything that uses me. One of the ways in which I get around this issue is by making use of the bind method from Prototype.
Function.prototype.bind = function(obj) 
{ 
    var method = this, 
    temp = function() 
        { 
            return method.apply(obj, arguments); 
        }; 
  
    return temp; 
 } 

This function wraps a new function around the calling function while binding that calling function to the obj parameter. Huh? This explains it pretty well. Let me show you how we can use it keep the value of this consistent with what we would expect.
function  foo()
{
    var privateVal = "Private Val";
    this.publicVal = "Public Val";

    var privateAlert = (function(str)
    {
        alert(str + this.publicVal);
        alert(str + privateVal);
    }).bind(this);

    this.Run = function()
    {
        privateAlert("Private Call: ");

        this.publicAlert = privateAlert;
        this.publicAlert("Public Call: ");
    }
}

var bar = new foo();
bar.Run();
Notice that I've added the bind call to the private function so that any references to this inside that private function will be reference the expected object. If you run the above code, this is the output you would now get.
Private Call: Public Val
Private Call: Private Val
Public Call: Public Val
Public Call: Private Val
That's more inline with what we would expect!