Note: this entry has moved.
First, I followed the instructions and used the code from the Vertigo Software guys.
Next, the issue is that to configure a new project for continuous integration, you have to modify manually the web.config of the CI service as follows:
< appSettings >
< add key = " 1 " value = " TeamProjectName=MyProject;BuildType=MyBuildType " />
</ appSettings >
Yuck!
What I wanted was a UI that would automatically populate dropdowns with the available projects in TFS, as well as their configured Build Types, which is the information you need to setup a new continuous integration build using this solution. Here's the UI I built:
To set it up, you just need to unzip these files to the same location of the CI service (by default C:\Program Files\Microsoft Visual Studio 2005 Team Foundation Server\Web Services\CI), and add an entry in the web.config with the Url of your TFS:
< appSettings >
< add key = " ServerUrl " value = " http://tfs:8080 " />
</ appSettings >
The web.config also contains the references that are needed to connect to the TFS using the client APIs:
< compilation debug = " true " >
< assemblies >
< add assembly = " System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089 " />
< add assembly = " Microsoft.TeamFoundation, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
< add assembly = " Microsoft.TeamFoundation.Build.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
< add assembly = " Microsoft.TeamFoundation.Client, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
< add assembly = " Microsoft.TeamFoundation.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
< add assembly = " Microsoft.TeamFoundation.VersionControl.Client, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
< add assembly = " Microsoft.TeamFoundation.VersionControl.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A " />
</ assemblies >
</ compilation >
Connecting to the server is actually pretty easy:
TeamFoundationServer server = TeamFoundationServerFactory.GetServer(ConfigurationManager.AppSettings["ServerUrl"]);
server.Authenticate();
Then, to retrieve the source control projects in TFS, you request the VersionControlServer service from the server instance:
VersionControlServer vcs = (VersionControlServer)server.GetService(typeof(VersionControlServer));
Retrieving the configured build types can be done performing a query to retrieve items from the well-known path they are stored on the server, after getting an instance of the owning project:
VersionControlServer vcs = GetSCC();
TeamProject project = vcs.GetTeamProject(projectList.SelectedValue);
ItemSet items = vcs.GetItems("$/" + project.Name + "/TeamBuildTypes/*");
List < string > buildTypes = new List < string >(items.Items.Length);
foreach (Item item in items.Items)
{
buildTypes.Add(item.ServerItem.Replace(items.QueryPath, "").Substring(1));
}
Note that I'm removing the query path from the ServerItem property, as it contains the full server-side path to it. I must say that even without looking at the documentation, 10' of Google search, and Reflector was all I needed to get it done. A fairly intuitive API in general.
Note: this entry has moved.
Surely you know Linq brings the standard query operators to make queries a first class concept in the C# language. What you may or may not have realized, is that Linq can be used for way more than just querying. Here goes my first exploration outside the query bounds with Linq.
The problem with reflection: bye-bye type safety
There's (at least for me) a sense of comfort and reassurance in using a type-safe language like C# every time I hit Ctrl + Shift + B (or Shift + F6) - that is, when I compile ;). I know that weird and hard to debug runtime errors because of wrong type usage will almost never happen, as well as "missing method" or something like that. That's until I use reflection and get the infamous TargetInvocationException or some NullReferenceException if I'm not careful. Here's what I mean:
MethodInfo method = typeof(Mock).GetMethod("PublicMethodParameters",
new Type[] { typeof(string), typeof(int) }));
What happens if a refactoring is applied to the Mock class to rename the method? What happens if the type of a parameter changes? Yeeessss, runtime exceptions! This is not a trivial problem if you have a flexible and pluggable framework that uses lots of reflection. Not being able to apply refactorings (or making it too expensive) because of the risk of breaking things, essencially limits your ability to improve the design and evolve your code. So, how about this to replace the magic strings and loosely typed Type arrays?:
MethodInfo info = Reflector.Method<Mock, string, int>(
(x, y, z) => x.PublicMethodParameters(y, z));
Strong-typed reflection via Linq
The working principle is that lamda expressions passed as arguments (just as delegates in previous versions of .NET) are not necessarily executed.
The code above basically constructs a lambda expression with a calls to a given method on a type. The type of the target type that declares the method is the first type parameter to the Method<> static generic method. The optional type parameters that you can specify will be the types of the arguments (if any) of the method you will call. If I were to retrieve the MethodInfo for a parameterless method, the expression would be:
MethodInfo info = Reflector.Method<Mock>(x => x.PublicMethodNoParameters());
This is the more typical lambda that you may be used to seeing. In a lambda expression, if you need to pass additional arguments, you must enclose all of them in parethesis (x, y, z in the example above). I got the same typed reflection feature working for properties and fields:
PropertyInfo property = Reflector.Property<Mock>(x => x.PublicProperty);
FieldInfo field = Reflector.Field<Mock>(x => x.PublicField);
Leveraging expression trees
Now to the interesting part. How is it implemented?
In Linq, any method receiving a lambda expression (a delegate type) can be converted into a method receiving an Expression<T> for the same delegate type, without changes to client code. For example:
private static void DoSomething(Predicate<Mock> predicate)
can be replaced with:
private static void DoSomething(Expression<Predicate<Mock>> predicate)
In both cases, calling code can be the same lambda expression:
DoSomething(x => x.Value > 25);
What happens is that the compiler, instead of passing in the pointer to the anonymous delegate in the second method signature, generates IL code that builds an AST (abstract syntax tree) of the code, in the form of an expression tree. You can see this if you open Reflector (I named my typed reflection class after it as a tribute to the greatest tool any advanced developer should use regularly) and dissasemble the method invocation to DoSomething:
ParameterExpression expression1 = Expression.Parameter(typeof(Mock), "x");
Program.DoSomething(Expression.Lambda<Predicate<Mock>>(Expression.GT(Expression.Field(expression1, fieldof(Mock.Value)), Expression.Constant(0x19, typeof(int))), new ParameterExpression[] { expression1 }));
There you can see how the compiler built the entire expression using static methods on the Expression class (more on how I think the API could be improved in a separate entry). And of course, in your method implementation, you can inspect that same tree and do whatever you want with it. The latest Linq CTP includes a very cool visualizer to see what's in the expression tree once it reaches your method body at runtime:

It should be pretty obvious by now how I'm implementing the strong typed reflection: I'm receiving an expression tree, and searching it for the method call node (or member access, for properties and fields). Here's the implementation of the Method<> method:
public static MethodInfo Method<TDeclaringType>(Expression<Operation> method)
{
return GetMethodInfo(method);
}
private static MethodInfo GetMethodInfo(Expression method)
{
LambdaExpression lambda = method as LambdaExpression;
if (lambda == null) throw new ArgumentNullException("method");
MethodCallExpression methodExpr = null;
// Our Operation<T> returns an object, so first statement can be either
// a cast (if method does not return an object) or the direct method call.
if (lambda.Body.NodeType == ExpressionType.Cast)
{
// The cast is an unary expression, where the operand is the
// actual method call expression.
methodExpr = ((UnaryExpression)lambda.Body).Operand as MethodCallExpression;
}
else if (lambda.Body.NodeType == ExpressionType.MethodCall ||
lambda.Body.NodeType == ExpressionType.MethodCallVirtual)
{
methodExpr = lambda.Body as MethodCallExpression;
}
if (methodExpr == null) throw new ArgumentException("method");
return methodExpr.Method;
}
The Operation delegate type is one that I created. I couldn't use the Linq Func<T> (and T, Arg0..) because they return a boolean. I needed something more flexible, basically something returning an object, and delegate "overloads" receiving a number of fixed argument types (same as Func<T>). So I got:
public delegate object Operation();
public delegate object Operation<T>(T declaringType);
public delegate object Operation<T, A0>(T declaringType, A0 arg0);
...
Note that the user of our API never knows about these delegate types, just as the user of the query operators never knows about Func<T>. I expect these delegates to dissapear in the future, in favor of something more elegant (maybe public delegate object Operation <params T> ;)). Also, notice how I'm adding the new argument type parameters *after* the T, which is the usual convention for overloading, and which is contrary to what Linq does in their Func<T>s.
Properties and fields are very similar to the example above, and not too interesting. The Method overloads, however, are the really nice part:
public static MethodInfo Method<TDeclaringType>(Expression<Operation<TDeclaringType>> method)
{
return GetMethodInfo(method);
}
public static MethodInfo Method<TDeclaringType, A0>(Expression<Operation<TDeclaringType, A0>> method)
{
return GetMethodInfo(method);
}
public static MethodInfo Method<TDeclaringType, A0, A1>(Expression<Operation<TDeclaringType, A0, A1>> method)
{
return GetMethodInfo(method);
}
...
Ok, what's the big deal, right? Well, by being able to specify the types of the arguments and then declaring them in the lambda, you basically get strong typing and compile-type safety back even if you are using reflection in the end :). Back to the initial example:
MethodInfo info = Reflector.Method<Mock, string, int>(
(x, y, z) => x.PublicMethodParameters(y, z));
See how the y and z parameters are strong typed and are used to resolve at compile time which is the method "invoked" in the lambda expression. When the IDE is fully updated to work with C# 3.0, a rename refactor of the given method would yield the expected result: it will be renamed in all places like this where you are using it even for reflection! And if you change an argument type, the code will simply fail to compile!
Freakin' amazing :D
Get the prototype and play at will.
Note: this entry has moved.
As part of the
Mobile Client
Software Factory I've been working on for the past few months,
we introduced the Orientation Aware Control (OAC). I blogged about it and
showed it working. In this post I'll delve a little more on the process you go when
building UIs for devices that must adapt to different resolutions and orientations.
I've already
hinted that the solution we implemented is based on the
Localization feature in .NET. So let's see how you go about using it.
First step is to add a new UserControl to your project, and changing the base class
to inherit from the OrientationAwareControl class provided with the factory. After
you do that, you will see something like the following:
New and modified properties:
- Localizable: as you can see from the property description from the above screenshot,
this property is fixed to the True value. This is the proof that OAC uses the localization
feature, and therefore this property cannot be changed.
- Orientation: this property can have the values Vertical | Horizontal, and corresponds
to the Rotate command (both in context menu as command area in the properties window).
It basically allows you to design different UI for the portrait and landscape orientations.
- Resolution: this property allows you to select one of the available resolutions.
These resolutions can be the standard ones (VGA and QVGA standard or square), and
will show up in a dropdown. More on how this list is populated and how to add custom
resolutions later.
New commands: the commands, as is usual on custom control designers, are available
either from the context menu of the control and in the command area in the properties
window.
- Rotate: rotates the current layout, so that you can start designing the rotated
layout. By default, the first time the control is rotated, controls bounds will
be checked to see if they fit in the rotated control (height and width are switched).
If they don't, they will be moved up and left until all controls fall within bounds
of the container user control.
- Switch to Default Layout: by design, in VS2005 you can only add new components/controls
through the designer if the current control/form is in the default culture. Because
the OAC extends the localization infrastructure, the equivalent of the default culture
is the default layout, meaning default culture + default resolution and vertical
orientation. More on how to set which is the default resolution later on.
- The other three commands help in designing localized versions of the different resolutions.
Basically, whenever you start with a new locale (say Spanish), the default layout
is applied to the new resolution/orientation/culture, which is probably not optimum
depending on which locale you are designing. For example, say you have QVGA-Spanish
already designed, and now you want to design VGA-Spanish. The default culture layout
will be applied and auto-scaled to give you a starting point. Well, in the localization
case, you probably want to have all the labels and other text properties applied
too, so that you don't have to translate everything again. Copy Text Properties
is there for that purpose. You just switch back to the QVG-Spanish layout, click
Copy Text Properties, and back in the VGA-Spanish, you click Paste Properties. All
text properties will be set in all controls, saving you quite a bit of time. The
same goes for the layout properties. If you already designed the layout for one,
say, VGA-Horizontal resolution, and now you're localizing it, in every locale instead
of re-locating all controls, you can simply Paste Properties after you run the Copy
Layout Properties from the "source" layout (i.e. VGA-Horizontal, Default culture).
Layout properties are basically location and size.
As you see, there's NO code whatesoever that you need to write to detect the current
screen size and apply the appropriate resource. All is done automatically by the
base Orientation Aware Control. In addition, and because we're reusing the localization
feature in .NET, layouts are "inherited" across locales. Also, when no specific
layout is found for the current resolution (i.e. a new device just came out), the
default layout will automatically be applied.
How do resolutions work
I said above that the available resolutions are rendered as a dropdown you can pick
from in the properties window. Here's how it looks:

Notice the description at the bottom of the window. This description is dynamic,
and reflects the form factors that support the given resolution. So where is this
information pulled from?
This is a pretty advanced control, which was very fun to develop. Turns out that
there's an IPlatformInformation service exposed to device control designers, that
allows you to list and retrieve form factors defined in Tools | Options | Device
Tools | Form Factors options page in Visual Studio. This is how the page looks after
you install the Windows Mobile 5.0 SDK:
At first, my control simply reused the FormFactor you already have in custom user
controls:

That turned out to be a bad idea, as multiple form factors can have the same physical
screen resolution, such as Phone VGA and VGA (both are 480x640). Hence, the OAC
designer is hiding this property and providing an alternative one, the Resolution
property. Basically it's populating the unique set of resolutions, and building
the description dynamically to show which form factors defined in the VS options
support the current value.
The OAC is fully integrated with the VS options dialog shown above. You can easily
use the Save As button above to create a new form factor based on an existing one.
After renaming it, you can click the Properties button and change its resolution.
Once you're done, the control will automatically pick the new resolution (you may
need to close and reopen the designer):

Note that in the VS options dialog you can also specify which is the default form
factor, so that if your default target device is going to be, say, VGA, you don't
need to change the resolution in every new control you create.
Stay tunned as I continue to explore the journey of building such a cool control,
if I'm allowed to say so ;-). I have little doubt that this is the way to go for
the .NET CF v3. We'll see...