<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>blog.davidbarrett.net</title>
        <link>http://blog.davidbarrett.net/Default.aspx</link>
        <description>///&amp;lt;summary&amp;gt;Just a lot of random technical stuff, really.&amp;lt;/summary&amp;gt;</description>
        <language>en-US</language>
        <copyright>David Barrett</copyright>
        <managingEditor>blog@davidbarrett.net</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>blog.davidbarrett.net</title>
            <url>http://blog.davidbarrett.net/images/RSS2Image.gif</url>
            <link>http://blog.davidbarrett.net/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Using Entity Framework to Query Dynamic Types</title>
            <link>http://blog.davidbarrett.net/archive/2012/02/06/using-entity-framework-to-query-dynamic-types.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2012/02/06/using-entity-framework-to-query-dynamic-types.aspx'&gt;http://blog.davidbarrett.net/archive/2012/02/06/using-entity-framework-to-query-dynamic-types.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I ran across a unique scenario recently, and I’m not sure if I should be proud of the solution, or appalled at the Frankenstein result.  Either way, I thought I’d post about it to possibly help others in the same situation.&lt;/p&gt;  &lt;p&gt;I was developing a website leveraging jQuery / AJAX to query views of data at runtime.  The kicker?  I didn’t know which views.  The choice of database view was determined via configuration and user choice.&lt;/p&gt;  &lt;p&gt;I was leveraging &lt;a href="http://www.trirand.com/blog/"&gt;jqGrid&lt;/a&gt; for the client-side grid presentation, sorting, filtering, etc.  I was also proving out an approach using the &lt;a href="http://www.trirand.net/download.aspx"&gt;MVC library for jqGrid&lt;/a&gt; to bind and query for results (this isn't necessary for this discussion, but was the original reason to create this solution, as we’ll soon see).&lt;/p&gt;  &lt;p&gt;The jqGrid MVC library uses IQueryable data sources to bind to the grid.  IQueryable in and of itself isn’t that hard to produce, but what about when you don’t know what the type will look like (read =&amp;gt; the view you’re binding to is unknown at runtime)?  It sure would be nice to leverage an existing technology like Entity Framework, but EF assumes you know the tables / views in advance.  It’s not a bad assumption; but I definitely have an edge case here.&lt;/p&gt;  &lt;p&gt;So, the summary is: how do you return an IQueryable&amp;lt;T&amp;gt; when T is unknown at compile-time?&lt;/p&gt;  &lt;p&gt;There are some constraints here, all of which makes this solution more palatable/scary:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I don’t need to worry about database updates.  Views are hard to update, anyway, usually requiring INSTEAD OF triggers. &lt;/li&gt;    &lt;li&gt;I could eliminate EF and just run a straight database query, mapping the datareader into a List&amp;lt;T&amp;gt;, where T is dynamically typed at runtime.  I could then return List&amp;lt;T&amp;gt;.AsQueryable(), but I lose something significant:  deferred execution.  I’m returning the entire resultset and then using Linq in memory to sort and filter the result.  What if I have a million rows?  Awful. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So, I set about to force EF into helping me solve the problem.  Nothing like forcing a square peg into a round hole.&lt;/p&gt;  &lt;p&gt;First off, how do I create an EF context that will return dynamic results?  This part is fairly simple.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green;"&gt;Context class for dynamic queries and catalog information
&lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;QueryCatalogContext &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;DbContext
&lt;/span&gt;{

    &lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green;"&gt;Initializes a new instance of the &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;see cref="QueryCatalogContext" /&amp;gt; &lt;/span&gt;&lt;span style="color: green;"&gt;class.
    &lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="model"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The model.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;QueryCatalogContext(&lt;span style="color: rgb(43, 145, 175);"&gt;DbCompiledModel &lt;/span&gt;model)
        : &lt;span style="color: blue;"&gt;base&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"DomainDB"&lt;/span&gt;, model)
    {
        modelProvided = &lt;span style="color: blue;"&gt;true&lt;/span&gt;;
    }&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;&lt;style type="text/css"&gt;&lt;![CDATA[







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;EF allows us to provide a model at runtime, so assuming I can define a model based on my run-time view, I’m OK there.  Now how do I return an IQueryable&amp;lt;T&amp;gt; from this context?

&lt;pre class="code"&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green;"&gt;Gets a set of generalized query results.
&lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="query"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The query.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name="columns"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The columns.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; GetDynamicQueryResults&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;QueryMetadata &lt;/span&gt;query)
{

    &lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ColumnMetadata&lt;/span&gt;&amp;gt; columns = &lt;span style="color: blue;"&gt;this&lt;/span&gt;.GetColumnMetadata(query);

    &lt;span style="color: blue;"&gt;string &lt;/span&gt;className = &lt;span style="color: rgb(43, 145, 175);"&gt;QueryTypeFactory&lt;/span&gt;.GetType(query, columns).Name;

    &lt;span style="color: green;"&gt;// Build the query and execute
    &lt;/span&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;sql = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"SELECT VALUE {0} FROM CodeFirstContainer.{0} AS {0}"&lt;/span&gt;, className);
    &lt;span style="color: blue;"&gt;return new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ObjectQuery&lt;/span&gt;&amp;lt;T&amp;gt;(sql, ((&lt;span style="color: rgb(43, 145, 175);"&gt;IObjectContextAdapter&lt;/span&gt;)&lt;span style="color: blue;"&gt;this&lt;/span&gt;).ObjectContext, &lt;span style="color: rgb(43, 145, 175);"&gt;MergeOption&lt;/span&gt;.NoTracking);

}&lt;/pre&gt;

&lt;p&gt;GetColumnMetadata is an internal function that returns a list of column (class property) metadata based on the particular query metadata (it does this by querying the database for view column metadata). QueryTypeFactory uses the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx"&gt;Dynamic Linq Library&lt;/a&gt; to stamp out (and cache) types based on a set of properties (the columns I just retrieved).  I then turn that type info into an EF SQL statement and return an ObjectQuery&amp;lt;T&amp;gt; with no tracking.&lt;/p&gt;

&lt;p&gt;OK, that’s fine and dandy, but how do I provide the model and, more importantly, how do I call the generic method if I don’t know what T is in advance?&lt;/p&gt;

&lt;p&gt;The service class that actually executes the query using the context passes in the model and calls the generic method.  That mechanism follows:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green;"&gt;Gets the dynamic query results.
&lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="query"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The query.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name="columns"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The columns.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; GetDynamicQueryResults&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;QueryMetadata &lt;/span&gt;query, &lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ColumnMetadata&lt;/span&gt;&amp;gt; columns) &lt;span style="color: blue;"&gt;where &lt;/span&gt;T : &lt;span style="color: blue;"&gt;class
&lt;/span&gt;{

    &lt;span style="color: green;"&gt;// Define a dynamic type and create a configuration for it
    &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DbModelBuilder &lt;/span&gt;builder = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DbModelBuilder&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;DbModelBuilderVersion&lt;/span&gt;.V4_1);
    &lt;span style="color: rgb(43, 145, 175);"&gt;EntityTypeConfiguration&lt;/span&gt;&amp;lt;T&amp;gt; configuration = (&lt;span style="color: rgb(43, 145, 175);"&gt;EntityTypeConfiguration&lt;/span&gt;&amp;lt;T&amp;gt;)&lt;span style="color: rgb(43, 145, 175);"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;DynamicViewConfiguration&lt;/span&gt;&amp;lt;&amp;gt;).MakeGenericType(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(T)), query, columns);

    &lt;span style="color: green;"&gt;// Add configuration for dynamic type
    &lt;/span&gt;builder.Configurations.Add(configuration);

    &lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;SqlConnection &lt;/span&gt;connection = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;SqlConnection&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[&lt;span style="color: rgb(163, 21, 21);"&gt;"MyDB"&lt;/span&gt;].ConnectionString)) &lt;span style="color: green;"&gt;// Only need the connection for building the model;&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;    {
        &lt;span style="color: green;"&gt;// Can't use implicit IDisposable because the context is needed when the IQueryable is evaluated.
        &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;QueryCatalogContext &lt;/span&gt;context = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;QueryCatalogContext&lt;/span&gt;(builder.Build(connection).Compile());
        &lt;span style="color: blue;"&gt;return &lt;/span&gt;context.GetDynamicQueryResults&amp;lt;T&amp;gt;(query);
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;First, the service class creates a DbModelBuilder.  The magic happens in the next line.  Because I don’t know the type T at runtime, I need to use reflection to create an instance of the DynamicViewConfiguration&amp;lt;T&amp;gt; class.  I then pass this to the model builder (this class is an EntityTypeConfiguration&amp;lt;T&amp;gt;).  I use a new connection string for building the model (EF has to query the view for metadata) and then compile the model, passing it into the context constructor.  I then return the GetDynamicQueryResults&amp;lt;T&amp;gt; method, returning a true IQueryable&amp;lt;T&amp;gt; object.&lt;/p&gt;

&lt;p&gt;The DynamicViewConfiguration&amp;lt;T&amp;gt; class is used to define the model for EF.  At a minimum, models must define what table they map to and what constitutes the primary key.  This is what the DynamicViewConfiguration&amp;lt;T&amp;gt; class does.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green;"&gt;A dynamic entity configuration for views specified at run-time.
&lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DynamicViewConfiguration&lt;/span&gt;&amp;lt;TDynamic&amp;gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;EntityTypeConfiguration&lt;/span&gt;&amp;lt;TDynamic&amp;gt; &lt;span style="color: blue;"&gt;where &lt;/span&gt;TDynamic : &lt;span style="color: blue;"&gt;class
&lt;/span&gt;{

    &lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green;"&gt;Initializes a new instance of the &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;see cref="DynamicViewConfiguration" /&amp;gt; &lt;/span&gt;&lt;span style="color: green;"&gt;class.
    &lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="query"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The query.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="columns"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;The columns.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;DynamicViewConfiguration(&lt;span style="color: rgb(43, 145, 175);"&gt;QueryMetadata &lt;/span&gt;query, &lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ColumnMetadata&lt;/span&gt;&amp;gt; columns)
        : &lt;span style="color: blue;"&gt;base&lt;/span&gt;()
    {

        &lt;span style="color: green;"&gt;// Locate key column (TODO: Handle multiple key fields)
        &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ColumnMetadata &lt;/span&gt;key = columns.FirstOrDefault(c =&amp;gt; c.IsKey) ?? columns[0];
        &lt;span style="color: rgb(43, 145, 175);"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;DynamicViewLambdaGenerator&lt;/span&gt;&amp;lt;,&amp;gt;).MakeGenericType(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(TDynamic), key.DataType.ClrType), &lt;span style="color: blue;"&gt;this&lt;/span&gt;, key.Name);

        ToTable(query.Name);

    }

}&lt;/pre&gt;

&lt;p&gt;DynamicViewLambdaGenerator&amp;lt;T&amp;gt; is an internal class that defines the lambda for the PK (the key field).&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green;"&gt;Internal class to generate lambda expressions for the configuration
&lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: blue;"&gt;internal class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DynamicViewLambdaGenerator&lt;/span&gt;&amp;lt;TDynamic, TKey&amp;gt; &lt;span style="color: blue;"&gt;where &lt;/span&gt;TDynamic : &lt;span style="color: blue;"&gt;class
&lt;/span&gt;{

    &lt;span style="color: green;"&gt;// TODO: Change to a stateful approach and cache reflection and expressions if usage of this class increases
    &lt;/span&gt;&lt;span style="color: blue;"&gt;private readonly &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type &lt;/span&gt;type;
    &lt;span style="color: blue;"&gt;private readonly string &lt;/span&gt;keyPropertyName;

    &lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green;"&gt;Initializes a new instance of the &lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;see cref="PropertyLambdaGenerator" /&amp;gt; &lt;/span&gt;&lt;span style="color: green;"&gt;class.
    &lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="propertyName"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;Name of the property.&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;DynamicViewLambdaGenerator(&lt;span style="color: rgb(43, 145, 175);"&gt;DynamicViewConfiguration&lt;/span&gt;&amp;lt;TDynamic&amp;gt; configuration, &lt;span style="color: blue;"&gt;string &lt;/span&gt;keyPropertyName)
    {
        &lt;span style="color: blue;"&gt;this&lt;/span&gt;.keyPropertyName = keyPropertyName;
        &lt;span style="color: blue;"&gt;this&lt;/span&gt;.type = &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(TDynamic);

        configuration.HasKey(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.Generate());
    }

    &lt;span style="color: gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green;"&gt;Generates this instance.
    &lt;/span&gt;&lt;span style="color: gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Func&lt;/span&gt;&amp;lt;TDynamic, TKey&amp;gt;&amp;gt; Generate()
    {
        &lt;span style="color: rgb(43, 145, 175);"&gt;PropertyInfo &lt;/span&gt;property = type.GetProperty(keyPropertyName);
        &lt;span style="color: rgb(43, 145, 175);"&gt;ParameterExpression &lt;/span&gt;thing = &lt;span style="color: rgb(43, 145, 175);"&gt;Expression&lt;/span&gt;.Parameter(type);
        &lt;span style="color: rgb(43, 145, 175);"&gt;MemberExpression &lt;/span&gt;keyExpression = &lt;span style="color: rgb(43, 145, 175);"&gt;Expression&lt;/span&gt;.Property(thing, property);

        &lt;span style="color: blue;"&gt;return &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Func&lt;/span&gt;&amp;lt;TDynamic, TKey&amp;gt;&amp;gt;(keyExpression, thing);
    }
}&lt;/pre&gt;

&lt;p&gt;OK, bear with me.  This is where all the real funny stuff goes on.  In the DynamicViewConfiguration&amp;lt;T&amp;gt; constructor, we find the primary key column.  We use that to (again, through reflection, because we don’t know any generic types at compile time) create the lambda function for the EF entity configuration HasKey method.  We use the key property name, reflection, and more of the Dynamic Linq library to return the property of the type within the Generate() method.&lt;/p&gt;

&lt;p&gt;After that, we call ToTable passing in the name of the view.  Voila.  We’ve defined the underlying view name and the key field.&lt;/p&gt;

&lt;p&gt;With the context (and model) defined for our runtime type, the service class can then call GetDynamicQueryResults&amp;lt;T&amp;gt;, and as mentioned earlier, I get a true IQueryable&amp;lt;T&amp;gt; back.  I can use Linq to filter or sort the results and the view is not queried until the set is iterated.&lt;/p&gt;

&lt;p&gt;The last missing piece is how to call the service class.  This is done in an MVC controller.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green;"&gt;// Generate a type based on the return columns
&lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type &lt;/span&gt;type = &lt;span style="color: rgb(43, 145, 175);"&gt;QueryTypeFactory&lt;/span&gt;.GetType(query, columns);

&lt;span style="color: rgb(43, 145, 175);"&gt;MethodInfo &lt;/span&gt;generic = &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;IQueryCatalogDynamic&lt;/span&gt;).GetMethod(&lt;span style="color: rgb(163, 21, 21);"&gt;"GetDynamicQueryResults"&lt;/span&gt;).MakeGenericMethod(type);
&lt;span style="color: blue;"&gt;var &lt;/span&gt;data = generic.Invoke(repository, &lt;span style="color: blue;"&gt;new object&lt;/span&gt;[] { query, columns });&lt;/pre&gt;

&lt;p&gt;The controller gets the runtime type through our type factory class, then calls the GetDynamicQueryResults on the service instance, and we invoke the method, passing in our parameters.  The controller uses this functionality to return an IQueryable&amp;lt;T&amp;gt; to the grid databinding function, which actually performs the sort and filter.  With literally millions of rows in some tables, the jqGrid client-side paging and sorting was nearly instant.&lt;/p&gt;

&lt;p&gt;Now I know that this is sort of a bastardization of technology, but the use case is narrow, and it worked great for my scenario.  The purpose isn’t really how to uglify EF, but more so how some solutions can be solved with a little ingenuity (and a lot of head-banging against keyboards).&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/148618.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2012/02/06/using-entity-framework-to-query-dynamic-types.aspx</guid>
            <pubDate>Mon, 06 Feb 2012 23:21:41 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/148618.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2012/02/06/using-entity-framework-to-query-dynamic-types.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/148618.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/148618.aspx</trackback:ping>
        </item>
        <item>
            <title>NuCon 2012, Irvine, CA</title>
            <link>http://blog.davidbarrett.net/archive/2012/01/16/nucon-2012-irvine-ca.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2012/01/16/nucon-2012-irvine-ca.aspx'&gt;http://blog.davidbarrett.net/archive/2012/01/16/nucon-2012-irvine-ca.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If you’re in southern California on February 16, 2012, come out to &lt;a href="http://www.neudesic.com/nucon/"&gt;NuCon 2012&lt;/a&gt;.  Spend the day building an IT strategy for your organization through business and technical &lt;a href="http://www.neudesic.com/nucon/schedule.html"&gt;tracks&lt;/a&gt;.  Meet with peers and experts in your field, demo technology, and &lt;a href="http://www.neudesic.com/nucon/activities.html"&gt;win prizes&lt;/a&gt;!  &lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/148367.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2012/01/16/nucon-2012-irvine-ca.aspx</guid>
            <pubDate>Mon, 16 Jan 2012 17:20:06 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/148367.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2012/01/16/nucon-2012-irvine-ca.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/148367.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/148367.aspx</trackback:ping>
        </item>
        <item>
            <title>Sharepoint Conference 2011, Anaheim, CA</title>
            <category>Neudesic</category>
            <link>http://blog.davidbarrett.net/archive/2011/09/15/sharepoint-conference-2011-anaheim-ca.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2011/09/15/sharepoint-conference-2011-anaheim-ca.aspx'&gt;http://blog.davidbarrett.net/archive/2011/09/15/sharepoint-conference-2011-anaheim-ca.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If you’ll be at the Sharepoint Conference this year, here’s something you’ll want to tuck into your back pocket.  See the following information on some cool Sharepoint solutions and some fun stuff to boot, courtesy of my employer.&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;From Oct. 3 to 6 at the SharePoint Conference 2011 in Anaheim, Calif. Neudesic experts will be on hand to demonstrate innovative “SharePoint Plus” solutions.  “SharePoint Plus” solutions enhance social, mobile, business intelligence and user experience capabilities to Microsoft’s popular business collaboration platform. One of Neudesic’s central “SharePoint Plus” solutions is Pulse, a software product that transforms SharePoint’s My Site experience into a captivating, socially collaborative environment.&lt;/p&gt;  &lt;p&gt;To take a closer look at the benefits associated with integrating Neudesic Pulse and Neudesic SharePoint Services into SharePoint 2010, Neudesic will host “Space X Launches SharePoint 2010 with Neudesic Pulse for Out of this World Business Collaboration” on Thursday, Oct. 6 from 9 – 10:15 a.m. By implementing Neudesic products and services, Space X broke down existing paradigms of information and created more direct lines of communication in order to facilitate ideation and shared knowledge across the organization.  &lt;a href="http://www.spacex.com/"&gt;http://www.spacex.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Neudesic will also sponsor an evening celebration at Disneyland Park from 8 p.m.-1 a.m. featuring unlimited drinks and refreshments, access to many of the park’s rides and attractions, and a private viewing of Fantasmic.&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/146908.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2011/09/15/sharepoint-conference-2011-anaheim-ca.aspx</guid>
            <pubDate>Thu, 15 Sep 2011 23:50:53 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/146908.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2011/09/15/sharepoint-conference-2011-anaheim-ca.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/146908.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/146908.aspx</trackback:ping>
        </item>
        <item>
            <title>Azure Storage Explorer 4 Beta 1 Released</title>
            <link>http://blog.davidbarrett.net/archive/2010/10/25/azure-storage-explorer-4-beta-1-released.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2010/10/25/azure-storage-explorer-4-beta-1-released.aspx'&gt;http://blog.davidbarrett.net/archive/2010/10/25/azure-storage-explorer-4-beta-1-released.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If you use Windows Azure simple storage, there’s a tool that you can use to browse your artifacts in storage.  Go grab the &lt;a href="http://azurestorageexplorer.codeplex.com/"&gt;latest version&lt;/a&gt;.&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/142441.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2010/10/25/azure-storage-explorer-4-beta-1-released.aspx</guid>
            <pubDate>Mon, 25 Oct 2010 16:04:35 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/142441.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2010/10/25/azure-storage-explorer-4-beta-1-released.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/142441.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/142441.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.Net Security Vulnerability Discovered</title>
            <link>http://blog.davidbarrett.net/archive/2010/09/20/asp.net-security-vulnerability-discovered.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2010/09/20/asp.net-security-vulnerability-discovered.aspx'&gt;http://blog.davidbarrett.net/archive/2010/09/20/asp.net-security-vulnerability-discovered.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;A significant security vulnerability was discovered in ASP.Net (all versions) over the weekend.  To learn about the issue and how to protect any sites you may have running on ASP.Net, check Scott Gu's link.  &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx&lt;/a&gt;&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/141903.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2010/09/20/asp.net-security-vulnerability-discovered.aspx</guid>
            <pubDate>Mon, 20 Sep 2010 15:16:34 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/141903.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2010/09/20/asp.net-security-vulnerability-discovered.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/141903.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/141903.aspx</trackback:ping>
        </item>
        <item>
            <title>Firefox Delicious Add-in, RefControl, Missing Bookmarks, and Poor Software Design</title>
            <link>http://blog.davidbarrett.net/archive/2010/02/03/firefox-delicious-add-in-refcontrol-missing-bookmarks-and-poor-software-design.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2010/02/03/firefox-delicious-add-in-refcontrol-missing-bookmarks-and-poor-software-design.aspx'&gt;http://blog.davidbarrett.net/archive/2010/02/03/firefox-delicious-add-in-refcontrol-missing-bookmarks-and-poor-software-design.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I have been experiencing an ongoing issue with the Delicious Firefox add-in where the list of local bookmarks didn’t jive with the list on the Delicious website – I had more locally than on the Delicious website.  After an unfruitful exchange with Delicious support (does anyone ever really get any help with first level support?  No offense intended, people), I set out to figure out what was going on myself.&lt;/p&gt;  &lt;p&gt;Turns out that another Firefox add-in called RefControl caused the post to the Delicious website to fail when adding new bookmarks.  The add-in uses a local SqlLite instance to cache your bookmarks offline so as to improve performance, so what was happening was that the add-in added the bookmark locally, but the post to the website failed, and so the bookmark never was really ‘saved’.  What’s the rub?  The add-in received an ‘authentication failed’ response from the Delicious services, but didn’t notify the user that an error occurred.  Happily, I kept on, thinking my bookmarks were safe and ubiquitously stored on Delicious’ servers.  Bad, bad design, that decision not to capture an exception and notify the user.&lt;/p&gt;  &lt;p&gt;It wasn’t until I noticed the discrepancy between the add-in and the web that I ever realized there was a problem.  To make matters worse, there’s no way to sync between your local cache and the web, only a one-way from the web to your local cache.  So I had to hack up the SqlLite database of bookmarks, cull the ones that were missing from the web, and re-add them one by one.  Not a fun thing to make your users do.  Again, shame on you, Delicious.&lt;/p&gt;  &lt;p&gt;Incidentally, the fix for using RefControl and Delicious together in Firefox is to add an exception to RefControl:  Allow del.icio.us as Normal.&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/137785.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2010/02/03/firefox-delicious-add-in-refcontrol-missing-bookmarks-and-poor-software-design.aspx</guid>
            <pubDate>Wed, 03 Feb 2010 23:24:44 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/137785.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2010/02/03/firefox-delicious-add-in-refcontrol-missing-bookmarks-and-poor-software-design.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/137785.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/137785.aspx</trackback:ping>
        </item>
        <item>
            <title>Windows Azure Dev Fabric and the PathTooLongException</title>
            <link>http://blog.davidbarrett.net/archive/2009/10/09/windows-azure-dev-fabric-and-the-pathtoolongexception.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2009/10/09/windows-azure-dev-fabric-and-the-pathtoolongexception.aspx'&gt;http://blog.davidbarrett.net/archive/2009/10/09/windows-azure-dev-fabric-and-the-pathtoolongexception.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I’ve been working on converting a complex, distributed, real-world application to the cloud.  It’s been an exciting journey, but also one filled with little gotchas.  One such gotcha was a failure on startup of dev fabric when running a web role containing a series of WCF services.  The specific exception I got ended up being a PathTooLongException.&lt;/p&gt;  &lt;p&gt;I dug into the problem and discovered that the folder hierarchy for the ‘deployed’ artifacts running on the local dev fabric is crazy long.  As my project artifacts were deployed, the dev fabric was throwing the PathTooLongException when it ran into an assembly whose full path exceeded the OS limit.  Because of the length of the root dev fabric deployment path, the flexibility of naming your web/worker roles and dependent assemblies is significantly limited.  Here’s what I found:&lt;/p&gt;  &lt;p&gt;The root path of deployments made to dev fabric is something like (on Win 2008, anyway):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Users\{username}\AppData\Local\dftmp\s0\&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font color="#000000"&gt;This isn’t crazy (yet), but each deployment consists of a series of hierarchical folders depending on the roles.  Within each role, dependent assemblies are located still deeper within the folder structure.  So, as an example, one of the assemblies might be located at (this was an actual path; names changed to protect the innocent):&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Users\{username}\AppData\Local\dftmp\s0\deployment(27)\res\deployment(27).{ServiceDefName}.{RoleName}.0\AspNetTemp\aspNetTemp\root\07ac5e60\bd64b387\assembly\dl3\2cbe1cb5\591b1f0f_1842ca01\{AssemblyName}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is crazy long!  Without the username, service definition name, role name, and assembly name, I’m already up to 156 characters.  Considering the path length maximums are 248 for the folder name, and 260 for the complete filename, we’re already pretty far along.&lt;/p&gt;  &lt;p&gt;Now, consider this:  sometimes, you use 3rd party assemblies, whose names can’t easily be changed.  Take, for example, one of the Enterprise Library assemblies: Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF.dll.  This just happened to be one of the assemblies being used by my WCF services.  Taking that assembly name into account, that’s chewing through another 69 characters, leaving just 23/35 characters total for the username, service definition name, and role name before hitting the directory/path limits, respectively.  That’s not a lot of characters, especially when you consider that some usernames are a concatenation of first and last, such as david.barrett.  Another 13 characters lost.&lt;/p&gt;  &lt;p&gt;How do you minimize these tokens?&lt;/p&gt;  &lt;p&gt;The ServiceDefName token in the path above can be modified by manually updating the value in the ServiceDefinition.csdef and ServiceConfiguration.cscfg without any effect on the code (in other words, you don’t have to actually change the name of the project or folder:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;ServiceDefinition name="A" xmlns="&lt;a href="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&amp;quot;"&gt;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"&lt;/a&gt;&amp;gt;…&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font color="#000000"&gt;The RoleName is taken from the project name.  This is the same name that shows in Visual Studio, and is not necessarily the name of the project file itself.  I typically name projects (and assemblies) with a ‘namespace’ flavor, such as Company.System.Subsystem/Feature.  In this case, I can’t afford that length, so I had to shorten it something like &lt;em&gt;Svcs&lt;/em&gt; after creating the project initially as Company.System.Subsystem.  Blech.&lt;/font&gt;&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/135386.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2009/10/09/windows-azure-dev-fabric-and-the-pathtoolongexception.aspx</guid>
            <pubDate>Fri, 09 Oct 2009 21:55:39 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/135386.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2009/10/09/windows-azure-dev-fabric-and-the-pathtoolongexception.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/135386.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/135386.aspx</trackback:ping>
        </item>
        <item>
            <title>Conferencing Add-In for Outlook: &amp;ldquo;An error occurred while executing this command&amp;rdquo;</title>
            <link>http://blog.davidbarrett.net/archive/2009/08/03/conferencing-add-in-for-outlook-ldquoan-error-occurred-while-executing-this.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2009/08/03/conferencing-add-in-for-outlook-ldquoan-error-occurred-while-executing-this.aspx'&gt;http://blog.davidbarrett.net/archive/2009/08/03/conferencing-add-in-for-outlook-ldquoan-error-occurred-while-executing-this.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I experienced this error recently and spent an eternity trying to resolve it.  I finally found the solution to my problem and wanted to document it for others.&lt;/p&gt;  &lt;p&gt;For me, the issue only appeared when I tried to invite people to a scheduled meeting.  Under normal circumstances, blank (no invitees) scheduled meetings worked fine.  Ad-hoc meetings worked fine.  Some invitees worked, but others did not.  When an invitee caused the issue to appear, this message would be displayed either when I saved/sent the meeting, or tried to set an invitee as a meeting leader.&lt;/p&gt;  &lt;p&gt;It turned out to be caused by the format of the invitee information.  Typically, on an Exchange-based email network, your global address book contains all the people within your company.  Sometimes, emails will get sent around that results in employee names being displayed something like My Name &amp;lt;my.name@company.com&amp;gt; instead of just My Name.  These entries can get cached in a frequent recipient list that will pop down when entering addressees.&lt;/p&gt;  &lt;p&gt;Well, it turns out this format causes the Conferencing Add-In to barf.  When entering recipients into a LiveMeeting request, entries in this format (as opposed to the usual Exchange My Name format) will cause something somewhere to fail, resulting in this message.  Keep in mind that the name will look correct in the To: field, even though “behind the scenes” it’s actually the lengthy format above.&lt;/p&gt;  &lt;p&gt;To resolve, either select a user from the Global Address Book when entering attendees or remove the entry for the cached list by hitting Ctrl-Delete while the name is highlighted in the list.  Then enter a name, force a lookup on the user (“Check Names”), and all should be well.&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/133876.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2009/08/03/conferencing-add-in-for-outlook-ldquoan-error-occurred-while-executing-this.aspx</guid>
            <pubDate>Mon, 03 Aug 2009 18:18:27 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/133876.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2009/08/03/conferencing-add-in-for-outlook-ldquoan-error-occurred-while-executing-this.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/133876.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/133876.aspx</trackback:ping>
        </item>
        <item>
            <title>Azure Local Storage Endpoints</title>
            <category>Azure</category>
            <link>http://blog.davidbarrett.net/archive/2009/05/12/azure-local-storage-endpoints.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2009/05/12/azure-local-storage-endpoints.aspx'&gt;http://blog.davidbarrett.net/archive/2009/05/12/azure-local-storage-endpoints.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I’m constantly having to search for the local development storage endpoint Uris when I create a new Azure storage project from scratch, not to mention the account name and shared key, so I’m posting them here for my own reference.  Hopefully others will also find it useful.&lt;/p&gt;  &lt;div&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ConfigurationSettings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setting&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="AccountName"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;             &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="devstoreaccount1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setting&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="AccountSharedKey"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;             &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setting&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="BlobStorageEndpoint"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;             &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://127.0.0.1:10000/"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setting&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="QueueStorageEndpoint"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://127.0.0.1:100001/"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setting&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="TableStorageEndpoint"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://127.0.0.1:10002/"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ConfigurationSettings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/132059.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2009/05/12/azure-local-storage-endpoints.aspx</guid>
            <pubDate>Tue, 12 May 2009 15:40:30 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/132059.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2009/05/12/azure-local-storage-endpoints.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/132059.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/132059.aspx</trackback:ping>
        </item>
        <item>
            <title>Team Build: Part 1</title>
            <category>VSTS</category>
            <category>TFS</category>
            <category>Team Build</category>
            <link>http://blog.davidbarrett.net/archive/2009/03/10/team-build-part-1.aspx</link>
            <description>&lt;p&gt;Originally posted on: &lt;a href='http://blog.davidbarrett.net/archive/2009/03/10/team-build-part-1.aspx'&gt;http://blog.davidbarrett.net/archive/2009/03/10/team-build-part-1.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I’ve had the fortune of being involved in some pretty complex and elegant Team Build configurations.  I’ve started to blog about individual points several times, but ended up figuring that I should instead write a series of posts about common goals and general Team Build approaches.  I can’t take credit for all this content.  Some I’ve developed over time, some I’ve learned from others on the web, and yet other stuff I’ve learned from co-workers.  That said, here we go with Part 1.&lt;/p&gt;  &lt;h4&gt;General Approach&lt;/h4&gt;  &lt;p&gt;Every person has their personal preference, and this is typically taken to the nth degree with programmers.  What follows are my personal preferences.  Yours may vary.&lt;/p&gt;  &lt;p&gt;First, I like to separate any custom team build stuff from the default TFSBuild.proj file.  I’ll update properties already existing in that file, or available via the Microsoft.TeamFoundation.Build.targets file, directly in TFSBuild.proj.  But all my custom stuff exists in a separate file, or files.  For example, I’ll aggregate all my custom tasks into a CustomTasks.targets file, and import that at the bottom of TFSBuild.proj:&lt;/p&gt;  &lt;div&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #008000"&gt;&amp;lt;!--  ADDITIONAL REFERENCE PATH&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt; The list of additional reference paths to use while resolving references. For example:&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #008000"&gt;     &amp;lt;AdditionalReferencePath Include="C:\MyFolder\" /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #008000"&gt;     &amp;lt;AdditionalReferencePath Include="C:\MyFolder2\" /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &lt;span style="color: #008000"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!-- Add our custom target overrides --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Environment.proj"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="CustomTasks.targets"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here, we’ve imported the CustomTasks.targets file that contains all of our customizations, and we’ve also imported an Environment.proj file that contains metadata about the environment to which we typically deploy this build configuration.  In this way, we can create additional build for additional environments, and only need to change the Environment.proj file.&lt;/p&gt;

&lt;p&gt;Within the CustomTasks.targets file, I declare any custom MSBuild tasks I need, as well as define my overrides and custom targets.  (See &lt;a href="http://msdn.microsoft.com/en-us/library/aa337604.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa337604.aspx&lt;/a&gt; for a list of overridable team build targets).  An example skeleton is as follows:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="utf-8"&lt;/span&gt;?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Project&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/developer/msbuild/2003"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolsVersion&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="3.5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UsingTask&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TaskName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="XmlMassUpdate"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AssemblyFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UsingTask&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TaskName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Attrib"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AssemblyFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UsingTask&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TaskName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="XmlFile.GetValue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AssemblyFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(MSBuildExtensionsPath)\Microsoft.Sdc\Microsoft.Sdc.Tasks.dll"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UsingTask&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TaskName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="XmlFile.SetValue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AssemblyFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(MSBuildExtensionsPath)\Microsoft.Sdc\Microsoft.Sdc.Tasks.dll"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="BuildNumberOverrideTarget"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CallTarget&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Targets&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="CalculateCustomBuildNumber"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="GenerateDocumentation"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CallTarget&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Targets&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="CreateCustomDocumentation"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!-- Custom targets removed for brevity. --&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;For custom build tasks, I typically rely heavily on the Sdc and MSBuild Community tasks (&lt;a href="http://www.codeplex.com/sdctasks"&gt;http://www.codeplex.com/sdctasks&lt;/a&gt; and &lt;a href="http://msbuildtasks.tigris.org/"&gt;http://msbuildtasks.tigris.org/&lt;/a&gt;).  There’s not alot they can’t do, but if you find something, you can always develop a custom task yourself.&lt;/p&gt;

&lt;h4&gt;Adjusting Application Settings During a Deploy&lt;/h4&gt;

&lt;p&gt;One of the custom tasks I rely *heavily* on is the XmlMassUpdate task.  There are many scenarios where you want to tweak configuration settings when you deploy to an environment, and this task is perfect for it.  In a nutshell, you provide a set of configuration data (in this case, Xml), and the task dynamically updates/removes/adds the config content to match your desired settings.  I typically embed the configuration directly in the custom build file, but you could also declares this externally.  MSBuild supports including “random” Xml in the build file via the &amp;lt;ProjectExtensions/&amp;gt; node (anything within this content is ignored by MSBuild).  So, using this and the XmlMassUpdate tasks, we can do the following (example only):&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ProjectExtensions&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:xmu&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="urn:msbuildcommunitytasks-xmlmassupdate"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MyAppConfig&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=""&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;appSettings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmu:key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="key"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="MyDeployedValue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="One"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmu:key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="key"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="MySecondDeployedValue"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Two"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;appSettings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MyAppConfig&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ProjectExtensions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ConfigOverride"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Attrib&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Files&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(SolutionRoot)\MyApp.config"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ReadOnly&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="false"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;XmlMassUpdate&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ContentFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(SolutionRoot)\MyApp.config"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                        &lt;span style="color: #ff0000"&gt;ContentRoot&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="/configuration"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;                        &lt;span style="color: #ff0000"&gt;SubstitutionsFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="$(BuildDirectory)\BuildType\CustomTasks.targets"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;                        &lt;span style="color: #ff0000"&gt;SubstitutionsRoot&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="/msb:Project/msb:ProjectExtensions/MyAppConfig/configuration"&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;                        &lt;span style="color: #ff0000"&gt;NamespaceDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="msb=http://schemas.microsoft.com/developer/msbuild/2003"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The attrib task is there because, by default, files grabbed from source control to be used during a build are read-only.  You’ll want to check the docs on how to use XmlMassUpdate, but the short of this says (assume you call the ConfigOverride target somewhere else in your build process):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On the file MyApp.config in my solution path, replace/modify content starting at the /configuration node, using the content included in the CustomTasks.targets file (this same file) starting with the node located at Project/ProjectExtensions/MyAppConfig/configuration.  In this case, it will update the appSettings/add node with an “key” attribute of ‘MyDeployedValue’ to have a “value” attribute of ‘One’, and similarly for the second entry.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I use this for all manner of things, from updating configs, to updating project files (they’re just Xml after all), to updating Sandcastle help file docs, to adjusting ClickOnce settings on a deploy.  We’ll see more about these in the next several posts.&lt;/p&gt; &lt;img src="http://blog.davidbarrett.net/aggbug/129998.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>David Barrett</dc:creator>
            <guid>http://blog.davidbarrett.net/archive/2009/03/10/team-build-part-1.aspx</guid>
            <pubDate>Tue, 10 Mar 2009 22:32:07 GMT</pubDate>
            <wfw:comment>http://blog.davidbarrett.net/comments/129998.aspx</wfw:comment>
            <comments>http://blog.davidbarrett.net/archive/2009/03/10/team-build-part-1.aspx#feedback</comments>
            <wfw:commentRss>http://blog.davidbarrett.net/comments/commentRss/129998.aspx</wfw:commentRss>
            <trackback:ping>http://blog.davidbarrett.net/services/trackbacks/129998.aspx</trackback:ping>
        </item>
    </channel>
</rss>