Thursday, October 04, 2012

NuGet Package'N'Publish v0.6.0.1

I've just pushed NuGet.PackageNPublish v0.6.0.1 to NuGet and the Visual Studio Extension Gallery. This is a fix for the borked v0.6.0.0 I rushed out yesterday - it now really does work in VS2010 and VS2012!

Source is on github as ever - https://github.com/JoelHT-Landmark/NuGet-PackageNPublish

What's New?

  • Builds on VS2012
  • Targets VS2012 and VS2010
  • Includes support for both creating and publishing Symbol packages.
  • Packages the package\content folder by default, and includes that folder in the template.
  • Numerous bug fixes to the NuGetPackageAndPublish.targets file.

Want to know more?

Check out the introduction first - but I'm going to follow this post up with a walkthrough of using the tooling later today.

Monday, September 03, 2012

DDD 10 - A retrospective

Developer Developer Developer 10 has now been and gone, and so I'm once again distilling 15+ pages of notes into a summary as both aide-memoire and commentary on what was (once again) an excellent community event.


I arrived bright and early on Saturday morning at Microsoft in Thames Valley Park - for the first time fresh and relaxed after a mere 15 minutes from home. Bliss.

Registration was quick, easy and efficient and it shows the draw of this event that Building 4's reception was pretty full even at 0820. 

After catching up with a few friends and the odd colleague, I headed to the area in front of Chicago 1 and 2 to find food and coffee - the sausage butties going down a treat

Fortified and ready to go, I was briefly distracted by the O'Reilly book stand - and then quickly divested of cash for a couple of books that I just HAD to buy. "Just keep telling yourself, 'Tax Deductable'..." was the mantra for a lot of people around that table, I think!

With the introduction and housekeeping from Phil Winstanley out of the way, including the announcement of DDD Norfolk East Anglia next summer, it was straight into the first session.


Language pattern anti-patterns, aka "C# - the broken bits" - Jon Skeet


Standing room only for Jon Skeet
Jon's session could well have been billed as "Jon Rants At Cr*p Language Design", but his humour and flair made this a must-see - as the standing-room crowd attested to.

The session was thought-provoking in analysing some of the the oddities of C# in the context of more general principles of language design - the two key take-aways being
  • "Language expresses ideas - it is COMMUNICATION.
  • "C# is generally a well-specified language - others are not"

There were also more specific things to take-away from the session to do with the niceties of C# , including an interesting sample demonstrating how picking a different framework version can give radically different behavior due to changes of co-variance for IEnumerable.

The sock-puppet "Tony The Horse", and "Evil Code Hench-Kitty" had to give centre-stage to "Beary Dorans", however - a bear that glared balefully at delegates from the desk in Chicago 1 for the rest of the day.

Next up was a double act...


Stuart and Simon both with with Phil at Microsoft - and it's a somewhat radical departure that Microsofties were allowed to present at a DDD event. That being said, there was no corporate push, nor branding, in what was a very well thought out talk on the "Rules" of writing ASP.Net MVC the right way.
  1. No Business Logic in MVC Controller actions
  2. Maximum of 15 loc per MVC Controller action.
  3. No base controller class
  4. No Javascript (embedded) in C# code 
  5. Always use strongly-typed views
  6. Minimal logic in views - 1 loop, 1 branch
  7. No javascript in views
  8. No base views.
  9. No behavior in ViewModels
I for one agree with every one of these rules - tho' have to admit to have being guilty of implementing code that breaks all of them. The helper classes presented (and linked here) give solutions to aligning your code with the "Rules" and are something I'm going to be investigating.


Raspberry Pi-lovers
Next up was a change of pace - a session that had (almost) nothing to do with .Net or the code I write day-to-day. 

But as my own Pi has been languishing on my desk at home waiting (literally) for a rainy day for myself and my boys to play with it, this was one that was going to get my mind filled with ideas. And this was another session that was rammed to the rafters.

Garry gave a great intro to the little-computer-that-can that is the Raspberry Pi, and showed a demo of a web-app running on Node.JS on the Pi, with C# Mono worker-processes.

During this session, the power of Twitter was demonstrated when my pen ran out of ink. A speculative tweet resulted in Craig Murphy hand-delivering a RedGate pen to me in the middle of Gary's talk - now that's service!

After the usual sandwich/crisps/fruit/chocolate/can'o'drink lunch, which most people were able to enjoy in the sun in the Building 4 amphitheatre, it was on with more hardcore coding stuff.

Performance & Scalability The StackExchange Way - Marc Gravell

Marc presented some of the issues StackExchange had experienced with ASP.Net MVC sites, and looked at ways to investigate and solve performance problems.

The biggest take-away came from the first couple of minutes, and was that


"Adding servers is NOT a silver bullet."

Marc went on to demo MiniProfiler and show how it can help bring to light both rendering and pipeline issues, and SQL issues. MiniProfiler is definitely something I'm going to investigate and integrate with our standard practices.

He also suggested that devs should borrow from CQRS best-practice and implement a KISS approach - using a lightweight "microORM" such as Dapper.NET for reading from a database, and a full-fat ORM (e.g. EntityFramework) for C_UD operations to allow better optimisation of the most common activities.

Next up was something bang-up-to-date

Windows 8 with XAML and C# - Kris Athi

Kris started slowly, but built up to demo'ing the code needed to really make a Windows 8 Metro Modern application shine, including notifications and the five view states that you need to implement.


Dr Who Cupcake - Nom!
After the final break - with delicious Dr Who cupcakes care of Gibraltar Software, it was the turn of the ineffable Mark Rendle.

Simple.Web 101 - Mark Rendle

Mark was introducing his Simple.Web framework - a kind of "little brother" to Nancy that is even more pragmatic - making RESTful services a doddle.

There were a couple of head-scratching moments as he described the framework, but it's clearly a powerful little beast, and would probably have been a better choice then NancyFx for me in the last month or so had it been properly available. Another one to investigate.

Mark did have to suffer heckling on voxpop.at during his session (that'll teach him to put it on screen), including an atack of Rainbow Ponies (you had to be there!) - but it was all good natured and nicely punctuated the session.


Finally it was time to head outside into the amphitheatre for the traditional swag-out.

Nothing for me in any of the raffles, but others went away with books, ebook vouchers, RedGate stuff and one lucky punter even got a soon-to-be-obsolete-when-Windows-Phone-8-RTMs Nokia Lumia 800 running Windows Phone 7.5! 

But many still wondered why Microsoft didn't want to shift more swag after it's recent re-branding. 

All in all, it was another definite win for the DDD team. Slick organisation, great sessions, and a great community spirit - roll on DDD11.

The DDD 10 Team Swagging Out

Monday, June 11, 2012

Developer Developer Developer South West 4.0 - A Retrospective

I'm rather late to the party with this post - Chris Alcock posted his round-up of DDDSW4 links over the weekend. But for my own recollection this post is probably a good idea.

This was my third DDDSW event - but this time was different - I was a speaker not just a delegate.


6:31 AM - 26 May 12 - Half-way around.
The location in Bristol works for me as it's my old stomping ground from University - I studied Computing for Real-Time Systems at UWE under Rob Williams


It was a toss-up whether I should go to the Friday speaker dinner or catch up with old friends instead - getting together with the old gang won out, but it was probably for the best it wasn't a 3am finish as has happened in previous years! Still, it's a testament to the friendships that you can create in a small startup that two friends I'd not seen in over a decade joined the usual suspects - and that it felt like we still used to hang out every day.


So Saturday dawned with an early start and a 5km run to wake me up and set me up for the day (10km if you believe RunKeeper - I don't!).


Then off to UWE to check in, just in time for the Speakers' briefing - this might have been intimidating for new speakers but for Guy's delivery which was just the right balance of "check it, check it, check it again" and humour - especially at that early hour.


I think as a delegate whilst you appreciate the some effort that goes into making DDDSW work, I for one had very little idea about just how much required to herd speakers to the right place, get swag organised, manage the rooms, etc. Guy Smith-Ferrier and the team do an amazing job.


So after the speaker's briefing I wandered off to what was to be "my" room for the pretty much the whole day. I was speaking in Track 4 in 2Q43 and didn't want to risk not being prepared, so the first order of the day was to check projector connections and ensure my laptop was ready for action. 


Session 1 - "What's new in Entity Framework v5 (beta 1)" - Geff Lombardi

First up on Track 4 was Geff Lombardi, talking on "What's new in Entity Framework v5 (beta 1)". Geff's talk had a good balance of slides and coding (i.e. not too many of the former), and demo'd the new DB migrations features of EF. I'm not quite sure I've got my head around it, or how (or if) I can apply it to my codebase, but Spatial and Enum support will be the first things I'll play with, closely followed by the EF Power Tools.

All good stuff, but I'll admit my mind was really on the next session - mine! So after Geff finished I set up - doing a quick run-through of my slide deck and pre-loading the IIS apps I was going to demontsrate. As the room filled up the nerves really kicked in - and then we were off. 


Session 2 - "Using your NuGet for Fun & Profit" - Joel Hammond-Turner

For any new speaker I can only recommend practice, practice, practice. I'd run my talk no less than 5 times for my colleagues at work, so it was no surprise that the contingent from Landmark that came to DDDSW4 didn't want to come see it again. But practicing on them paid off when speaking in front of the DDDSW delegates - I soon forgot my nerves and cracked on.

I covered the background to our use of NuGet within Landmark, and the challenges we had had to overcome in packaging our internal libraries as NuGet packages - and then demo'd the NuGet.PackageNPublish tooling we'd developed. There was a nice ripple of appreciation when I pointed out that in the time it took to describe how the tooling worked (about 60 seconds), I'd created a packaging project.

Then I covered the options for hosting private NuGet feeds, including file-shares, NuGet.Server, NuGet.Gallery and the two commercial offerings - and had the fact that I'd missed TeamCity's new NuGet functionality!

Questions were asked and answered and towards the end of the session, we were having more of a round-table discussion than a presentation, with Mike Ackah and John Stovin in particular deep in the fray (and winning swag for their contributions).

I finished off with a quick refresher on the HanselFix for when NuGet.org goes down and announced that the NiGet.PackageNPublish tooling had been released as open source under the Apache 2.0 License by my company, Landmark.

Open-sourcing the tooling drew a round of applause that made the whole exercise in getting my session together worth it - it's been a good couple of months' work getting all the clearances and publishing everything. 


Once I was finished and cleared away I looked at the agenda for the first time to see what to go to next - and my first choice was in 2Q43 again. I felt like I was going to be living in that room for the day!


Session 3 - "Unit testing with Visual Studio 11 Beta" - Richard Fennell

Richard is always an excellent speaker, and this session was no exception, covering the new test runner, the always-on tests (very like NCrunch), and the multiple test runner plug-ins. This latter I would say is probably the stand-out feature - the ability to use the test and mocking framework combination best suited to your testing needs will I'm sure only reduce the friction when unit tests aren't quite first-class citizens in the development process (i.e. you're not doing pure TDD).

Next was lunch time - and the DDDSW team did us proud with a choice of sandwiches, crisps, cake, fruit... and hot pasties! Distinctly NOM time. Catching up with my Landmark colleagues outside by the pond, it was clear that all the other sessions that morning had been as good as the ones I'd been to, and it was on recommendation that I went to my next session


Session 4 - "WebSockets and SignalR" - Chris Alcock

Chris obviously made a good impression on his first go, because his repeat track room was absolutely rammed - all the chairs and all the tables along the back were full, and people were hanging in through the doorway to listen in.

Chris gave a great introduction to WebSockets and contrasted that low-level javascript technology with the "nicer" abstraction offered by SignalR. Talking about this with someone else later on, his use of a sample OTHER than the traditional text chat was a big win. For me (and many others, I'd imagine) the possibilities of calling client methods from the server and vice versa through one service API (SignalR) are endless and exciting - and Chris' demo really peaked my interest.

After Chris's session it was time for one of the regular highlights of the DDDSW experience - the cream tea. The food queue always seems to be an interesting experience - this time running into Johnno Nolan, Mark Kirschstein, and others from the Manchester NxtGen crowd. The one problem with any DDD event seems that there's never enough time to catch up with everyone you want to. I even "dissed" my Landmark colleagues and caught up with Chris Alcock & Dave Sussman in the Speakers Lounge. It was slightly surreal sitting there, not as a delegate wanting to dig for more information but as a speaker just shooting the breeze.

Session 5 - N/A

Yep - I never made it to any of the last sessions of the day... Setting the speaker world to rights with Chris & Dave (there's a Rockney band in there somewhere!) just rolled on into Session 5 - and after about 20 minutes in the heat of the Q-Block rooms forced me outside for only the second real bout of fresh air of the day.


I made it back in for the Close and Prize Draw - getting all 300(ish) delegates into that one room at the end really pressed home what a great event Developer Developer Developer South West is. I missed the geek dinner that night too - rescuing my wife from our children being the greater priority - but still came away with memories of a great day of geekery.


And finally...

I've got to thank the audience for my first-ever DDD session - they were very gentle with me - and from the feedback I received I'm pretty damned happy, averaging 8.0 for subject knowledge and 7.32 for presentation skills. And I know exactly how I'm going to improve and update my NuGet session if it get's chosen for DDD 10 in Reading in September! That one I'm NOT going to miss the speaker or geek dinners, either!

My company, Landmark, deserves thanks too, for sponsoring me and open-sourcing the NuGet.PackageNPublish tooling - giving me a great big comfort-blanket of support.

Even though none of my colleagues came to heckle me!


Thursday, May 03, 2012

Thursday Quickie - Lightswitch Build Issues #2 - XAP Signing

Update: 2015-05-20 - No idea why I never published this Quickie! Three years is way too long for a blog post to languish in the Drafts folder!

Wednesday, May 02, 2012

Wednesday Quickie - Getting rid of those darned connection string parameters

This quickie relates to the parameters used by MSDeploy to transform your web.config when a web application or site is deployed.

By default the deployment targets (Microsoft.Web.Publishing.targets) used when building a deployment package for a web app will automatically generate entries for connection strings. The problem is that it chooses really awful tag names for the parameters - for example:






This gave me a problem as the configuration system we use at Landmark to deploy our web apps can't have any spaces in its parameter tags. Fortunately, there's a quick solution.


It's easy enough to add a Parameters.xml file to your project to provide custom parameters - and in that file it's trivial to include a duplicate connection string parameter definition (that doesn't have spaces in the name).


The final part of the puzzle is to prevent the deployment targets from creating the default connection string entries on build. This is achieved by passing in the following (memorably-named) MSBuild parameter:
/parameter:AutoParameterizationWebConfigConnectionStrings=False
The deployment targets no longer add the connection string parameters by default, so you have to do so explicitly in your Parameters.xml file - but now YOU control the parameter name. Done.



Wednesday, April 25, 2012

Wednesday Quickie - Building Lightswitch Projects in TFS

So I've been fighting with getting my Lightswitch application to build under TFS as part of our (slow) move towards Continuous Build / Continuous Deployment at work... and for weeks I've been banging my head against the wall with the deaded "UnpackExtensionsToProjectDir" error.

And then came the revelation... looking a couple of lines down I found that the real error was being masked - looking at the detailed logs we can see the real culprit:


C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\LightSwitch\v1.0\Microsoft.LightSwitch.targets(1257,9): error MSB4018: The "UnpackExtensionsToProjectDir" task failed unexpectedly.
<SNIP>
[C:\Builds\4\MyApp\Trunk\Sources\Authentication\MyApp.LightswitchApp\MyApp.LightswitchApp.lsproj]C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\LightSwitch\v1.0\Microsoft.LightSwitch.targets(1257,9): error MSB4018:    at Microsoft.LightSwitch.ExtensionsReader.ExtensionInformationService.ExtensionInformation.LSPKGPackage.ExtensionDirectoryDeletionFailedAction(IServiceProvider serviceProvider, String directory) [C:\Builds\4\MyApp\Trunk\Sources\Authentication\MyApp.LightswitchApp\MyApp.LightswitchApp.lsproj]
<SNIP> 
[C:\Builds\4\MyApp\Trunk\Sources\Authentication\MyApp.LightswitchApp\MyApp.LightswitchApp.lsproj]Done Building Project "C:\Builds\4\MyApp\Trunk\Sources\Authentication\MyApp.LightswitchApp\MyApp.LightswitchApp.lsproj" (default targets) -- FAILED.Done Building Project "C:\Builds\4\MyApp\Trunk\Sources\Authentication\MyApp.LightswitchApp\MyApp.LightswitchApp.lsproj.metaproj" (default targets) -- FAILED.
By looking at the Microsoft.Lightswitch.targets file, I found that the actual error was that the build process couldn't delete the _Pvt_Extensions directory.


A quick check showed that that particular directory had been added to TFS source control - removing it and the deaded "UnpackExtensionsToProjectDir" error was finally vanquished. (OK - there were a couple of other build errors, but they were easily fixed).

So now I have a green tick beside my Lightswitch application in TFS Build Explorer - WIN!

Tomorrow, my next challenge - getting the thing packaged for MSDeploy deployment.

Thursday, March 15, 2012

Fixing CornerRadius in Silverlight

OK - I know I've not posted in nearly a year... but this time I'm covering one of those "why the frack does it work like that" issues with Silverlight 4.

I hit this one today - I wanted to unify the radii of corners within a Silverlight application to replace the random set of radii used (1, 2, 4, 5, 8, 10, 12, 15 and 20 pixels no less) with a simpler set - small, medium, large and massive.

The problem is that (for whatever reason), the developers of Silverlight decided that we didn't need to be able to create CornerRadius objects in our ResourceDictionaries. Or rather that we could TRY, but that the XAML Loader was never told how to deal with them. Even though the design surfaces in Visual Studio and Expression Blend can quite happily deal with this!

So if you *DO* try then you either get an error saying that you can't set the readonly TopLeft property of a CornerRadius, or if, like me, you do this in your theme.xaml you just get a catastrophic error - somewhere in your project.

So what was the solution?

Well, there was a very good answer to exactly this on Stack Overflow - using a Value Converter to read named resource values from the object for which we want to set the CornerRadius... But I suddenly realised that there was no need to have a "magic string" as keys for the TopLeft etc values - we can just use properties on the value converter ITSELF!

The result is a pretty elegant way to get around a limitation of Silverlight, thus:


<Border x:Name="buttonBorder">

<Border.CornerRadius>

<Binding ElementName="buttonBorder">

<Binding.Converter>

<Converters:DynamicCornerRadiusConverter TopLeft="{StaticResource massiveCornerRadiusValue}"

TopRight="{StaticResource massiveCornerRadiusValue}"

BottomRight="{StaticResource massiveCornerRadiusValue}"

BottomLeft="0.0" />

Binding.Converter>

Binding>

Border.CornerRadius>

Border>


Not quite as simple as defining a CornerRadius in a ResourceDictionary, but not bad at all - and certainly it allowed me to do what I wanted - to rationalise my myriad of Radii!

And here's the code:

namespace CheviotConsulting.Common.Silverlight.Converters
{
    using System.Windows;
    using System.Windows.Data;
 
    /// 
    /// Exposes a CornerRadius instance configured for a ValuationProgressButton
    /// 
    public class DynamicCornerRadiusConverter : IValueConverter
    {
        /// 
        /// Gets or sets the top left.
        /// 
        /// The top left.
        public double TopLeft { get; set; }
 
        /// 
        /// Gets or sets the top right.
        /// 
        /// The top right.
        public double TopRight { get; set; }
 
        /// 
        /// Gets or sets the bottom left.
        /// 
        /// The bottom left.
        public double BottomLeft { get; set; }
 
        /// 
        /// Gets or sets the bottom right.
        /// 
        /// The bottom right.
        public double BottomRight { get; set; }
 
        /// 
        /// Gets the corner radius.
        /// 
        /// The resource source.
        /// the corner radius
        private CornerRadius GetCornerRadius(FrameworkElement resourceSource)
        {
            var result = new CornerRadius(this.TopLeft, this.TopRight, this.BottomRight, this.BottomLeft);
            return result;
        }
 
        /// 
        /// Modifies the source data before passing it to the target for display in the UI.
        /// 
        /// The source data being passed to the target.
        /// The  of data expected by the target dependency property.
        /// An optional parameter to be used in the converter logic.
        /// The culture of the conversion.
        /// 
        /// The value to be passed to the target dependency property.
        /// 
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return this.GetCornerRadius(value as FrameworkElement);
        }
 
        /// 
        /// Modifies the target data before passing it to the source object.  This method is called only in cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings.
        /// 
        /// The target data being passed to the source.
        /// The  of data expected by the source object.
        /// An optional parameter to be used in the converter logic.
        /// The culture of the conversion.
        /// 
        /// The value to be passed to the source object.
        /// 
        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
    }
}