<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0"><channel><title>Readify's shared items in Google Reader</title><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ReadifysSharedItems" /><language>en</language><managingEditor>noemail@noemail.org (Readify)</managingEditor><lastBuildDate>Thu, 13 Oct 2011 18:25:56 PDT</lastBuildDate><generator>Google Reader http://www.google.com/reader</generator><gr:continuation xmlns:gr="http://www.google.com/schemas/reader/atom/">CPL47tni0qoC</gr:continuation><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="readifysshareditems" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><description></description><item><title>Log Tapping</title><link>http://www.paulstovell.com/log-tapping</link><category>log4net</category><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/fbd53467f84755cf</guid><description>&lt;p&gt;Octopus uses &lt;a href="http://logging.apache.org/log4net/"&gt;log4net&lt;/a&gt;, my favourite logging library. It also performs a lot of background tasks - for example, deploying applications. &lt;/p&gt;

&lt;p&gt;I wanted the output from log4net to be written to the event log (in the case of warnings/errors), as well as to the UI. However, I didn't want to end up with this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;log.Error(ex);
job.Output.Append(ex);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One of my tricks was to set up a "log tapper" - much like a wire tap. This allows me to "listen in" on the log4net chatter within a specific context. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var output = new StringBuilder();

log.Info("Starting the job");

using (LogTapper.CaptureTo(output))
{
    log.Info("Doing the work...");

    someObject.DoSomethingThatAlsoHappensToLog();
}

log.Info("Finished the job");
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The LogTapper sets up a scope - within the current thread, and as long as the using block is open, and log messages written by log4net will be appended to the &lt;code&gt;StringBuilder&lt;/code&gt; in addition to their normal destinations. &lt;/p&gt;

&lt;p&gt;Doing this means I can present the log4net output of a job in the UI, without it being mixed up with the output from lots of other jobs. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;LogTapper&lt;/code&gt; implementation is quite simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class LogTapper : IDisposable
{
    LogTapper(StringBuilder builder)
    {
        ThreadContext.Properties["LogOutputTo"] = builder;
    }

    public static IDisposable CaptureTo(StringBuilder builder)
    {
        return new LogTapper(builder);
    }

    public void Dispose()
    {
        ThreadContext.Properties.Remove("LogOutputTo");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;ThreadContext&lt;/code&gt; is a log4net class, and it stores properties that are available to &lt;a href="http://logging.apache.org/log4net/release/sdk/log4net.ThreadContext.html"&gt;all log4net appenders on a per-thread basis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To make the implementation work, I then set up a log4net Appender. Whenever a log is written, if a "log tapper" is active on the current thread, it will log the same message to the tapper:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class LogTapAppender : IAppender
{
    public string Name { get; set; }

    public void DoAppend(LoggingEvent loggingEvent)
    {
        var capture = ThreadContext.Properties["LogOutputTo"] as StringBuilder;
        if (capture == null)
            return;

        capture.AppendLine(DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + " " + loggingEvent.Level.DisplayName.PadRight(6, ' ') + " " + loggingEvent.RenderedMessage);

        if (loggingEvent.ExceptionObject != null)
        {
            capture.Append(loggingEvent.ExceptionObject.ToString());
            capture.AppendLine();
        }
    }

    public void Close()
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What I like about this approach is that all of my components just write useful information to the log4net &lt;code&gt;ILog&lt;/code&gt; - they don't need to know if they are being called within the context of a UI, or a job, or any other alternative way of recording their progress. My higher-level controlling classes can siphon the output of any components they call into the place that makes the most sense for them. &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/log-tapping"&gt;</description></item><item><title>Some early thoughts on Node.js</title><link>http://notgartner.wordpress.com/2011/10/11/some-early-thoughts-on-node-js/</link><category>Uncategorized</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Mitch Denny</dc:creator><pubDate>Mon, 10 Oct 2011 19:36:36 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/2039c55bf9221880</guid><description>&lt;p&gt;I’m pretty late to the &lt;a href="http://nodejs.org"&gt;Node.js&lt;/a&gt; party but I’ve found myself with some imposed free time this week so I thought I would spend some time getting across this newcomer. To get thing started I watch &lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=jo_B4LTHi3I"&gt;this video featuring Ryan Dahl&lt;/a&gt;. What follows is some reflection on what I see as the state of the platform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Node.js is a Mashup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first thing to remember is that Node.js is standing on the shoulders of giants. It hosts Google’s open source JavaScript engine (&lt;a href="http://code.google.com/p/v8/"&gt;V8&lt;/a&gt;), so the runtime and the language are a known quantity – this is good! &lt;a href="http://v8.googlecode.com/svn/data/benchmarks/v6/run.html"&gt;JavaScript performance has come a long way&lt;/a&gt; since I first starting dabbling with it.&lt;/p&gt;
&lt;p&gt;Because they haven’t invented their own language, and because they haven’t invented their own execution engine I put Node.js in the mashup category – and in doing so made JavaScript easily available as a server-side programming language. Of course, no modern web platform is completely without a package management tool – here you’ll find this space filled by &lt;a href="http://npmjs.org"&gt;NPM&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Process Model and Hosting&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Even though Node.js seems to be the new black, I think that is has some major hurdles to overcome around its process model. Each node process has one thread, so you might have a fantastically powerful box, but you aren’t going to be able to leverage it unless you are into cross process communication. Its easy enough to get Node to balance incoming requests across multiple processes using the “-balance” switch but if you do want to share data between those processes you need to serialise transmit and deserialise the data.&lt;/p&gt;
&lt;p&gt;When you start working at massive scale those tend to be some of the problems you need to deal with anyway, especially in the area of distributed caching, but these are also problems that not everyone has. A vast majority of software developers out there work within enterprises writing relatively low-load applications that just get uploaded to a server somewhere and tick along. Mind you, by that logic a single process with a single thread might serve their purposes just fine &lt;img src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt;
&lt;p&gt;Ultimately – the thing that worries me is the assumption that server == application == process. When you have a dedicated web server infront of your web application platform it can do useful things like sharing the same port/URL space with multiple applications. You can &lt;a href="http://arguments.callee.info/2010/04/20/running-apache-and-node-js-together/"&gt;patch through specific requests to Node JS&lt;/a&gt; and I see this becoming the most common hosting scenario for Node.js considering the kind of site density you get on some hosting providers.&lt;/p&gt;
&lt;p&gt;Overall – I can’t see why Node.js won’t be a viable web development platform moving forward. I think problems are being solved almost as quickly as they are being discovered which is what happens when you start trying to solve real problems with a new technology.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I’m actually very spoilt. I do most of my development with Visual Studio targeting the .NET platform, and Microsoft has bar none to most powerful debugging experience in any tool that I’ve ever used – so when I see things like “debugger;” in code I just want to cry. I suspect that debugger UX and debugger support are two completely different things. See, the UX that Microsoft has in Visual Studio has evolved for over a decade. The UX has been enhanced to support dealing with things like concurrency and adding first class support for TPL. Its hard for a newcomer to compete with hundreds of man years of investment, if I want to play with Node.js, I need to deal with a limited debugger experience.&lt;/p&gt;
&lt;p&gt;What I didn’t know, and what I do find interesting however is the way that the V8 engine exposes debugger information in the form of a JSON messages. In theory you could build a bridge between Node/V8 to Visual Studio and end up with quite a powerful combination. The model is a lot like the profiler API in .NET actually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Packages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Node.js by itself isn’t that interesting. Its got the fundamentals to get a server up and running, but if you commit to Node.js, you are also committing to learn at least half a dozen other frameworks in order to do something productive – same old story with any platform I guess.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Final Thought – Why Bother&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I think the novel thing about Node.js is the fact that it is a viable server-side JavaScript execution environment. I don’t think its process model has any special scalability benefits (at least not beyond what I am experience with in .NET), so for a .NET developer I have to ask the question – why would I bother? Natural geek curiosity is the first part of the answer, but a lot of good comes from investigating other platforms. Sometimes you pick up new techniques can be migrated back to your home turf, and vice-versa, and of course if Node.js really takes off (its getting some hot press these days) then you’ll be better prepared.&lt;/p&gt;
&lt;br&gt;Filed under: &lt;a href="http://notgartner.wordpress.com/category/uncategorized/"&gt;Uncategorized&lt;/a&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/notgartner.wordpress.com/3175/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/notgartner.wordpress.com/3175/"&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=notgartner.wordpress.com&amp;amp;blog=307844&amp;amp;post=3175&amp;amp;subd=notgartner&amp;amp;ref=&amp;amp;feed=1" width="1" height="1"&gt;</description></item><item><title>Switching to Trello</title><link>http://www.paulstovell.com/octopus/trello</link><category>octopus</category><category>trello</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/8070570d00314ea5</guid><description>&lt;p&gt;One of the things I'm noticing about running my Micro ISV is that I have to constantly change my mind :)&lt;/p&gt;

&lt;p&gt;Until today I &lt;a href="http://www.paulstovell.com/octopus/planning-for-v1"&gt;had been using AgileZen&lt;/a&gt; to manage the Octopus backlog. There is also &lt;a href="http://help.octopusdeploy.com/discussions/suggestions"&gt;a discussion board&lt;/a&gt; on Tender for people to post suggestions/ideas on improving Octopus.  &lt;/p&gt;

&lt;p&gt;AgileZen is great, but one of the downsides was that a suggestion would get added to the board, but people could never see how it was progressing or where it sat in the queue. There was also no voting, so I couldn't gauge how many people thought a suggestion was good. &lt;/p&gt;

&lt;p&gt;Today I switched to Trello, which is very similar to AgileZen but also allows public visibility. I'm hoping this will create much more transparency in how Octopus develops:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://trello.com/board/octopus/4e907de70880ba000079b75c"&gt;View the Octopus Trello&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you create an account on Trello (or use your Google account) you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vote for suggestions/features you like&lt;/li&gt;
&lt;li&gt;Add comments to items&lt;/li&gt;
&lt;li&gt;See how a suggestion progresses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trello doesn't yet allow you to create new suggestions, so they should still be posted to the &lt;a href="http://help.octopusdeploy.com/discussions/suggestions"&gt;Octopus discussion board&lt;/a&gt;. I'll then add the suggestion to Trello so you can see how it progresses. &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/trello"&gt;</description></item><item><title>iPhone/MonoTouch Unit Testing with Team Foundation Server</title><link>http://feedproxy.google.com/~r/CodingForFunAndProfit/~3/NMIXxV2BHuk/iphonemonotouch-unit-testing-with-team.html</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">uglybugger</dc:creator><pubDate>Sun, 25 Sep 2011 16:19:59 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/48f7adf13a46116d</guid><description>&lt;p&gt;I know, I know: apples, oranges etc. It’s not really, though – this is actually quite straight-forward. But first, some background.&lt;/p&gt;  &lt;p&gt;I was recently involved in building another iPhone application for an enterprise customer. We had previously dealt with that customer and had a good working relationship and level of trust with them, but a huge part of that trust was the visibility that we provided as to what was going on. It’s mostly off-topic for this post, but the way we did it involved using Team Foundation Server, giving the client’s people accounts and making sure that the client’s product owner could log in at any time and see how the project was going.&lt;/p&gt;  &lt;p&gt;With the iPhone application, we wanted to do exactly the same. The problem was that we hadn’t had that much experience using TFS to build iPhone apps. Most of our collective efforts had either been in Objective C using git (the stock-standard approach that Xcode pushes) or C#/MonoTouch using Mercurial (my experience). While both of those approaches are fine for personal and small projects, we really wanted all the other bonus points that TFS provides (continuous integration, work item tracking, reporting, web-based project portal etc.)&lt;/p&gt;  &lt;p&gt;So how’d we do it? Well, the first thing to note is that we’re not actually building the application bundle using TFS – yet. That still requires a MacBook, MonoDevelop and a bunch of other stuff. We’ll probably get there soon using custom build tasks, rsync, ssh and a few other things, but we’re not quite there yet.&lt;/p&gt;  &lt;p&gt;What we &lt;em&gt;do&lt;/em&gt; have is a working continuous integration and nightly build, plus running tests using MSTest. The nice thing is that it actually wasn’t that hard.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open the project in Visual Studio (not MonoDevelop). You’ll probably need something like Chris Small’s &lt;a href="https://bitbucket.org/mrshrinkray/monotouch-samples/src/b1983c0a8d68/MonotouchProjectConverter/"&gt;MonoTouch Project Converter&lt;/a&gt; to make this work happily.&lt;/li&gt;    &lt;li&gt;Include monotouch.dll in your /lib directory and reference it from there rather than from the GAC. (It won’t be in the GAC on your build server, and nor should it be.)&lt;/li&gt;    &lt;li&gt;If you have other dependencies (e.g. System.Data), copy those from your MacBook into /lib as well and reference those from there.&lt;/li&gt;    &lt;li&gt;Done :)&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The key point to note when you’re building your app is that you’re not going to be able to easily test your ViewController classes using MSTest, so make them dumb. If there’s business logic in there, extract it out into your domain model. If there’s data access logic in there… well… you’re doing it wrong anyway and you should &lt;em&gt;definitely&lt;/em&gt; extract that out :)&lt;/p&gt;  &lt;p&gt;You’ll end up with an app that has a dumb(ish) UI shell wrapped around a bunch of well-tested business logic classes. The added bonus of doing it this way is that you can then re-use a lot of that code when you write your WP7 or Android version.&lt;/p&gt;  &lt;p&gt;The outcome? The visibility we wanted from the reporting and work item tracking side of things, plus a CI build that didn’t require witchcraft to configure, plus automated unit tests.&lt;/p&gt;  &lt;p&gt;The only real down-side of this approach is that the build we’re unit-testing isn’t the build we’re shipping – we still have to build that manually on a MacBook somewhere. It does, however, give us a good indication of our overall code quality and a reliable safety net for refactoring.&lt;/p&gt;  &lt;div&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/4458266317332321413-6233448404097936319?l=www.codingforfunandprofit.com" alt=""&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingForFunAndProfit/~4/NMIXxV2BHuk" height="1" width="1"&gt;</description></item><item><title>5 Minute Screencast: Stop helping your users. Help yourself.</title><link>http://blog.tatham.oddie.com.au/2011/09/15/5-minute-screencast-stop-helping-your-users-help-yourself/</link><category>Presentations</category><category>Web Development</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Tatham Oddie</dc:creator><pubDate>Wed, 14 Sep 2011 16:23:10 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/918735cfc3532c78</guid><description>&lt;p&gt;A few weeks ago I spoke at &lt;a href="http://whatdoyouknow.webdirections.org/videos/stop-helping-your-users-help-yourself"&gt;Web Directions’ What Do You Know event&lt;/a&gt;. The event consisted of 10 speakers each doing a 5 minute presentation about some technique or idea that they find useful in web development.&lt;/p&gt;
&lt;p&gt;Here’s my talk:&lt;/p&gt;
&lt;span style="text-align:center;display:block"&gt;&lt;a href="http://blog.tatham.oddie.com.au/2011/09/15/5-minute-screencast-stop-helping-your-users-help-yourself/"&gt;&lt;img src="http://img.youtube.com/vi/04rTSNCoZ9M/2.jpg" alt=""&gt;&lt;/a&gt;&lt;/span&gt;
&lt;p&gt;Ros Hodgekis won the night with her awesome email-related talk (all delivered with champagne glass still in hand):&lt;/p&gt;
&lt;span style="text-align:center;display:block"&gt;&lt;a href="http://blog.tatham.oddie.com.au/2011/09/15/5-minute-screencast-stop-helping-your-users-help-yourself/"&gt;&lt;img src="http://img.youtube.com/vi/QDpA7Ae1hDA/2.jpg" alt=""&gt;&lt;/a&gt;&lt;/span&gt;
&lt;br&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tatham.wordpress.com/571/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tatham.wordpress.com/571/"&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.tatham.oddie.com.au&amp;amp;blog=171289&amp;amp;post=571&amp;amp;subd=tatham&amp;amp;ref=&amp;amp;feed=1" width="1" height="1"&gt;</description></item><item><title>Octopus: V1 backlog</title><link>http://www.paulstovell.com/octopus/features-for-v1</link><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/c9d1411969a24e90</guid><description>&lt;p&gt;When I started building Octopus and released &lt;a href="http://www.paulstovell.com/octopus/beta"&gt;a first beta&lt;/a&gt;, I had a pretty rough idea of &lt;a href="http://www.paulstovell.com/octopus/intro"&gt;what Octopus would be about&lt;/a&gt;. The beta experience has definitely shaped the product, and I'm much happier with the result that has been created by so much good feedback from the Octopus beta testers. Last week I had a couple of really useful phone calls with Octopus users, and I used some of that feedback to come up with a list of features that will make the final 'v1' cut of Octopus. &lt;/p&gt;

&lt;h3&gt;What does v1 actually mean?&lt;/h3&gt;

&lt;p&gt;Octopus currently has version numbers starting with 0.8, suggesting it's still in beta. Octopus 1.0 will be the version that is &lt;a href="http://semver.org/"&gt;ready for production use&lt;/a&gt; (though a few companies are already using Octopus in production at the moment). The 1.0 builds will also be the first builds where a &lt;a href="http://octopusdeploy.com/Pricing"&gt;license key&lt;/a&gt; will be required to unlock multiple projects. But in truth, there will still be new builds every few days after 1.0, and the product will continue to evolve incrementally. &lt;/p&gt;

&lt;h3&gt;V1 features&lt;/h3&gt;

&lt;p&gt;Before 1.0 is stamped, I'll add the following 'big' features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auto upgrade Tentacle&lt;/strong&gt;&lt;br&gt;
Tentacles will be automatically kept up to date with the Octopus (as per &lt;a href="http://www.paulstovell.com/octopus/auto-upgrade-tentacle"&gt;this blog post&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ad-hoc PowerShell execution on Octopus&lt;/strong&gt;&lt;br&gt;
As a user, I can define a deployment step that involves executing arbitrary PowerShell scripts on the Octopus, so I can perform tasks like configuring load balancers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Role based security&lt;/strong&gt;&lt;br&gt;
Create application-managed groups of Windows groups/users, and give them project/environment permissions - e.g., only 'Release Managers' can deploy Project A to Production (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/12-security-around-the-octopus-admin-site"&gt;suggestion&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pre-defined variable substitutions&lt;/strong&gt;&lt;br&gt;
For example, you can define &lt;code&gt;VarA = Hello${VarB}&lt;/code&gt;, and a number of useful pre-defined variables will be available (current path, date, etc.) (&lt;a href="http://help.octopusdeploy.com/discussions/questions/10-get-tentacle-application-path-in-variable"&gt;suggestion&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those features will be built first, so they have the most time to be tested and to get feedback on. &lt;/p&gt;

&lt;p&gt;The following small features/bug fixes are also going to be added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Download log files&lt;/strong&gt;&lt;br&gt;
When viewing the results of a deployment, instead of trying to read the results in my browser, I'd like a link to download the output as a .txt file that I can open in my preferred text editor (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/15-download-deployment-log"&gt;suggestion&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Show NuGet descriptions&lt;/strong&gt;&lt;br&gt;
When viewing a release, I want to see the the NuGet package description and release notes in the 'Packages' tab (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/10-suggestion-display-nuget-package-description-when-creating-and-viewing-a-release"&gt;suggestion&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy server support&lt;/strong&gt;&lt;br&gt;
Ensure Octopus can contact Tentacles and NuGet repositories via the default proxy server (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/8-proxy-support"&gt;suggestion&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command line&lt;/strong&gt;&lt;br&gt;
A command line Tentacle.exe, and a command line Octopus.exe, for programmatically executing a deployment (either locally or remotely) (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/11-command-line-service-call-or-api-for-automatic-deployment-support"&gt;suggestion&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project clone&lt;/strong&gt;&lt;br&gt;
Create a copy of an existing project to reduce effort required. Useful for example when setting up deployment of a branch of the same code (&lt;a href="http://help.octopusdeploy.com/discussions/suggestions/14-create-new-project-by-copying-another"&gt;suggestion&lt;/a&gt;). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also some small usability features, like better rendering of times, making it obvious deployment steps can be sorted using drag and drop, better naming of some buttons, and adding a favicon. &lt;/p&gt;

&lt;p&gt;There's also a nice long backlog of post-v1 features, such as automatic deployments, pull-based deployments, &lt;/p&gt;

&lt;p&gt;I estimate that this will take &lt;a href="http://meta.stackoverflow.com/questions/19478/the-many-memes-of-meta/19514#19514"&gt;6 to 8 weeks&lt;/a&gt;. Tomorrow I'll announce a special discount that will apply until v1 is released. &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/features-for-v1"&gt;</description></item><item><title>What price Cloud?</title><link>http://www.paulstovell.com/octopus/what-price-cloud</link><category>octopus</category><category>cloud</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/df22d70fc11203c0</guid><description>&lt;p&gt;I wanted to set up the infrastructure for Octopus properly. This meant that I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL server&lt;/li&gt;
&lt;li&gt;A TeamCity server&lt;/li&gt;
&lt;li&gt;A Web server or two (for OctopusDeploy.com)&lt;/li&gt;
&lt;li&gt;A domain controller&lt;/li&gt;
&lt;li&gt;A handful of servers for an Octopus test farm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of these servers are public, most would be private. I &lt;a href="http://www.paulstovell.com/the-big-move"&gt;just moved overseas&lt;/a&gt; so I didn't want to &lt;a href="http://www.paulstovell.com/behind"&gt;put another server in my living room&lt;/a&gt;. I started by looking at some cloud providers. Here are some really rough, back-of-the-envelope calculations (for Windows servers):&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;td&gt;Provider&lt;/td&gt;&lt;td&gt;CPU&lt;/td&gt;&lt;td&gt;RAM&lt;/td&gt;&lt;td&gt;Per hour&lt;/td&gt;&lt;td&gt;Per month (750 hours)&lt;/td&gt;&lt;/thead&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;a href="http://aws.amazon.com/ec2/pricing/"&gt;Amazon EC2&lt;/a&gt;&lt;/td&gt;
  &lt;td&gt;1 core&lt;/td&gt;
  &lt;td&gt;1.7gb&lt;/td&gt;
  &lt;td&gt;$0.12&lt;/td&gt;
  &lt;td&gt;$90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;a href="http://www.microsoft.com/windowsazure/pricing/#compute"&gt;Azure Compute&lt;/a&gt;&lt;/td&gt;
  &lt;td&gt;1 core&lt;/td&gt;
  &lt;td&gt;1.75gb&lt;/td&gt;
  &lt;td&gt;$0.12&lt;/td&gt;
  &lt;td&gt;$90&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Discounts are available if you buy spot instances or reserve hours, but from what I can gather, I'd be looking at $400-$500/month to have half a dozen 'small' servers on the cloud. &lt;/p&gt;

&lt;p&gt;For my needs, it turned out to be cheaper to rent a high-spec dedicated server, and to have my own mini-cloud. &lt;a href="http://www.leaseweb.com/en/dedicated-servers/configurator-custom-built#"&gt;LeaseWeb&lt;/a&gt; came to the rescue - for the last three months I've been renting a Quad core, 24GB RAM server for €190 (about $270 today). With 24gb I can run 10 'small' Azure instances, or about $900 worth of 'cloud'.  What I do miss out on is the rapid provisioning. If I needed a second of these servers, it could take over a week to provision one. &lt;/p&gt;

&lt;p&gt;If Octopus was a cloud service, I'd definitely look at offloading this to a real cloud provider. But for running TeamCity and a handful of test VM's, it appears to me that putting a server in a data centre is still more cost effective. Is that your experience?&lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/what-price-cloud"&gt;</description></item><item><title>WP7 Essentials Settings Provider</title><link>http://jake.ginnivan.net/wp7-essentials-settings-provider</link><category>wp7essentials</category><category>wp7</category><category>open-source</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jake Ginnivan</dc:creator><pubDate>Fri, 09 Sep 2011 16:14:14 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/b302a19e4d2fcbeb</guid><description>&lt;h2&gt;Settings Provider?&lt;/h2&gt;

&lt;p&gt;The settings provider is a port from the FunnelWeb settings provider to Windows Phone. It is a really simple interface&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public interface ISettingsProvider
{
    T GetSettings&amp;lt;T&amp;gt;() where T : ISettings, new();
    void SaveSettings&amp;lt;T&amp;gt;(T settings) where T : ISettings;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what does &lt;code&gt;T&lt;/code&gt; actually look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class ApplicationSettings : NotifyPropertyChanged, ISettings
{
    [DefaultValue(5)]
    [DisplayName("Number Results")]
    public int NumberResults { get; set; }

    public string Nickname { get; set; }

    [DefaultValue(true)]
    [DisplayName("Enable Stuff")]
    public bool EnableStuff { get; set; }

    public DateTime? Birthday { get; set; }

    [DisplayName("Some Options")]
    public Options SomeOptions { get; set; }
}

public enum Options
{
    Value1, 
    Value2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty easy right? We can use NotifyPropertyWeaver to keep the class nice and clean. Then to fetch or persist our settings we just need to do&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var applicationSettings = settingsProvider.GetSettings&amp;lt;ApplicationSettings&amp;gt;();
applicationSettings.SomeOptions = Options.Value2;
settingsProvider.SaveSettings(applicationSettings);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Settings Provider is limited to types supported by the Convert.ChangeType method (for a number of reasons, if this is too restrictive, let me know and why).&lt;/p&gt;

&lt;p&gt;So in the last release we added the SettingsList control, which will generate this for you (just the settings control, not the page, highlighted in red is what you get generated)&lt;/p&gt;

&lt;p&gt;&lt;img src="http://jake.ginnivan.net/get/screenshots/SettingsProvider.png" alt="Settings Provider control" title=""&gt;&lt;/p&gt;

&lt;p&gt;This is a first cut, and over time I will polish this page, and add support for ordering the properties and stuff (or feel free to submit pull requests :)). But I recon this is pretty cool for a first cut.&lt;/p&gt;

&lt;p&gt;Also the reason I am using a combobox instead of the ListPicker is there is a bug where the control simply doesn't work inside a scroll viewer. Bah. Anyone interested in doing a community fork which simply fixes bugs in the toolkit and doesn't add any new features?&lt;/p&gt;

&lt;h2&gt;Get it&lt;/h2&gt;

&lt;p&gt;This control is in a separate package (to keep the essentials package lean and mean :P).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Install-Package WindowsPhoneEssentials.Controls.Settings
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://wp7essentials.codeplex.com/"&gt;Codeplex&lt;/a&gt;&lt;br&gt;
&lt;a href="http://nuget.org/List/Search?searchTerm=WindowsPhoneEssentials"&gt;NuGet&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://jake.ginnivan.net/via-feed/wp7-essentials-settings-provider"&gt;  &lt;div&gt;
                      
                    &lt;/div&gt;</description></item><item><title>Octopus: Keeping Tentacles up to date</title><link>http://www.paulstovell.com/octopus/auto-upgrade-tentacle</link><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/ca713d378f794186</guid><description>&lt;p&gt;In &lt;a href="http://octopusdeploy.com"&gt;Octopus&lt;/a&gt;, you use one central web portal to push &lt;a href="http://help.octopusdeploy.com/kb/packaging/what-is-a-package"&gt;NuGet packages&lt;/a&gt; out to many servers. On each server is a "Tentacle", a little Agent that receives NuGet uploads, and installs and configures packages &lt;a href="http://help.octopusdeploy.com/kb/conventions/what-are-conventions"&gt;according to conventions&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;One of the annoying things about Tentacles at the moment is that as you get more than a few of them, the upgrade experience isn't very nice. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First you &lt;a href="http://octopusdeploy.com/download"&gt;download&lt;/a&gt; the new Octopus installer&lt;/li&gt;
&lt;li&gt;Remote desktop to the Octopus server and install it&lt;/li&gt;
&lt;li&gt;Now download the new Tentacle installer&lt;/li&gt;
&lt;li&gt;Remote desktop into every single staging/test/production server, and install it&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Improving the upgrade process&lt;/h3&gt;

&lt;p&gt;I'd like to make this process easier, so I'm using this blog post as a way to come up with a solution. I'm going to make use of &lt;a href="http://en.wikipedia.org/wiki/Bootstrapping_(compilers)"&gt;bootstrapping&lt;/a&gt; - that is, I'm going to use Tentacle to install Tentacle. &lt;/p&gt;

&lt;p&gt;Currently, the Tentacle is a Windows Service EXE that works something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It starts&lt;/li&gt;
&lt;li&gt;It hosts a WCF service (net.tcp on port 10933)&lt;/li&gt;
&lt;li&gt;Packages are uploaded to it, and it installs them&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Bootstrapping the Tentacle&lt;/h3&gt;

&lt;p&gt;To allow Tentacle to bootstrap itself, I'm going to do two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turn Tentacle into a Console App instead of a Windows Service&lt;/li&gt;
&lt;li&gt;Create "Suction cup" - a bootstrapper Windows Service that launches Tentacle&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;New installs&lt;/h3&gt;

&lt;p&gt;When you first install Tentacle to your test/staging/production server, the MSI will include a bundled NuGet package. On start-up, Suction Cup will install the package using the standard conventions. Then it will launch Tentacle.exe as a child process (much like IIS's main process launches each ASP.NET application pool child process). &lt;/p&gt;

&lt;h3&gt;Upgrades&lt;/h3&gt;

&lt;p&gt;Suppose a few weeks later, you download and install a new version of Octopus. The Octopus will include a Tentacle NuGet package matching the Octopus version. You can then navigate to &lt;a href="http://www.paulstovell.com/get/octopus/Environments.PNG"&gt;the Environments page&lt;/a&gt; in Octopus, and click a button to deploy the new Tentacle package.&lt;/p&gt;

&lt;p&gt;Now, here's the interesting bootstrapping part: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tentacle (v1) will deploy Tentacle (v2) to a side-by-side folder&lt;/li&gt;
&lt;li&gt;Tentacle (v1) will shut itself down (&lt;code&gt;Environment.Exit(0)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Suction Cup will realize that the Tentacle child process has shut down&lt;/li&gt;
&lt;li&gt;Suction Cup will find the latest installed version of Tentacle (now v2) and launch the new child process&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Notes&lt;/h3&gt;

&lt;p&gt;This has some added benefits - for example, if something catastrophic happened during a deployment and Tentacle crashes, Suction Cup will automatically restart it. &lt;/p&gt;

&lt;p&gt;One thing I'll need to detect is that if Tentacle repeatedly crashes in a short period of time, e.g., 5 times in 30 seconds, Suction Cup should wait a while before trying again - this way we don't fill up the event log. &lt;/p&gt;

&lt;p&gt;Finally, since Suction Cup itself isn't upgraded during this process, I'm going to go with the approach that Suction Cup just needs to be 100% perfect from day 1 :) &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/auto-upgrade-tentacle"&gt;</description></item><item><title>Octopus: planning for v1</title><link>http://www.paulstovell.com/octopus/planning-for-v1</link><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/717886116a85082f</guid><description>&lt;p&gt;Since I started working on Octopus, I've been using &lt;a href="http://agilezen.com/"&gt;AgileZen&lt;/a&gt; as a task board. The graph below gives an idea of how the work has progressed:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.paulstovell.com/get/octopus/Cumulative.PNG" alt="Cumulative flow diagram from AgileZen"&gt;&lt;/p&gt;

&lt;p&gt;There are a few nice things this graph suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The backlog is always growing thanks to great suggestions from the beta testing group&lt;/li&gt;
&lt;li&gt;The archive is also always growing, because work is actually getting completed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The slowdown in change during July/August is due to my &lt;a href="http://www.paulstovell.com/the-big-move"&gt;moving overseas&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;On a fixed time, fixed scope project I'd ideally want to see backlog growing much slower, if at all, as the project nears completion. For product development, however, I think it's actually healthy for the backlog to be growing as quickly as the 'done' column. &lt;/p&gt;

&lt;p&gt;So far I've been following &lt;a href="http://programming-motherfucker.com/"&gt;this methodology&lt;/a&gt;, but as I prepare for an Octopus version 1.0, I want to get a little more disciplined about my process. One of the things I miss working as a one-man-band is the "closure" that comes when working on actual sprints - the sprint planning and sprint review sessions in Scrum are a good way to book-end a few weeks of work. &lt;/p&gt;

&lt;p&gt;To improve my process, here's what I am going to start doing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run two-week 'sprints'&lt;/li&gt;
&lt;li&gt;On the first Monday, choose the work to do, and move it from the backlog to the 'Sprint' column&lt;/li&gt;
&lt;li&gt;Post the sprint plan on my blog&lt;/li&gt;
&lt;li&gt;Do the work&lt;/li&gt;
&lt;li&gt;On the last Sunday (since most of the Octopus work is done on weekends), move work from 'done' into 'archive'&lt;/li&gt;
&lt;li&gt;Send an email to the beta testing list with what features were completed, so people know what to expect&lt;/li&gt;
&lt;li&gt;Celebrate with cake&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During the two weeks I'll also spend a good amount of time on support (I'll blog about how I use &lt;a href="http://help.octopusdeploy.com"&gt;Tender&lt;/a&gt; for that), so each sprint probably won't go exactly as planned. &lt;/p&gt;

&lt;p&gt;How do you approach your personal projects? What else could I do to improve my process? My first 'sprint' should start on Monday, 12th September. &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/planning-for-v1"&gt;</description></item><item><title>My Sessions at TechEd 2011</title><link>http://jake.ginnivan.net/teched-2011</link><category>vsto</category><category>wp7</category><category>presentations</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jake Ginnivan</dc:creator><pubDate>Mon, 29 Aug 2011 05:27:55 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/6885add73cccb1a3</guid><description>&lt;h2&gt;DEV304 - Adding Value to Software Projects with VSTO (Wed, 11:30am)&lt;/h2&gt;

&lt;p&gt;This sessions will have something for everyone, if you have never used VSTO and are interested in it, I will be showing the value it has.
If you have used it, and hated it, I will also be showing how to improve your experience and give you a way of approaching the problems and some nice ways to improve the default experience. Part of this is a quick intro to COM Interop, how it works and how to make sure you avoid problems with it.
And finally, I will be showing a bit of VSTO contrib and how you can use IoC and other cool enhancements to the platform.&lt;/p&gt;

&lt;h2&gt;WPH305 - Multi-Tasking and Application Services (Fri, 8:15am)&lt;/h2&gt;

&lt;p&gt;In this session with Chris Walsh, we will be going through a whole lot of App services related features in Windows Phone Mango. We will cover things like Multi-Tasking, Background agents, Tiles, Notifications and Search extra's. We have some cool demo's and it will be a fun session.&lt;/p&gt;

&lt;h2&gt;Demos&lt;/h2&gt;

&lt;p&gt;I also have a few demo's lined up
 - Unit Testing with WP7 (1:30pm Wednesday)
 - Windows Phone MVC Intro (2:00pm Wednesday)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Testing with WP7 (1:00pm Wednesday)&lt;/li&gt;
&lt;li&gt;Windows Phone MVC Intro (1:30pm Wednesday)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you attend, feedback is always welcomed and please submit your evals, it helps us as speakers a lot.&lt;/p&gt;
&lt;img src="http://jake.ginnivan.net/via-feed/teched-2011"&gt;  &lt;div&gt;
                      
                    &lt;/div&gt;</description></item><item><title>New Octopus build, website and screenshots</title><link>http://www.paulstovell.com/octopus/news-1</link><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/2f83f1cfc80f4b9a</guid><description>&lt;p&gt;New builds of Octopus are available immediately from my CI server, and can be downloaded from the &lt;a href="http://octopusdeploy.com/download"&gt;Octopus downloads&lt;/a&gt; page. Every couple of weeks, though, I'll publish a short list of what's going on. &lt;/p&gt;

&lt;p&gt;The last couple of weeks saw a lot of new features added. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dashboard, to give you a high level overview of which projects are deployed to what environment.&lt;/li&gt;
&lt;li&gt;Edit release notes for releases that have already been created.&lt;/li&gt;
&lt;li&gt;Scope variables on a per-package basis, in addition to per-environment and per-machine&lt;/li&gt;
&lt;li&gt;A more streamlined release user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A number of bug fixes and tiny enhancements are also included, from a quick list of projects that appear when you hover over the Projects tab, to correctly uninstalling old NuGet packages.&lt;/p&gt;

&lt;p&gt;Below is a screenshot of the new dashboard - you can see larger versions of this screenshot and more on the Features page of &lt;a href="http://octopusdeploy.com"&gt;the new Octopus website&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.paulstovell.com/get/octopus/ss/Dashboard.PNG" alt="The Octopus dashboard"&gt;&lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/news-1"&gt;</description></item><item><title>Why Octopus?</title><link>http://www.paulstovell.com/octopus/why</link><category>octopus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/fe017d8ace19529e</guid><description>&lt;p&gt;Decades from now, I want the IT industry to be known not just for its innovation and creativity, but for its ability to deliver software projects reliably. There's a lot of work to do, and I think Agile principles of frequent, high-quality collaboration and embracing change are playing a big part in getting us there. Along with the human to human improvements, we're also adopting engineering practices to boost our chances of success - source control, continuous integration, and unit testing for example make an enormous difference. &lt;/p&gt;

&lt;p&gt;Delivering even a small software project is a huge undertaking. There are an unlimited number of practices that we'd like to adopt, but since time is always so critical, we always have to make trade-offs. In my experience, there's one practice that always falls into the too-hard basket: automated deployment. &lt;/p&gt;

&lt;p&gt;The state of the art in deployment on the .NET stack leaves a lot to be desired. At big companies and small, I see programmers routinely remoting into production machines to patch configuration files, or writing long and semi-complete documents because automating deployments was too time consuming. After months of repeated test deployments, production deployments still fail and are rushed because of bad automation or incomplete documentation. It's hampering our ability to deliver and give our customers confidence. We can do better. &lt;/p&gt;

&lt;p&gt;I believe wholeheartedly that automated, frequent, repeatable deployments is one of the most important practices we can follow. There's no compelling, standardised, complete solution out there, and I don't know if &lt;a href="http://www.octopusdeploy.com"&gt;Octopus&lt;/a&gt; will ever become one either. But I know that we as an industry would be much better off if we could nail this problem, and I'm going to try my best to do something about it. &lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/octopus/why"&gt;</description></item><item><title>Crash Logging in a MonoTouch App</title><link>http://feedproxy.google.com/~r/CodingForFunAndProfit/~3/jeBKdgBKxTI/crash-logging-in-monotouch-app.html</link><category>iPhone</category><category>MonoTouch</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">uglybugger</dc:creator><pubDate>Fri, 26 Aug 2011 18:23:00 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/7c432860061c2457</guid><description>Customer: Your app crashed again.    &lt;br&gt;Developer: How? What were you doing when it crashed? What happened?     &lt;br&gt;Customer: I don’t know. I was playing with it and it crashed.     &lt;br&gt;Developer: Do you remember which page you were on?     &lt;br&gt;Customer: ?     &lt;br&gt;Developer: *bangs head against wall*&lt;br&gt;
Sound familiar?&lt;br&gt;
One of the first things I do when I start a project (or when I inherit one) is set up logging. You’d be amazed and depressed at how many projects just don’t have any, or bolt it on as an after thought. Here’s a hint: &lt;em&gt;it’s much easier to debug your app while you’re developing it if you know where it’s breaking&lt;/em&gt;. Ground-breaking, I know &lt;img alt="Smile with tongue out" src="http://lh4.ggpht.com/-3fKyPNGZM5k/TlhCKOHjPgI/AAAAAAAAAUE/16CIyFW1aLg/wlEmoticon-smilewithtongueout2.png?imgmax=800" style="border-bottom-style:none;border-left-style:none;border-right-style:none;border-top-style:none"&gt;&lt;br&gt;
There are a couple of things we want to do:&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;Log when the app crashes. Do it quickly and reliably, and don’t rely on any app infrastructure (e.g. injected loggers) as it’s already been torn down at this point. &lt;/li&gt;
&lt;li&gt;Send the log message the next time the app starts. This will allow us to use all our nice web services etc. and means we can use just the one logging mechanism rather than having several different ones. &lt;/li&gt;
&lt;/ol&gt;
MonoDevelop creates a fairly standard-looking Main.cs for us: &lt;br&gt;
  &lt;br&gt;
Let’s change that to add a simple try/catch block:&lt;br&gt;
  &lt;br&gt;
The key here is line 11 – it makes it simple and obvious as to what it’s doing.&lt;br&gt;
So… the CrashLog class itself is a static class and doesn’t do very much at all. The idea is that it’s simple to call and doesn’t rely on having any of the app’s components still available.&lt;br&gt;
  &lt;br&gt;
We’re using the &lt;em&gt;My Documents&lt;/em&gt; special folder as that’s where we’re reliably allowed to write things to on the filesystem.&lt;br&gt;
So now that we have our crash logger, let’s hook things up so that we can log when the app starts again. In our AppDelegate class:&lt;br&gt;
  &lt;br&gt;
Yes, we’re using our IoC container as a service locator. This isn’t good, but we can’t use constructor injection in our AppDelegate as it’s the class responsible for creating our IoC container.&lt;br&gt;
So how does the logger work? Well, that’s up to you. You can choose to make a web-service call; you could spit it to another text file and periodically upload it; you could even send an email if you really wanted to.&lt;br&gt;
My preference is using a web service as I tend to just hook it straight to the server-side logger (which usually uses log4net under the covers), but your mileage may vary.&lt;br&gt;
The next time a customer tells you that your app crashed, though, you’ll be able to respond with, “I know – and I’ve already fixed that bug.”&lt;div&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/4458266317332321413-6552011487361099601?l=www.codingforfunandprofit.com" alt=""&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingForFunAndProfit/~4/jeBKdgBKxTI" height="1" width="1"&gt;</description></item><item><title>An iPhone Eye for the C# Guy at @dddbrisbane</title><link>http://feedproxy.google.com/~r/CodingForFunAndProfit/~3/ahoagNXfbnE/iphone-eye-for-c-guy-at-dddbrisbane.html</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">uglybugger</dc:creator><pubDate>Fri, 26 Aug 2011 17:28:17 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/1dd3c008d7144a4c</guid><description>&lt;p&gt;I just submitted this abstract for &lt;a href="http://www.dddbrisbane.com/"&gt;DDD Brisbane 2011&lt;/a&gt;. Don’t forget to vote for me!&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;An iPhone Eye for the C# Guy&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;iPhone Development using MonoTouch&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;This session will cover the basics of developing an iPhone application using C#/MonoTouch, from how to create a “Hello, world!” app through to a look at a real-world, production codebase.&lt;/p&gt;    &lt;p&gt;We’ll cover the use of web services, threads, databases, generics (yes, you &lt;i&gt;can&lt;/i&gt; use generics), reflection, inversion of control (yes, you can use IoC, too!) and general application architecture, and finish with a look at some tools, tips and tricks to make life as an iPhone developer much less painful.&lt;/p&gt;    &lt;p&gt;This session will assume prior knowledge of threading, reflection, generics, inversion of control and why you'd want to use all of these, but don't let that scare you :)&lt;/p&gt;&lt;/blockquote&gt;  &lt;div&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/4458266317332321413-2846449799003110079?l=www.codingforfunandprofit.com" alt=""&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingForFunAndProfit/~4/ahoagNXfbnE" height="1" width="1"&gt;</description></item><item><title>A Lap around business Connectivity Services in SharePoint 2010</title><link>http://sptechpoint.wordpress.com/2011/08/24/a-lap-around-business-connectivity-services-in-sharepoint-2010/</link><category>Azure</category><category>BCS</category><category>Development</category><category>SharePoint</category><category>Presentations</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nalaka Withanage</dc:creator><pubDate>Tue, 23 Aug 2011 17:39:27 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/1a8216b3335d3a49</guid><description>&lt;p&gt;Here’s is my slide deck and the Resources from the SharePoint Saturday Sydney 2011. Thank you for those who attended and voted for this session.&lt;/p&gt;
&lt;p&gt;  &lt;br&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="500"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;BCS Overview &lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/library/ee661740.aspx"&gt;http://technet.microsoft.com/en-us/library/ee661740.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;Plan to upgrade BCS&lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/library/ff607947.aspx"&gt;http://technet.microsoft.com/en-us/library/ff607947.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;BCS Resource Centre          &lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/sharepoint/ff660755.aspx"&gt;http://msdn.microsoft.com/en-us/sharepoint/ff660755.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;BCS Video – Secure Store          &lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bcs/archive/2010/05/06/bcs-team-channel-secure-store-service.aspx"&gt;http://blogs.msdn.com/b/bcs/archive/2010/05/06/bcs-team-channel-secure-store-service.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;BCS Security Overview          &lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/library/ee661743.aspx"&gt;http://technet.microsoft.com/en-us/library/ee661743.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="573"&gt;How BCS &amp;amp; Azure play together  &lt;/td&gt;
&lt;td valign="top" width="296"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/steve_fox/archive/2010/06/09/sharepoint-2010-amp-windows-azure-how-they-play-together.aspx"&gt;BCS Azure Integration&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br&gt; Tagged: &lt;a href="http://sptechpoint.wordpress.com/tag/azure/"&gt;Azure&lt;/a&gt;, &lt;a href="http://sptechpoint.wordpress.com/tag/bcs/"&gt;BCS&lt;/a&gt;, &lt;a href="http://sptechpoint.wordpress.com/tag/presentations/"&gt;Presentations&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sptechpoint.wordpress.com/448/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sptechpoint.wordpress.com/448/"&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sptechpoint.wordpress.com&amp;amp;blog=10973205&amp;amp;post=448&amp;amp;subd=sptechpoint&amp;amp;ref=&amp;amp;feed=1" width="1" height="1"&gt;&lt;/p&gt;</description></item><item><title>MultiTargeted WP7 Project</title><link>http://jake.ginnivan.net/multitargeted-windows-phone-project</link><category>wp7</category><category>open-source</category><category>msbuild</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jake Ginnivan</dc:creator><pubDate>Mon, 22 Aug 2011 16:01:24 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/f1d1c50f9c766757</guid><description>&lt;p&gt;I saw Shawn Wildermuth's post on maintaining a project targeting multiple versions of windows phone, I thought I would share the way I do it as I think it is far easier than the alternatives.
&lt;a href="http://wildermuth.com/2011/08/23/Maintaining_a_Project_with_Two_Windows_Phone_Versions"&gt;http://wildermuth.com/2011/08/23/Maintaining&lt;em&gt;a&lt;/em&gt;Project&lt;em&gt;with&lt;/em&gt;Two&lt;em&gt;Windows&lt;/em&gt;Phone_Versions&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Multi-Targeted .csproj file&lt;/h2&gt;

&lt;p&gt;First off I open up my .csproj file and add this under the initial property group&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;TargetFrameworkProfile Condition=&amp;quot;&amp;#39;$(TargetFrameworkProfile)&amp;#39; == &amp;#39;&amp;#39;&amp;quot;&amp;gt;WindowsPhone71&amp;lt;/TargetFrameworkProfile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This means I target Windows Phone 71 by default, then I modify the define constants property under each build configuration to be conditional:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;DefineConstants Condition=&amp;quot;&amp;#39;$(TargetFrameworkProfile)&amp;#39; == &amp;#39;WindowsPhone&amp;#39;&amp;quot;&amp;gt;TRACE;SILVERLIGHT;WINDOWS_PHONE&amp;lt;/DefineConstants&amp;gt;
&amp;lt;DefineConstants Condition=&amp;quot;&amp;#39;$(TargetFrameworkProfile)&amp;#39; == &amp;#39;WindowsPhone71&amp;#39;&amp;quot;&amp;gt;TRACE;SILVERLIGHT;WINDOWS_PHONE71&amp;lt;/DefineConstants&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now I can easily include files in only my mango build, for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#if WINDOWS_PHONE71
namespace WindowsPhoneMVC.Navigation
{
    public static class DeepLink
    {
        public static string UriFor(string controller, string action, IDictionary&amp;lt;string, string&amp;gt; parameters)
        {
            var parametersString = string.Join(&amp;quot;&amp;amp;&amp;quot;, parameters.Select(p =&amp;gt; p.Key + &amp;quot;=&amp;quot; + p.Value));
            return string.Format(&amp;quot;/Shell.xaml?controller={0}&amp;amp;action={1}{2}{3}&amp;quot;, controller, action, 
                string.IsNullOrEmpty(parametersString) ?  string.Empty : &amp;quot;&amp;amp;&amp;quot;, parametersString);
        }

        public static NavigationRequest DecodeUri(string navigationFrame, string deepLink)
        {
            var kvp = deepLink.Split(new[] {&amp;#39;&amp;amp;&amp;#39;})
                .Select(o =&amp;gt; o.Split(new[] {&amp;#39;=&amp;#39;}))
                .ToDictionary(k =&amp;gt; k[0], k =&amp;gt; k[1]);

            string controller = null;
            if (kvp.ContainsKey(&amp;quot;controller&amp;quot;))
            {
                controller = kvp[&amp;quot;controller&amp;quot;];
                kvp.Remove(&amp;quot;controller&amp;quot;);
            }

            string action = null;
            if (kvp.ContainsKey(&amp;quot;action&amp;quot;))
            {
                action = kvp[&amp;quot;action&amp;quot;];
                kvp.Remove(&amp;quot;action&amp;quot;);
            }

            return new NavigationRequest(navigationFrame, controller, action, new NavigationParameter(kvp));
        }
    }
}
#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This way in visual studio I always build for 71, then my build.cmd which looks like this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@echo off
call "%VS100COMNTOOLS%vsvars32.bat"
mkdir .\build\log\

msbuild.exe /ToolsVersion:4.0 "WindowsPhoneMVC.msbuild" 

pause
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the important part of that msbuild script, which builds my project as 7.0 and 7.1. After it builds it goes on to create my NuGet packages and releases meaning I can make a fix and test the new NuGet package locally within minutes, it works quite nice.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Target Name=&amp;quot;Compile&amp;quot; DependsOnTargets=&amp;quot;Version&amp;quot;&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC\WindowsPhoneMVC.csproj&amp;quot;
             Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build;TargetFrameworkProfile=WindowsPhone;&amp;quot; /&amp;gt;

    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC\WindowsPhoneMVC.csproj&amp;quot;
             Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build_71;TargetFrameworkProfile=WindowsPhone71;&amp;quot; /&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Complete build script&lt;/h4&gt;

&lt;p&gt;Here is my complete build script if you are interested, or just go to &lt;a href="http://windowsphonemvc.codeplex.com"&gt;http://windowsphonemvc.codeplex.com&lt;/a&gt; to grab the latest version out of source control.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Project DefaultTargets=&amp;quot;Package&amp;quot; xmlns=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;MSBuildCommunityTasksPath&amp;gt;$(MSBuildProjectDirectory)\build\lib\&amp;lt;/MSBuildCommunityTasksPath&amp;gt;
    &amp;lt;Root&amp;gt;$(MSBuildProjectDirectory)\&amp;lt;/Root&amp;gt;
    &amp;lt;Major&amp;gt;0&amp;lt;/Major&amp;gt;
    &amp;lt;Minor&amp;gt;4&amp;lt;/Minor&amp;gt;
    &amp;lt;Build&amp;gt;0&amp;lt;/Build&amp;gt;
    &amp;lt;Revision&amp;gt;0&amp;lt;/Revision&amp;gt;

    &amp;lt;NuGet&amp;gt;$(Root)build\lib\NuGet.exe&amp;lt;/NuGet&amp;gt;
    &amp;lt;ContentSource&amp;gt;$(Root)src\SampleProjects\NuGetContentSource\&amp;lt;/ContentSource&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;Import Project=&amp;quot;$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets&amp;quot;/&amp;gt;
  &amp;lt;Import Project=&amp;quot;$(MSBuildCommunityTasksPath)\MSBuild.Deployment.Tasks.Targets&amp;quot;/&amp;gt;
  &amp;lt;Import Project=&amp;quot;$(MSBuildCommunityTasksPath)\MSBuild.Mercurial.tasks&amp;quot;/&amp;gt;

  &amp;lt;Target Name=&amp;quot;GetVersion&amp;quot;&amp;gt;
    &amp;lt;Error Condition=&amp;quot;$(MSBuildCommunityTasksPath) == &amp;#39;&amp;#39;&amp;quot; Text=&amp;quot;MSBuildCommunityTasksPath variable must be defined&amp;quot; /&amp;gt;
    &amp;lt;Error Condition=&amp;quot;$(Root) == &amp;#39;&amp;#39;&amp;quot; Text=&amp;quot;Root variable must be defined&amp;quot; /&amp;gt;

    &amp;lt;HgVersion LocalPath=&amp;quot;.&amp;quot;&amp;gt;
      &amp;lt;Output TaskParameter=&amp;quot;Revision&amp;quot; PropertyName=&amp;quot;Revision&amp;quot; /&amp;gt;
    &amp;lt;/HgVersion&amp;gt;
    &amp;lt;!-- Diagnostics --&amp;gt;
    &amp;lt;Message Text=&amp;quot;Diagnostics:&amp;quot;/&amp;gt;
    &amp;lt;Message Text=&amp;quot;Build Number:    $(Major).$(Minor).$(Build).$(Revision)&amp;quot; /&amp;gt;
    &amp;lt;Message Text=&amp;quot;Project root:    $(Root)&amp;quot; /&amp;gt;
    &amp;lt;Message Text=&amp;quot;Drop path:       build\Artifacts&amp;quot; /&amp;gt;

    &amp;lt;!-- Clean up --&amp;gt;
    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;FilesToDelete Include=&amp;quot;$(Root)**\bin\**\*.*&amp;quot; /&amp;gt;
      &amp;lt;FilesToDelete Include=&amp;quot;$(Root)**\obj\**\*.*&amp;quot; /&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
    &amp;lt;Delete Files=&amp;quot;@(FilesToDelete)&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;Version&amp;quot; DependsOnTargets=&amp;quot;GetVersion&amp;quot;&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\artifacts\&amp;quot; /&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\temp\&amp;quot; /&amp;gt;

    &amp;lt;AssemblyInfo CodeLanguage=&amp;quot;CS&amp;quot;
	      OutputFile=&amp;quot;$(Root)src\WindowsPhoneMVC\Properties\VersionInfo.cs&amp;quot;
	      AssemblyVersion=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;
	      AssemblyFileVersion=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;
	      Condition=&amp;quot;$(Revision) != &amp;#39;-1&amp;#39; &amp;quot;/&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;Compile&amp;quot; DependsOnTargets=&amp;quot;Version&amp;quot;&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC\WindowsPhoneMVC.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build;TargetFrameworkProfile=WindowsPhone;&amp;quot; /&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.Transitions\WindowsPhoneMVC.Extensions.Transitions.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build;TargetFrameworkProfile=WindowsPhone;&amp;quot; /&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.AutofacIntegration\WindowsPhoneMVC.Extensions.AutofacIntegration.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build;TargetFrameworkProfile=WindowsPhone;&amp;quot; /&amp;gt;

    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC\WindowsPhoneMVC.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build_71;TargetFrameworkProfile=WindowsPhone71;&amp;quot; /&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.Transitions\WindowsPhoneMVC.Extensions.Transitions.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build_71;TargetFrameworkProfile=WindowsPhone71;&amp;quot; /&amp;gt;
    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.AutofacIntegration\WindowsPhoneMVC.Extensions.AutofacIntegration.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;Platform=Any CPU;OutputPath=bin\Build_71;TargetFrameworkProfile=WindowsPhone71;&amp;quot; /&amp;gt;

    &amp;lt;MSBuild Projects=&amp;quot;$(Root)src\Templates\WPMvcTemplatesExtension\WPMvcTemplatesExtension.csproj&amp;quot;
         Properties=&amp;quot;Configuration=Release;OutputPath=bin\Build&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;NuGet&amp;quot; DependsOnTargets=&amp;quot;Compile&amp;quot;&amp;gt;
    &amp;lt;MakeDir Directories=&amp;quot;$(Root)build\artifacts&amp;quot; /&amp;gt;

    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;AutofacContent Include=&amp;quot;$(Root)build\autofaccontent\**\*.*&amp;quot; /&amp;gt;
      &amp;lt;TransitionsContent Include=&amp;quot;$(Root)build\transitionscontent\**\*.*&amp;quot; /&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;

    &amp;lt;!--Main NuGet package--&amp;gt;
    &amp;lt;CallTarget Targets=&amp;quot;MvcNuGet&amp;quot; /&amp;gt;
    &amp;lt;CallTarget Targets=&amp;quot;MvcLibsNuGet&amp;quot; /&amp;gt;
    &amp;lt;CallTarget Targets=&amp;quot;AutofacNuGet&amp;quot; /&amp;gt;
    &amp;lt;CallTarget Targets=&amp;quot;TransitionsNuGet&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;MvcNuGet&amp;quot;&amp;gt;
    &amp;lt;PropertyGroup&amp;gt;
      &amp;lt;NuGetManifest&amp;gt;$(Root)build\temp\WindowsPhoneMVC.nuspec&amp;lt;/NuGetManifest&amp;gt;
      &amp;lt;MainNuGetContent&amp;gt;$(Root)build\temp\NuGet\content\&amp;lt;/MainNuGetContent&amp;gt;
    &amp;lt;/PropertyGroup&amp;gt;

    &amp;lt;MakeDir Directories=&amp;quot;$(Root)build\temp\NuGet\WindowsPhoneMVC\lib&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)build\WindowsPhoneMVC.nuspec&amp;quot;
		      DestinationFiles=&amp;quot;$(NuGetManifest)&amp;quot; /&amp;gt;

    &amp;lt;FileUpdate Files=&amp;quot;$(NuGetManifest)&amp;quot;
				    Regex=&amp;quot;0.0.0.1&amp;quot;
				    ReplacementText=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;/&amp;gt;

    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)Controllers\HomeController.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)Controllers\&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)ViewModels\Home\AboutViewModel.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)ViewModels\Home\&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)ViewModels\Home\MainViewModel.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)ViewModels\Home\&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)Views\Home\MainPage.xaml&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)Views\Home\&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)Views\Home\MainPage.xaml.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)Views\Home\&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)Shell.xaml&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)Shell.xaml.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)WindowsPhoneMVC_GettingStarted.htm&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;

    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;MvcContentFiles Include=&amp;quot;$(MainNuGetContent)\**\*.*&amp;quot; /&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
    &amp;lt;FileUpdate Files=&amp;quot;@(MvcContentFiles)&amp;quot;
				    Regex=&amp;quot;NuGetContentSource&amp;quot;
				    ReplacementText=&amp;quot;$rootnamespace$&amp;quot;/&amp;gt;
    &amp;lt;Move SourceFiles=&amp;quot;@(MvcContentFiles)&amp;quot;
		      DestinationFiles=&amp;quot;@(MvcContentFiles-&amp;gt;&amp;#39;$(MainNuGetContent)%(RecursiveDir)%(Filename)%(Extension).pp&amp;#39;)&amp;quot; /&amp;gt;

    &amp;lt;!--SL3--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL3-WP\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4_71--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build_71\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone71\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;Exec Command=&amp;#39;&amp;quot;$(NuGet)&amp;quot; pack &amp;quot;$(NuGetManifest)&amp;quot; -BasePath &amp;quot;$(Root)build\temp\NuGet&amp;quot; -OutputDirectory &amp;quot;$(Root)build\artifacts&amp;quot;&amp;#39; /&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\temp\&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;MvcLibsNuGet&amp;quot;&amp;gt;
    &amp;lt;PropertyGroup&amp;gt;
      &amp;lt;NuGetManifest&amp;gt;$(Root)build\temp\WindowsPhoneMVC.Libs.nuspec&amp;lt;/NuGetManifest&amp;gt;
    &amp;lt;/PropertyGroup&amp;gt;

    &amp;lt;MakeDir Directories=&amp;quot;$(Root)build\temp\NuGet\WindowsPhoneMVC\lib&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)build\WindowsPhoneMVC.nuspec&amp;quot;
		      DestinationFiles=&amp;quot;$(NuGetManifest)&amp;quot; /&amp;gt;

    &amp;lt;FileUpdate Files=&amp;quot;$(NuGetManifest)&amp;quot;
				    Regex=&amp;quot;0.0.0.1&amp;quot;
				    ReplacementText=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;/&amp;gt;

    &amp;lt;!--SL3--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL3-WP\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4_71--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC\bin\Build_71\WindowsPhoneMVC.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone71\WindowsPhoneMVC.dll&amp;quot;/&amp;gt;
    &amp;lt;Exec Command=&amp;#39;&amp;quot;$(NuGet)&amp;quot; pack &amp;quot;$(NuGetManifest)&amp;quot; -BasePath &amp;quot;$(Root)build\temp\NuGet&amp;quot; -OutputDirectory &amp;quot;$(Root)build\artifacts&amp;quot;&amp;#39; /&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\temp\&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;AutofacNuGet&amp;quot;&amp;gt;
    &amp;lt;PropertyGroup&amp;gt;
      &amp;lt;NuGetAutofacManifest&amp;gt;$(Root)build\temp\WindowsPhoneMVC.Extensions.AutofacIntegration.nuspec&amp;lt;/NuGetAutofacManifest&amp;gt;
      &amp;lt;MainNuGetContent&amp;gt;$(Root)build\temp\NuGet\content\&amp;lt;/MainNuGetContent&amp;gt;
    &amp;lt;/PropertyGroup&amp;gt;

    &amp;lt;MakeDir Directories=&amp;quot;$(Root)build\temp\NuGet\WindowsPhoneMVC.Extensions.AutofacIntegration\lib&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)build\WindowsPhoneMVC.Extensions.AutofacIntegration.nuspec&amp;quot;
		      DestinationFiles=&amp;quot;$(NuGetAutofacManifest)&amp;quot; /&amp;gt;

    &amp;lt;FileUpdate Files=&amp;quot;$(NuGetAutofacManifest)&amp;quot;
				    Regex=&amp;quot;0.0.0.1&amp;quot;
				    ReplacementText=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;/&amp;gt;

    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)To_Enable_Autofac.txt&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)ApplicationModule.cs&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;

    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;AutofacContentFiles Include=&amp;quot;$(MainNuGetContent)\**\*.*&amp;quot; /&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
    &amp;lt;FileUpdate Files=&amp;quot;@(AutofacContentFiles)&amp;quot;
				    Regex=&amp;quot;NuGetContentSource&amp;quot;
				    ReplacementText=&amp;quot;$rootnamespace$&amp;quot;/&amp;gt;
    &amp;lt;Move SourceFiles=&amp;quot;@(AutofacContentFiles)&amp;quot;
		      DestinationFiles=&amp;quot;@(AutofacContentFiles-&amp;gt;&amp;#39;$(MainNuGetContent)%(RecursiveDir)%(Filename)%(Extension).pp&amp;#39;)&amp;quot; /&amp;gt;

    &amp;lt;!--SL3--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.AutofacIntegration\bin\Build\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL3-WP\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.AutofacIntegration\bin\Build\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4_71--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.AutofacIntegration\bin\Build_71\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone71\WindowsPhoneMVC.Extensions.AutofacIntegration.dll&amp;quot;/&amp;gt;
    &amp;lt;Exec Command=&amp;#39;&amp;quot;$(NuGet)&amp;quot; pack &amp;quot;$(NuGetAutofacManifest)&amp;quot; -BasePath &amp;quot;$(Root)build\temp\NuGet&amp;quot; -OutputDirectory &amp;quot;$(Root)build\artifacts&amp;quot;&amp;#39; /&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\temp\&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;TransitionsNuGet&amp;quot;&amp;gt;
    &amp;lt;PropertyGroup&amp;gt;
      &amp;lt;NuGetTransitionsManifest&amp;gt;$(Root)build\temp\WindowsPhoneMVC.Extensions.Transitions.nuspec&amp;lt;/NuGetTransitionsManifest&amp;gt;
      &amp;lt;MainNuGetContent&amp;gt;$(Root)build\temp\NuGet\content\&amp;lt;/MainNuGetContent&amp;gt;
    &amp;lt;/PropertyGroup&amp;gt;

    &amp;lt;MakeDir Directories=&amp;quot;$(Root)build\temp\NuGet\WindowsPhoneMVC.Extensions.Transitions\lib&amp;quot; /&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)build\WindowsPhoneMVC.Extensions.Transitions.nuspec&amp;quot;
		      DestinationFiles=&amp;quot;$(NuGetTransitionsManifest)&amp;quot; /&amp;gt;

    &amp;lt;FileUpdate Files=&amp;quot;$(NuGetTransitionsManifest)&amp;quot;
				    Regex=&amp;quot;0.0.0.1&amp;quot;
				    ReplacementText=&amp;quot;$(Major).$(Minor).$(Build).$(Revision)&amp;quot;/&amp;gt;

    &amp;lt;Copy SourceFiles=&amp;quot;$(ContentSource)To_Enable_Transitions.txt&amp;quot; DestinationFolder=&amp;quot;$(MainNuGetContent)&amp;quot; /&amp;gt;

    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;TransitionsContentFiles Include=&amp;quot;$(MainNuGetContent)\**\*.*&amp;quot; /&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
    &amp;lt;FileUpdate Files=&amp;quot;@(TransitionsContentFiles)&amp;quot;
				    Regex=&amp;quot;NuGetContentSource&amp;quot;
				    ReplacementText=&amp;quot;$rootnamespace$&amp;quot;/&amp;gt;
    &amp;lt;Move SourceFiles=&amp;quot;@(TransitionsContentFiles)&amp;quot;
		      DestinationFiles=&amp;quot;@(TransitionsContentFiles-&amp;gt;&amp;#39;$(MainNuGetContent)\%(RecursiveDir)%(Filename)%(Extension).pp&amp;#39;)&amp;quot; /&amp;gt;

    &amp;lt;!--SL3--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.Transitions\bin\Build\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL3-WP\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.Transitions\bin\Build\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;/&amp;gt;
    &amp;lt;!--SL4_71--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\WindowsPhoneMVC.Extensions.Transitions\bin\Build_71\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\temp\NuGet\lib\SL4-WindowsPhone71\WindowsPhoneMVC.Extensions.Transitions.dll&amp;quot;/&amp;gt;
    &amp;lt;Exec Command=&amp;#39;&amp;quot;$(NuGet)&amp;quot; pack &amp;quot;$(NuGetTransitionsManifest)&amp;quot; -BasePath &amp;quot;$(Root)build\temp\NuGet&amp;quot; -OutputDirectory &amp;quot;$(Root)build\artifacts&amp;quot;&amp;#39; /&amp;gt;
    &amp;lt;RemoveDir Directories=&amp;quot;build\temp\&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;Test&amp;quot; DependsOnTargets=&amp;quot;NuGet&amp;quot;&amp;gt;

  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;Package&amp;quot; DependsOnTargets=&amp;quot;Test&amp;quot;&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;$(Root)src\Templates\WPMvcTemplatesExtension\bin\Build\WindowsPhoneMvcTemplatesExtension.vsix&amp;quot;
		      DestinationFiles=&amp;quot;$(Root)build\artifacts\WindowsPhoneMvcTemplates.vsix&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;
&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="http://jake.ginnivan.net/via-feed/multitargeted-windows-phone-project"&gt;  &lt;div&gt;
                      
                    &lt;/div&gt;</description></item><item><title>Windows Phone MVC Update</title><link>http://jake.ginnivan.net/windows-phone-mvc-update</link><category>wp7</category><category>mvc</category><category>open-source</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jake Ginnivan</dc:creator><pubDate>Mon, 22 Aug 2011 07:17:28 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/7b4ec6d5323f7622</guid><description>&lt;h2&gt;Windows Phone MVC?&lt;/h2&gt;

&lt;p&gt;So to get started, let me explain what it is.&lt;br&gt;
It is a MVC + MVVM Hybrid framework, I think MVVM falls down in a few area's, and by teaming up with the MVC pattern we can achieve great testability, performance, navigation, lifecycle etc.. &lt;/p&gt;

&lt;p&gt;The aim of Windows Phone MVC is to make windows phone development quicker, easier, more enjoyable and most of all help you build a nice performant app which gives an awesome user experience.&lt;/p&gt;

&lt;p&gt;This is going to be quite a long post going through many features of Windows Phone MVC, I hope it gets across what I am trying to do with the framework, and how it can help you out!&lt;br&gt;
I am still a little way from v1, so there will be API changes, but I am more than happy to field some questions about how to use it.&lt;/p&gt;

&lt;p&gt;Many of the improvements on this release are due to &lt;a href="http://transhub.wordpress.com/"&gt;http://transhub.wordpress.com/&lt;/a&gt; using Windows Phone MVC and I have been working close with the transub team to make sure the framework helped them deliver a killer app!&lt;/p&gt;

&lt;h3&gt;Important Links&lt;/h3&gt;

&lt;p&gt;NuGet Package Name: &lt;a href="http://nuget.org/List/Search?packageType=Packages&amp;amp;searchTerm=WindowsPhoneMVC"&gt;WindowsPhoneMVC&lt;/a&gt;&lt;br&gt;
Codeplex URL: &lt;a href="http://windowsphonemvc.codeplex.com/"&gt;http://windowsphonemvc.codeplex.com/&lt;/a&gt;&lt;br&gt;
Documentation: &lt;a href="http://windowsphonefoundations.net/windowsphonemvc"&gt;http://windowsphonefoundations.net/windowsphonemvc&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;MVC&lt;/h3&gt;

&lt;p&gt;First off it is important to understand how a MVC framework works.&lt;/p&gt;

&lt;p&gt;It all starts off with a Controller, and an Action.  &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class HomeController : Controller
{
    public ActionResult Main()
    {
        return Page(new MainViewModel());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An &lt;strong&gt;action&lt;/strong&gt; is simply a method on a class which inherits from Controller. The Controller returns an ActionResult, there are helper methods in the controller base class which let you do this with ease.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; is actions are invoked on a &lt;code&gt;background thread&lt;/code&gt; and you should do work synchronously, we have made this easy with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public ActionResult GetWebData()
{
    var request = WebRequest.CreateHttp(url);
    var response = (HttpWebResponse)Execute.AsyncPatternWithResult(request.BeginGetResponse, request.EndGetResponse);
    return Result(response.GetResponseString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Will talk a bit more about threading later..&lt;/p&gt;

&lt;h4&gt;ActionResults&lt;/h4&gt;

&lt;p&gt;We have a few different action results, they include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PageResult (Navigates to a new page, the parameter you pass becomes the datacontext for that page)&lt;/li&gt;
&lt;li&gt;DialogResult (Shows a dialog over the top of your current page)&lt;/li&gt;
&lt;li&gt;NothingResult (Allows you to finish a controller action without doing anything. i.e if (TrialExpired) &lt;code&gt;return Nothing();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;BackResult (navigates back)&lt;/li&gt;
&lt;li&gt;BackToResult (navigates back to a particular view. i.e to go back to home, no matter how many between &lt;code&gt;return BackTo&amp;lt;HomeController&amp;gt;(&amp;quot;Main&amp;quot;);&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;DataResult (used to return data to the previous view, more info below!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using these, you can do most things you need to pretty easily.&lt;/p&gt;

&lt;h4&gt;Invoking actions&lt;/h4&gt;

&lt;p&gt;Generally you will invoke ALL actions from the viewmodel, currently all the API's are named around navigation, this may change in the future. What do you think?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;//MainViewModel ctor
public MainViewModel()
{
    SearchCommand = Controller&amp;lt;SearchController&amp;gt;.NavigationCommand(c=&amp;gt;c.SearchLocations(SearchCriteria));
}

public SearchCriteria SearchCriteria { get { return searchCriteria; } }
public ICommand SearchCommand { get; private set; }
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;One of the first things that people say to me when I say I am building &lt;em&gt;another&lt;/em&gt; framework for windows phone is, 'I don't use frameworks, they are too slow'.&lt;br&gt;
Something to keep in mind is that there are two types of performance, actual performance and perceived performance. The latter is actually the more important of the two, because it is how the user perceives how fast the application is.
I remember reading in a book the story about how back in the day Microsoft got told that their c++ compiler was slow vs the borland one, even though it WAS faster, so they then made it output everything that it was happening onto the console and the users congratulated them on the improvement. It was about 5% slower because of the output.  &lt;/p&gt;

&lt;p&gt;Windows Phone MVC tries to achieve both by default, I am trying to optimise the framework as much as I can, the overhead in startup time &amp;amp; memory usages is 15-20% at the moment based on some initial testing, I hope to drop this over time and put some neat perf tricks in.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://jake.ginnivan.net/get/screenshots/mvc/ProgressBar.png" alt="Progress Screen" title=""&gt;&lt;/p&gt;

&lt;p&gt;There is a few things to note here, Windows Phone MVC has a rich navigation system, so you can do work, load data, THEN navigate. You can also invoke an action which simply returns you data, or navigates to a page, then returns you the result from that page!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Performance Progress Bar included out of the box (original, if you add transitions extension which needs Silverlight Toolkit, we switch to using the new one from Silverlight Toolkit).&lt;/li&gt;
&lt;li&gt;As soon as you invoke any action the Progress bar will be shown, and the screen grayed. You can also easily show text by just going &lt;code&gt;LoadingMessage("Search in progress..");&lt;/code&gt; from your controller action.&lt;/li&gt;
&lt;li&gt;The app bar buttons are all disabled (we also give you full Commanding support in the app bar! more info on that later).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I still have some tuning and plan on rounding up some WP7 performance experts at TechEd to give me more tips about how I can improve the performance of this, but it feels and looks nice at the moment. &lt;/p&gt;

&lt;h3&gt;MVVM/Commanding Support&lt;/h3&gt;

&lt;p&gt;Out of the box there are some really nice helpers for you.&lt;/p&gt;

&lt;h4&gt;Buttons&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Button commands:Click.Command=&amp;quot;{Binding AboutPageCommand}&amp;quot;
        Content=&amp;quot;About&amp;quot; /&amp;gt;
&amp;lt;Button commands:Navigate.To=&amp;quot;Home.ViewItem&amp;quot;
        DataContext=&amp;quot;{Binding }&amp;quot; &amp;lt;!--Action can be ViewItem(ItemViewModel item)--&amp;gt;
        Content=&amp;quot;View Item&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second can optionally pass the datacontext to the controller action, really useful when you have a button in a list of items.&lt;/p&gt;

&lt;h4&gt;App Bar&lt;/h4&gt;

&lt;p&gt;As you probably know, the Application Bar is not a DependencyObject, so we can't use any of the nice silverlight goodness we are used to. I have taken the following approach:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;phone:PhoneApplicationPage.ApplicationBar&amp;gt;
    &amp;lt;shell:ApplicationBar IsVisible=&amp;quot;True&amp;quot;
                          IsMenuEnabled=&amp;quot;True&amp;quot;&amp;gt;
        &amp;lt;shell:ApplicationBarIconButton IconUri=&amp;quot;/Icons/dark/appbar.add.rest.png&amp;quot;
                                        Text=&amp;quot;new[AddCommand]&amp;quot; /&amp;gt;
        &amp;lt;shell:ApplicationBar.MenuItems&amp;gt;
            &amp;lt;shell:ApplicationBarMenuItem Text=&amp;quot;settings[ShowSettingsPageCommand]&amp;quot; /&amp;gt;
            &amp;lt;shell:ApplicationBarMenuItem Text=&amp;quot;about[ShowAboutPageCommand]&amp;quot; /&amp;gt;
        &amp;lt;/shell:ApplicationBar.MenuItems&amp;gt;
    &amp;lt;/shell:ApplicationBar&amp;gt;
&amp;lt;/phone:PhoneApplicationPage.ApplicationBar&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Simply put the command name in square brackets in your appbar text, and they will be wired up to your viewmodel. Including listening to CanExecuteChanged to enable and disable appbar buttons!&lt;/p&gt;

&lt;h4&gt;ListBoxes&lt;/h4&gt;

&lt;p&gt;Another handy addition is if you have a list of items, and you want to view details when any one of them is selected.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;ListBox ItemsSource=&amp;quot;{Binding Items}&amp;quot;
            Commands:Navigate.OnItemSelected=&amp;quot;AnotherController.ItemAction&amp;quot;
            DisplayMemberPath=&amp;quot;Title&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;On the ViewModel&lt;/h4&gt;

&lt;p&gt;How often do you write something like &lt;code&gt;new DelegateCommand(()=&amp;gt;DoStuff())&lt;/code&gt; in the case of MVC it would be &lt;code&gt;new DelegateCommand(()=&amp;gt;Controller&amp;lt;HomeController&amp;gt;().DoStuff())&lt;/code&gt;. That is kinda ugly, so I have provided a nicer API for defining Commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ShowGreetingPageCommand = Controller&amp;lt;HomeController&amp;gt;().NavigationCommand(c =&amp;gt; c.SayHelloTo(Name));
//or if you want to fetch some data/refresh the page: 
RefreshCommand = Controller&amp;lt;AnotherController&amp;gt;().NavigationCommandWithResult&amp;lt;ObservableCollection&amp;lt;SearchResult&amp;gt;&amp;gt;(c =&amp;gt; c.PerformSearch(Parameter), HandleCallback);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Navigation&lt;/h3&gt;

&lt;p&gt;I mentioned earlier that Windows Phone MVC has a really powerful navigation system. It actually does not use the inbuild NavigationService, it navigates once at the start of the all to your &lt;code&gt;Shell.xaml&lt;/code&gt;, which hosts your app, the framework then takes care of switching out the content, and maintaining it's own journal. This has a number of advantages.&lt;/p&gt;

&lt;p&gt;Be aware that Navigation with Windows Phone MVC is equivilent to Tombstoning that view, when you navigate the controller action will ALWAYS be executed. The advantage of this is that your views/viewmodels can be garbage collected as soon as you navigate away from that view.&lt;/p&gt;

&lt;h4&gt;Type safe navigation WITH arguments&lt;/h4&gt;

&lt;p&gt;Take this navigation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Controller&amp;lt;HomeController&amp;gt;().NavigateTo(c =&amp;gt; c.MyAction(ComplexProperty));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is all type safe, and I am passing any class as an argument to my action, I don't need to know the view name, and I get full intellisense on the arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Due to WP7 limitations around reflection, you cannot pass local variables (declare in the same method), method arguments, or protected/private fields. All of these things require reflection on non public types, which is not supported.&lt;br&gt;
Never fear!&lt;/p&gt;

&lt;p&gt;If you try and do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private void NavigateWithPrivate()
{
    var local = new SomeClass();
    Controller&amp;lt;AnotherController&amp;gt;().NavigateTo(c=&amp;gt;c.PerformSearch(local));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will get a nice helpful error message:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://jake.ginnivan.net/get/screenshots/mvc/NavNotSupported.png" alt="Useful exception message" title=""&gt;&lt;/p&gt;

&lt;p&gt;You can literally copy and paste the suggested syntax (check it first, and let me know if I get any cases wrong) over your code, then it will start working! &lt;/p&gt;

&lt;h4&gt;Back stack manipulation (without Mango :P)&lt;/h4&gt;

&lt;p&gt;At any time in a viewmodel or a controller you can write:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Navigator.RemoveBackEntry();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is pretty cool, and works without mango. But to go one better than what you get in Mango:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Navigator.NavigateBackTo&amp;lt;HomeController&amp;gt;(&amp;quot;Main&amp;quot;);
// or in controller:
return BackTo&amp;lt;HomeController&amp;gt;(&amp;quot;Main&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will unwind the backstack until you get to the matching controller and action! If it can't find it, it will let you know.&lt;/p&gt;

&lt;h4&gt;Returning data to previous page&lt;/h4&gt;

&lt;p&gt;A great example of this is the DateTimePicker in the toolkit, when you click on it, it actually hijacks the navigation service, navigates to a page inside the toolkit, then when you click on one of the appbar buttons it navigates back, then updates the control. Sound useful? It really is..&lt;/p&gt;

&lt;h5&gt;Without a navigation&lt;/h5&gt;

&lt;p&gt;This performs a search in a controller action, then returns the data without navigating.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private void PerformSearch()
{
    Controller&amp;lt;SearchController&amp;gt;().NavigateToWithResult&amp;lt;JourneyPlanningResponse&amp;gt;(c =&amp;gt; c.PerformSearch(SearchCriteria), SearchComplete);
}

private void SearchComplete(JourneyPlanningResponse response)
{
     ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;With navigation&lt;/h5&gt;

&lt;p&gt;What about the datepicker example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GetValueCommand = Controller&amp;lt;DebugController&amp;gt;().NavigationCommandWithResult&amp;lt;string&amp;gt;(c =&amp;gt; c.PageWithResult(), HandleCallback);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then on our viewmodel looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class PageWithResultViewModel : ViewModelBase
{
    private string valueToReturn;

    public PageWithResultViewModel()
    {
        OkCommand = new DelegateCommand(() =&amp;gt; Navigator.NavigationResult(ValueToReturn));
        CancelCommand = new DelegateCommand(() =&amp;gt; Navigator.NavigateBack());
    }

    public string ValueToReturn
    {
        get { return valueToReturn; }
        set
        {
            valueToReturn = value;
            OnPropertyChanged(()=&amp;gt;ValueToReturn);
        }
    }

    public ICommand OkCommand { get; private set; }
    public ICommand CancelCommand { get; private set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I recon that is pretty cool! And super easy to use.... &lt;/p&gt;

&lt;h3&gt;Threading&lt;/h3&gt;

&lt;p&gt;Mentioned earlier, actions are invoked on a background thread, and the Controller's lifetime scope (if using autofac) is disposed as soon as the action is invoked, so you shouldn't &lt;code&gt;return&lt;/code&gt; from the  action before you have fully setup the new view's viewmodel and you shouldn't be waiting for any callbacks. The way we have solved this is with the &lt;code&gt;Execute&lt;/code&gt; class.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var response = (HttpWebResponse)Execute.AsyncPatternWithResult(svc.BeginGetResponse, someArg, request.EndGetResponse);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;//or if the call doesnt return anything
   Execute.AsyncPattern(svc.BeginDoSomething, someArg, svc.EndDoSomething);&lt;/p&gt;

&lt;p&gt;This will turn the async pattern Begin/End pair into a synchronous call. You should not use this class on the UI Thread obviously...&lt;/p&gt;

&lt;p&gt;Talking about the UI Thread, what happens if you want to do stuff on the UI Thread?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Execute.OnUIThread(()=&amp;gt;{/*dostuff*/});
Execute.OnUIThreadSync(()=&amp;gt;{/*do stuff synchronously*/});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These two methods invoke an action(or func with the synchronous option) on the UI Thread asynchronously and synchronously respectively.&lt;/p&gt;

&lt;h3&gt;WP7 Lifecycle&lt;/h3&gt;

&lt;p&gt;Another very important part of developing for WP7 is the lifecycle management. We do a fair bit here to help you out.&lt;/p&gt;

&lt;p&gt;If you want a property to be saved between navigations, and tomb-stoning simply mark it as transient like follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public RegisterViewModel()
{
    Transient(() =&amp;gt; Name);
    Transient(() =&amp;gt; Username);
    Transient(() =&amp;gt; Password);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because we recreate the view each time you navigate (I may possibly introduce caching of the view so it doesn't have to be recreated, but memory pressure is tight pre-mango so will investigate in the future), Panoramas will not restore to the same panel that was selected. This is easily fixed with an attached property&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;toolkit:Panorama Title=&amp;quot;my application&amp;quot;
                  Phone:Restore.PanoramaPosition=&amp;quot;True&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let me know if there any other things that you would like restored.&lt;/p&gt;

&lt;h4&gt;OnActivate/OnDeactivate&lt;/h4&gt;

&lt;p&gt;Windows Phone MVC changes the behaviour slightly from the default experience. When a view is navigated away from, OnDeactivate will be called, and whenever it is shown OnActivate will be executed. Simply override one/both of these methods to do anything you need to for tombstoning.&lt;/p&gt;

&lt;h4&gt;PageState&lt;/h4&gt;

&lt;p&gt;Earlier I mentioned that Windows Phone MVC has it's own NavigationService, and Journal. This means I cannot use the included PageState from the framework as it is tightly coupled with the phones NavigationService. So I have rolled my own.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public interface IPageTransientStore
{
    void Save&amp;lt;T&amp;gt;(string key, T obj) where T : class;
    T Load&amp;lt;T&amp;gt;(string key) where T : class;
    bool Contains(string key);
    void Remove(string key);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All serialisation in Windows Phone MVC is done using Mike Talbot's &lt;a href="http://whydoidoit.com/silverlight-serializer/"&gt;Silverlight Serializer&lt;/a&gt;. This means I can serialise complex types, without specifying known types very fast.&lt;/p&gt;

&lt;h4&gt;Obscured&lt;/h4&gt;

&lt;p&gt;If you are interested in being notified when your app is obscured, simple make your ViewModel inherit from &lt;code&gt;IObscuredAware&lt;/code&gt;, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class ViewResultTestViewModel : ViewModelBase, IObscuredAware
{
    public void Unobscured(object sender, EventArgs e)
    {
    }

    public void Obscured(object sender, ObscuredEventArgs e)
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Deep Linking&lt;/h3&gt;

&lt;p&gt;We also support Mango features! If you want to create a deep link into your Windows Phone MVC application, that is really easy too.. It is also type safe =)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private void CreateDeepLink()
{
    var deepLinkUri = Controller&amp;lt;HomeController&amp;gt;().UriFor(c =&amp;gt; c.DeepLinkPage, new Dictionary&amp;lt;string, string&amp;gt;());
    ShellTile.Create(new Uri(deepLinkUri, UriKind.Relative), new StandardTileData
                                                {
                                                    BackgroundImage = new Uri(&amp;quot;/ApplicationIcon.png&amp;quot;, UriKind.Relative),
                                                    Title = &amp;quot;MVC Deep Link&amp;quot;
                                                });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Deep links can only take a collection of KeyValuePair for the parameters. &lt;/p&gt;

&lt;h3&gt;Transitions&lt;/h3&gt;

&lt;p&gt;Everyone loves a nice sexy app that has transitions. Jeff and the guys behind the Silverlight have made it pretty easy to get nice transitions working in your app. You will be happy to know it is just as easy for Windows Phone MVC. Simple run in your NuGet console &lt;code&gt;Install-Package WindowsPhoneMVC.Extensions.Transitions&lt;/code&gt;. This relies on the Silverlight toolkit and will drop a &lt;code&gt;To_Enable_Transitions.txt&lt;/code&gt; file into your project with the code required to wire it up (super easy).
The usage is exactly the same after the setup.&lt;/p&gt;

&lt;h3&gt;IoC Container Support&lt;/h3&gt;

&lt;p&gt;By default, Windows Phone MVC has a DefaultControllerFactory, this isn't very interesting. So you can just run this in your NuGet console &lt;code&gt;Install-Package WindowsPhoneMVC.Extensions.AutofacIntegration&lt;/code&gt; and you will get two files and a reference added to your project, the first is &lt;code&gt;To_Enable_Autofac.txt&lt;/code&gt;, it will have code in it which you can copy/paste into App.xaml to enable the integration. The next is &lt;code&gt;ApplicationModule.cs&lt;/code&gt; which is where you can register everything.&lt;/p&gt;

&lt;h4&gt;Performance&lt;/h4&gt;

&lt;p&gt;Once again, as soon as you mention an IoC container on the phone, people freak out. The performance penalty is next to nothing if you do a bit of work in your ApplicationModule class.&lt;/p&gt;

&lt;p&gt;Use Register(()=&amp;gt;) rather than RegisterType. Out of the box (so it works by default) you have this in your ApplicationModule.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;builder
    .RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
    .AssignableTo&amp;lt;Controller&amp;gt;()
    .AsSelf();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This has the cost of reflecting your assembly when starting your app, then the reflection cost of construcing the object. A more performant alternative is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;builder
    .Register(c=&amp;gt;new MainController(c.Resolve&amp;lt;ISomeService&amp;gt;()))
    .AsSelf();
builder
    .Register(c=&amp;gt;new SomeService())
    .As&amp;lt;ISomeService&amp;gt;()
    .SingleInstance(); //Lightweight services can be left as SingleInstance
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sure this has more maintenance costs, but the performance different is substantial. On my phone the a object graph of ~90 object constructions took about 30% of the time vs letting the container do the hard work.&lt;/p&gt;

&lt;h3&gt;Debugging&lt;/h3&gt;

&lt;p&gt;To make diagnosing issues, and to give warnings and suggestions, simply handle the Trace event on the NavigationApplication and write the message out to Debug.Write. Internally no logging will be executed if the debugger is not attached.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Application.ApplicationLifetimeObjects&amp;gt;
    &amp;lt;AutofacIntegration:AutofacNavigationApplication Activated=&amp;quot;AutofacNavigationApplicationActivated&amp;quot;
                                                     Deactivated=&amp;quot;AutofacNavigationApplicationDeactivated&amp;quot;
                                                     Closing=&amp;quot;NavigationApplication_OnClosing&amp;quot;
                                                     Trace=&amp;quot;AutofacNavigationApplication_Trace&amp;quot;/&amp;gt;
&amp;lt;/Application.ApplicationLifetimeObjects&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the HelloWorld application this produces an output like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Navigator: Memory usage before navigation: 8.359375
Navigator: Memory usage after navigation: 9.42578125
Navigator: Memory usage before navigation: 9.46484375
Navigator: Memory usage after navigation: 15.55859375
Navigator: Memory usage before navigation: 13.84765625
Navigator: Passing ViewModels as parameters may cause memory pressure as they are not disposed! Consider using base type of NotifyPropertyChanged if the parameter is actually an entity, not a ViewModel.
Navigator: Memory usage after navigation: 19.08203125
Navigator: Memory usage before navigation: 11.46875
Navigator: Memory usage after navigation: 12.62890625
Navigator: Memory usage before navigation: 11.828125
Navigator: Memory usage after navigation: 16.98828125
TimerScope: Beginning Parsing Navigation Expression
Navigator: Memory usage before navigation: 15.3203125
TimerScope: Ending Parsing Navigation Expression. Took 13ms
Navigator: Memory usage after navigation: 19.84765625
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Logging is pretty light at the moment, as I try and identify performance bottlenecks and other things I will likely introduce logging levels and lots more of it. I also hope to add helpful warnings for best practices as I have done with the note about ViewModels.&lt;/p&gt;

&lt;p&gt;The downside of such a rich navigation model, is that you can pass very large things around, and parameters are always kept in memory, and viewmodels often have a lot more data than actually needs to be kept in memory.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I hope this is a useful post as a introduction to Windows Phone MVC, and shows off many of the features which make it really easy to write WP7 applications.&lt;/p&gt;

&lt;p&gt;Please leave feedback, ping me on twitter (@JakeGinnivan), or email me at jake@ginnivan.net with suggestions/issues. I want to power towards v1.0 when I will lock down API's and consider the framework stable. The framework is reasonably stable now, and is being used in a decent size app. But there will likely be situations I haven't thought of, or haven't tested. &lt;/p&gt;

&lt;h2&gt;Go get it!&lt;/h2&gt;

&lt;p&gt;Simply add &lt;code&gt;WindowsPhoneMVC&lt;/code&gt; to your project via NuGet to get started, there will be a readme added to your project and a sample controller/ViewModels etc. If you don't want the files to get you started, choose the libs project&lt;/p&gt;
&lt;img src="http://jake.ginnivan.net/via-feed/windows-phone-mvc-update"&gt;  &lt;div&gt;
                      
                    &lt;/div&gt;</description></item><item><title>Phone Test Project Template</title><link>http://jake.ginnivan.net/phone-test-project</link><category>wp7</category><category>wp7essentials</category><category>open-source</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jake Ginnivan</dc:creator><pubDate>Sat, 20 Aug 2011 18:12:36 PDT</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/85599c9641aa0e3a</guid><description>&lt;p&gt;Last week I put together a project template for a windows phone 7 test project. At the moment there isn't a really good story for unit testing on the phone. If you have the mango tools you have to grab the Mango Silverlight Unit Test assemblies from Jeff Wincox's blog. &lt;/p&gt;

&lt;p&gt;The Project Template available at &lt;a href="http://visualstudiogallery.msdn.microsoft.com/6819514d-4bd6-4f31-a231-48c6530ed03b"&gt;http://visualstudiogallery.msdn.microsoft.com/6819514d-4bd6-4f31-a231-48c6530ed03b&lt;/a&gt; is really basic, and you then have to add a reference via NuGet of either the Silverlight Unit Testing Framework (doesn't work with Mango), or WindowsPhoneEssentials.Testing.&lt;/p&gt;

&lt;p&gt;The advantage of the WindowsPhoneEssentials.Testing project is it contains the Mango compatible versions, sets everything up and has a collection of really useful testing related helpers/abstractions for WP7. Check out &lt;a href="http://windowsphonefoundations.net/windowsphoneessentials"&gt;http://windowsphonefoundations.net/windowsphoneessentials&lt;/a&gt; or the source at &lt;a href="http://wp7essentials.codeplex.com/"&gt;http://wp7essentials.codeplex.com/&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;But what you get after you install it is:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://jake.ginnivan.net/get/screenshots/NewTestProject.png" alt="New Phone Test Project" title=""&gt;&lt;/p&gt;

&lt;p&gt;Then you add the NuGet reference to WindowsPhoneEssentials.Testing&lt;/p&gt;

&lt;p&gt;&lt;img src="http://jake.ginnivan.net/get/screenshots/TestingNuGet.png" alt="Add NuGet reference to WindowsPhoneEssentials.Testing" title=""&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;img src="http://jake.ginnivan.net/via-feed/phone-test-project"&gt;  &lt;div&gt;
                      
                    &lt;/div&gt;</description></item><item><title>ThreadPool vs. Tasks</title><link>http://www.paulstovell.com/threadpool-vs-tasks</link><category>wpf</category><category>threading</category><category>tpl</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Stovell</dc:creator><pubDate>Sun, 26 Feb 2012 18:14:07 PST</pubDate><guid isPermaLink="false">tag:google.com,2005:reader/item/353ce2059f918bcd</guid><description>&lt;p&gt;.NET 4.0 includes a new few new classes called &lt;a href="http://msdn.microsoft.com/en-us/library/dd537609.aspx"&gt;Tasks&lt;/a&gt;, which are part of the Task Parallel Library. You can learn all about them in an article by my friend &lt;a href="http://www.codeproject.com/KB/cs/TPL1.aspx"&gt;Sacha on Code Project&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The TPL is useful, but I'm starting to see a lot of coders using the &lt;code&gt;Task&lt;/code&gt; class. I may be an old &lt;a href="http://www.phrases.org.uk/meanings/fuddy-duddy.html"&gt;fuddy-duddy&lt;/a&gt;, but I can't quite understand what advantage &lt;code&gt;Task&lt;/code&gt; gives me over plain old ThreadPool in .NET 2.0. Here are some examples of how the Tasks "features" would be implemented using ThreadPool. &lt;/p&gt;

&lt;h3&gt;Starting a task&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Waiting for a task to complete&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var handle = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();
    handle.Set();
});
handle.WaitOne();
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Returning&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;int result = 0;

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();

    result = 42;

    handle.Set();
});
handle.WaitOne();

Console.WriteLine(result);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Chaining tasks&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var handle = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();
    handle.Set();
});
handle.WaitOne();

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeMoreWork();
    handle.Set();
});
handle.WaitOne();
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Waiting for multiple tasks to complete&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var handle1 = new ManualResetEvent(false);
var handle2 = new ManualResetEvent(false);

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();
    handle1.Set();
});

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeMoreWork();
    handle2.Set();
});

WaitHandle.WaitAll(new WaitHandle[] { handle1, handle2 });
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Exception handling&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var handle = new ManualResetEvent(false);

Exception error = null;
ThreadPool.QueueUserWorkItem(delegate
{
    try
    {
        DoSomeWork();
    }
    catch (Exception ex)
    {
        error = ex;
    }
    finally
    {
        handle.Set();
    }
});

handle.WaitOne();

if (error != null)
    Console.WriteLine("Error! " + error);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Word of caution: you should probably always do this when using ThreadPool, since exceptions thrown on a ThreadPool thread will tear down the AppDomain if not caught&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Cancellation&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var cancel = false;

ThreadPool.QueueUserWorkItem(delegate
{
    while (!cancel)
    {
        Thread.Sleep(100);
    }
});

cancel = true;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: this is like a gazillion times more complex in Tasks&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Dispatching to UI thread&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;var dispatcher = Application.Current.Dispatcher;

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();

    dispatcher.BeginInvoke(new Action(() =&amp;gt; progressBar.Value += 10));

    DoSomeMoreWork();

    dispatcher.BeginInvoke(new Action(() =&amp;gt; progressBar.Value += 10));
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Being notified when a task is complete without blocking&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Action&amp;lt;int&amp;gt; done = (int x) =&amp;gt; Console.WriteLine(&amp;quot;Done! &amp;quot; + x);

ThreadPool.QueueUserWorkItem(delegate
{
    DoSomeWork();

    done(42);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So help me learn the &lt;code&gt;Task&lt;/code&gt; API - how would using &lt;code&gt;Task&lt;/code&gt; make the examples above look better?&lt;/p&gt;
&lt;img src="http://www.paulstovell.com/via-feed/threadpool-vs-tasks"&gt;</description></item></channel></rss>

