# Wednesday, August 01, 2012

About a year ago, I enrolled in the TEALS program; I was about to be dropped in a classroom full of high school students to teach them about programming stuff.

The deal was simple: TEALS had booked the first period of every day (8:00am-8:55am) for the computer science course. The plan was that I would go there teach 2 days a week, help the teacher then zip to Microsoft to work the rest of the day. Obviously things did not go according to the plan… for the better.

It quickly turned out that this teaching gig was way more addicting and exciting than expected. I immediately found myself going 5 days a week. I had the chance to work with a great team: the teacher, Michael Braun, and another Microsoft employee Chris Mitchell. Chris also was supposed to show up 2 days a week but ended up coming every day as well. This was an amazing experience – teaching is just something really special.

One year later, I survived my first year of American high school and better words, watch is the video that summarizes it:

posted on Wednesday, August 01, 2012 6:10:02 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]
# Saturday, September 09, 2006

After 2 years in the CLR, I'm moving job (and building) to Microsoft Research. I will be working on Parametrized Unit Testing.

 

posted on Saturday, September 09, 2006 11:21:39 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [3]
# Monday, July 25, 2005

In this post, I’ll show how to build an MsBuild (msdn2) task will automatically generate XSD schemas for your custom tasks. The post is separated in two sections: if you are interested to see how the task works, continue on reading. If you don’t care and want to get straight down to the beef, scroll down until you see TaskSchema reference.

What is MsBuild? Why do we want to generate schemas?

MsBuild is the new .Net build system. It is based on XML files containing the projects, targets and tasks (see also Ant, NAnt). The framework comes with a set of tasks that allows easy compilation of solutions or projects and doing a couple more actions. Of course, everybody has different needs and you will probably end up writing your own specialized task to solve your problems.

When editing a MsBuild script, it is *very* convenient to take advantage of the “built-in intellisense” of XML by attaching it to the MsBuild schema file. You can do this in VS2005 in two mouse clicks (see below How to setup intellisense for msbuild). Unfortunately, this is not true for your custom tasks where you need to create yourself a XSD schema.

I’ll assume you have a basic knowledge of custom msbuild tasks in the following.

Note that NAnt has had this feature (nantschema) for a while now.

What are we looking for?

Before diving into the coding details, let’s see what our “final products” looks like. Let’s build a simple task to use it as our example during the article: the sleep tasks makes msbuild sleep x seconds (note that this implementation is very very poor):

using System;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Foo
{
public sealed Sleep : Task
{
private int seconds;

[Required]
public int Seconds
{
get { return this.seconds;}
set { this.seconds = value;}
}
public override bool Execute()
{
this.Log.LogMessage(“Sleeping {0} seconds”, this.Seconds);
Thread.Sleep(this.Seconds * 1000);
}
}
}

The sleep task has a single (required) parameter “seconds”. We expect the schema for this task to look as follows:

<xs:schema
    xmlns:msb=http://schemas.microsoft.com/developer/msbuild/2003
    elementFormDefault="qualified" 
    targetNamespace="http://schemas.microsoft.com/developer/msbuild/2003"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <
xs:include schemaLocation=" Microsoft.Build.Commontypes.xsd" />
    <
xs:element name="Sleep" substitutionGroup="msb:Task">
    <
xs:complexType>
        <
xs:complexContent mixed="false">
            <
xs:extension base="msb:TaskType">
                <
xs:attribute name="Seconds" type="msb:non_empty_string" />
            </
xs:extension>
        </
xs:complexContent>
   
</xs:complexType>
</xs:element>
</xs:schema>

There’s a couple things to say about this schema:

  1. we include the MsBuild schema so we get all the type that are already defined for msbuild,
  2. Sleep is in the substitutionGroup msb:Task,
  3. the extension has “msb:TaskType” as base class to inherit the Task properties,
  4. Since Seconds is an int, we restrict the attribute to msb:non_empty_string. We cannot restrict it to xs:integer to handle cases where the users pases a property, e.g. $(Property).
  5. Latter on, we could add information from the xml documentation into the schema as well.

Now that we know kind of output we are looking for, let’s see what “ingredients” we need.

Recipe ingredients

Here’s a little summary of tools and techniques that we will use to generate the schemas:

  • System.Reflection: we’ll use reflection to enumerate types, find custom attributes, etc…
  • System.Xml.Schema: this namespace contains the object model to create schemas (what a surprise!)
  • System.Xml: to integrate document parts (if available) in the output
  • Microsoft.Build.Utilities: this namespace contains the Task base class,

Building TaskSchema

The TaskSchema has the following properties (it actually has more properties but I’ll skip them for simplicity):

[Required]
ITaskItem[] Assemblies {get;set}
[Output]
ITaskItem[] Schemas {get;}

Assemblies is a list of assemblies containing the tasks to “schematize”. Schemas is an output parameter that will contain the path of each schema, as we will generate one schema per assembly.

This is the high level “factored” Execute method (almost pseudo-code):

CreateAndInitializeSchema(); // (add namespace, includes, etc...)

foreach(string assemblyName in Assemblies)
{
// load error handling comes here
Assembly assembly = LoadAssembly(assemblyName);
// iterating exported types
foreach(Type type in assembly.GetExportedTypes())
{
//if (type is not a task) continue;
if(!typeof(ITask).IsAssignableFrom(type)) continue;
// create a new schema element and name it after the type
// create a simpleType + extension
XmlSchemaElement element = CreateElement(type);
foreach(PropertyInfo property in type.GetProperties())
{
// if (property is defined in some base class) continue;
if (property.DeclaringType != type) continue;
// create schema attribute and name it after property name
// create a simpleType that
XmlSchemaAttribute attribute = CreateAttribute(property);
// add attribute to current element
AddAttribute(element, attribute);
}
}
// saving to disk
SaveSchema(schema);

There are a lot of interesting details to go through to implement this pseudo-code.
I won’t go through all of them. I will rather focus on some parts:

Translating enums into XSD

An enumeration can be represented in XSD by simple type restriction. For example,

[C#]

public enum HelloWorld
{
Hello,
World
}

[XSD]

<xs:simpleType name="HelloWorldType" base="msb:non_empty_integer">
    <
xs:restriction base="xs:string">
        <
xs:enumeration value="Hello" />
        <
xs:enumeration value="World" />
    </
xs:restriction>
</
xs:simpleType>

Getting custom attributes, the generic way

This is a well know (and very handy trick) that add a generic type parameter to a method to “strongly type” it.

T GetAttribute<T>(ICustomAttributeProvider t) where T : Attribute
{
object[] attributes = t.GetCustomAttributes(typeof(T), true);
if (attributes != null && attributes.Length > 0)
return (T)attributes[0];
else
return null;
}

 

Finding and adding documentation to the schema

Adding documention to the schema is straightforward, it is a matter of adding a annotation containing a document element:

<xs:attribute name="Assemblies" use="required">
    <
xs:annotation>
        <
xs:documentation>
            Gets or sets the list of path to analyse.
        </xs:documentation>
    </
xs:annotation>
</
xs:attribute>

The real trouble is to find what kind of documentation we are going to put there. We cannot rely solely on Reflection for this task because MsBuild custom attributes does not store any “documentation” data. Therefore, the best source of documentation is the XML documentation that is generated by the C# compiler (don’t forget to turn it on in Projects -> Properties -> Build). By default, the compiler dumps that file along side of the assembly so it is easy to find. Here’s a sample of how that file looks like:

<?xml version="1.0"?>
<
doc>
    <
assembly>
        <
name>TaskFoo</name>
    </
assembly>
    <
members>
        <
member name="T:TaskFoo.TaskSchema">
            <
summary>
                A Task that generates a XSD schema of the tasks in an assembly.
            </summary>
        </
member>
...

That is sweet. We can access the summary of each member very easily using XPath. For example:

//member[@name=”T:taskType.FullName”]/summary

This expression will return me the summary of the taskType type. Similar constructs can be mode for the property summary.

TaskSchema task reference

A Task that generates the XSD schemas for assemblies containing tasks.

Download: See Task on project distributor. Compiled against .Net 2.0 Beta 2.

Features:
  • Generates ready-to-use XSD schemas. No edition needed.
  • Generates task lists, i.e. the UsingTask sequence, to integrate easily your tasks into MsBuild,
  • If documentation is available, automatically adds documentation to the schema,
  • Task attribute are strongly typed,
  • Generates specific types for enumerations
  • It’s a MsBuild task! It will fit in your automation!
Attributes:
  • Assemblies: Required ITaskItem[] expression. The list of assemblies to analyse.
  • OutputPath: Optional string expression. The desired schemas output path.
  • Schemas: Output ITaskItem[] expression. For each assembly, the corresponding schema path.
  • CreateTaskList: Optional Boolean expression. A value that indicates if TaskList (see below) should be generated as well.
  • TaskLists: Output ITaskItem[] expression. For each assembly, the corresponding task list path. This output is null if CreateTaskList is false.

There are a couple more options. Run TaskSchema to have the full schema!

Examples:

This little msbuild project applies TaskSchema to itself (it is part of Churn.Tasks.dll):

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

    <
UsingTask AssemblyFile="Churn.Tasks\bin\Debug\Churn.Tasks.dll" TaskName="Churn.Tasks.TaskSchema" />

    <
ItemGroup>
        <
Assemblies Include="bin\Debug\TaskFoo.dll" />
    </
ItemGroup>

    <
Target Name="CreateSchema">
        <
TaskSchema
            Assemblies="@(Assemblies)" 
            OutputPath="Churn.Tasks\bin\Schemas" 
            />
    </
Target>
</
Project>

[Output]

Microsoft (R) Build Engine Version 2.0.50215.44
[Microsoft .NET Framework, Version 2.0.50215.44]
Copyright (C) Microsoft Corporation 2005. All rights reserved.
Build started 5/26/2005 8:19:51 PM.
__________________________________________________
Project "D:\Projects\Churn.NET\Churn.Tasks\taskschema.self.xml" (default targets):
Target CreateSchema:
Analysing bin\Debug\Churn.Tasks.dll
Found documentation file at Debug\Churn.Tasks.xml
Analyzing Churn.Tasks.TaskSchema
Creating Schema bin\Schemas\Churn.Tasks.Tasks.xsd
Create Task list bin\Schemas\Churn.Tasks.Tasks
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.93

[Schema: TaskFoo.xsd]

Execute the sample and see for yourself!

posted on Monday, July 25, 2005 10:27:33 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [5]
# Wednesday, May 25, 2005

A while ago, I mentioned I was planning to build an autonomous agent framework on .NET (this was in fact a long time ago). It’s time to wake this project up with a shiny description:

NSteer is a framework for simulating of autonomous agents for .NET.

Until we get down to the code, here is a little snapshot to get you hooked:

 

A bit of history: boids, flocks, herds, etc…

In 1986, Craig Reynolds wrote a little application that simulated bird group behaviors. The term Boids was born. The beauty of his approach was that the “bird” behavior was not created from some complicated mathematical equation, it all boiled down to 3 simple rules that each agent would follow:

  1. Separation: avoid neighbors,
  2. Cohesion: go towards the group center,
  3. Alignment: align with group velocity.

Since then there has been a lot action in this field and you can see applications of this approach in a lot of the blockbuster hits. Check out Craig’s web site for an impressive list of links to papers (I love this one), samples, frameworks and movies…. It was about time to bring .NET into the play.

Laying down concepts

Let’s start by identifying the concepts in our problem that we can later translate into interfaces:

  • An Agent describes an independent entity that lives in a World. An Agent has a Vision, a Body and a Behavior
  • A Body defines the cinematic properties of the agent (position, acceleration, etc…)
  • A Vision defines the region where the Agent can “see” obstacles or neighbors
  • The Behavior of the Agent will yield a steering force that will move the Agent. This is the “brain” of the agent.
  • Agents are confined in a World.
  • A Simulator that uses an Integrator to integrate the dynamics of the system.

We will also need ways to access the list of Agents, Obstacles, etc… To do so, I chose to use the Service – Component – Container pattern where different services give access to the agents, obstacles, etc...

In .Net, this pattern is already part of the framework. The IComponent, IContainer interfaces are defined in System.ComponentModel and there already exists base class such as Container, Component, ServiceContainer to get started.

For a start, we will define the following services:

  • AgentService, gives access to the Agents,
  • WorldService, gives access to the world dimension and properties,
  • ObstacleService, gives access to the obstacles in the world,
  • NeighorhoodService, let agent query about neighboring agents

At last, we need some concepts for visualization:

  • A Sprite is a 2D drawing with background color, foreground color, etc… It can be hidden or made visible.
  • A Scene is an abstraction of GDI+,(just in case I had the courage to implement the framework using DirectX or XAML).

There might be a couple more going down the road, but this looks like a good starting point. I’ll see on the next post how we lay down the interface and maybe get ready for testing.

posted on Wednesday, May 25, 2005 8:35:00 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]