Sunday, March 29, 2009

Crayon Physics is Phun

imageI recently bought a refurb iPhone and have been enjoying thumbing through the app store and trying apps. Being a cheapskate, I rarely purchase any - opting for the free stuff out there instead.  But I did splurge $5.99 recently to download the gem Crayon Physics, and have enjoyed it's casual nerdy style.  The premise is simple: get the star with the ball by drawing on the screen.  The first few levels introduce you to gameplay: You can draw closed or open shapes, little hinges and even ropes, which the game animates with realistic physics.   You can build up cranes, levers, catapults, or other contraptions, and no level has one "right" solution. Each level gets progressively harder, though none so far are so difficult I'd want to throw my iPhone at the wall.   A level editor lets you create and play your own levels.

The game is a port of a full windows game that won accolades at the Independent Game Festival last year.  I haven't shelled out the $20 for that version, but the demo was enjoyable- I'm holding out for the next batch of multitouch tablet PCs, which would be perfect for this sort of game.

Wednesday, March 25, 2009

One Thing I Still Don't Get About MVC

I've been using the new ASP.NET MVC framework lately, and loving it.  The app has cleaner markup and clear separation of concerns, and the various 'conventions' have let me focus on the business logic and UI.  But one thing still sort of bugs me about it, and that's the "ASP.NET" part.   One of the raison d'être of separation of concerns is to be able to reuse code as much as possible - Don't Repeat Yourself (DRY).  If my business logic is UI-agnostic, I should be able to easily reuse it in other UIs.  Yet for ASP.NET, controllers are still very UI-aware.  Sure, you can abstract the HttpContext away for unit testing, but it's still there, and thus the controller is not reusable in a WPF/WinForms scenario. 

In thinking this through, I began to suspect I was missing something vital.  Maybe I misunderstand SoC or DRY or MVC in general.  So I asked over on Stack Overflow, and the answers helped clarify some of the reasons ASP.NET MVC is not ".NET MVC".   First, the reality is some things are always going to be different between Web and Desktop.  Eduardo Molteni writes:

I have to say the the MVC model is specially practical in web apps, and that's because the view (the html page) is really disconnected and far away from the controler and the model. In desktop apps, that is not the case, and you will be soon missing some opportunities the break the pattern to make the app more useful. For example, you can't do the powerful and time-saver databinding in WPF, because it breaks the MVC pattern.

And user Ash makes the point:

If they had created a more general ".NET MVC" framework I would expect it would require a much more difficult trade-off between the needs of web applications versus desktop applications.

So, in a sense, re-usable controllers is pie-in-the-sky, ivory tower architecture.  Maybe possible, but given the two distinct natures of web and desktop apps, not always practical.  That's not to say ASP.NET MVC falls short.  Testability is one clear reason to keep controller logic and views separate.  Also I've found having a clear place for each concern to live helps me think about what is business logic, versus what is UI.  In the end, a little voice still tells me my code should be more reusable - perhaps by moving some logic out of the controllers and into reusable services- but I see now that's not always desirable or practical.

Tuesday, March 24, 2009

Finally, Easy Documentation is Back!

image Ages ago, NDoc- a jDoc clone- was the best free .NET documentation-generating application in town.  For various reasons, that project shut down, and Microsoft released it's internal documenting system, Sandcastle, to the public.  However Sandcastle by itself is non-trivial to understand and implement.  It's designed to gen up the entire MSDN documentation site, so it can be overwhelming for creating docs for your small line-of-business app.

Enter Sandcastle Help File Builder.  This gem brings back the simplicity and open source spirit of NDoc, and adds some functionality from Sandcastle to provide a great documenting solution for small or large projects. I'd checked it out in earlier versions, but it's come a long way. It even has a console app, which can easily be integrated into your continuous integration process.   In addition, you can add documents other than the typical xml-doc and build a true compiled help that a developer may actually use.

Here's how we set ours up:

  • A solution has a _FileReferences project for file-based dll references and other non-compiled code.  (Build is false for all Build configurations).  This project contains:
    • a Help folder that  contains .htm files and the compiled .chm file
    • a .shfbproj file that manages the documentation project.
  • In the .shfbproj:
    • A site map has been added to build the table of contents.  It has nodes pointing to each .htm file.
    • The solutions' projects have been added as Documentation Sources.
  • An automated process downloads the solution from source control, checks out the .shfbproj and .chm, runs the console app to generate a new .chm, and checks everything back in.

This way, the documentation is constantly updated and available in source control alongside the project!

Share this post :

Monday, March 23, 2009

An Active Directory Role Provider That Works

Most of our web apps to date have used SqlMembershipProvider and SqlRoleProvider, however a recent app had a need for ActiveDirectoryMembershipProvider.  The client wanted to authenticate against AD, but also wanted to allow users to sign out of the app, or allow different users to log in.

Setting the Membership provider up is fairly trivial, but the Role Provider is a little counter-intuitive.  First, there's no "ADRoleProvider".  AuthorizationStoreRoleProvider is supposed to work with AD, as is WindowsTokenRoleProvider, but each had some unique errors.  I'm a little fuzzy on exactly why the errors occurred, but both seemed to be assuming the current process's principal would be a WindowsPrincipal - in other words, they assumed we'd be using Windows authentication, not forms. 

After some digging, I decided a custom ADRoleProvider was in order.  After trying a few, this was the only one that allowed specifying credentials, similar to the way the AD Membership Provider works:  http://slalomdev.blogspot.com/2008/08/active-directory-role-provider.html

Usage was trivial - just cut-and-paste the class, then add to web config with the same connection info as the Membership Provider, and everything Just Worked.  I do have a nagging suspicion that MS didn't _want_ role provider to work this way, possibly due to security or performance concerns, but we'll see.

Wednesday, March 18, 2009

Cool Stuff from Mix09

Mix09 is happening this week.  This is one of Microsoft's larger developers conferences and sure to drop a few new tools, features, and plans.  Below are some cool new technologies I'm watching.  This post will be updated as I hear about interesting news, so check back from time to time.

  • Of course, as already mentioned, MVC v1 is now live!
  • Expression Web SuperPreview - effortlessly test browser compatibility in Expression Web.  I hope we get this for Visual Studio soon!
  • Silverlight 3 Beta 1 - Hardware GPU acceleration. New codecs, including AAC. Write your own codecs. IIS Media Services - static and LIVE streaming video support easily installed from Web Platform Installer (see below).  3D perspective support for any control.  Improved fonts.  Multitouch support. Support for running outside-of-browser on Windows and Mac in secure sandbox, with offline-awareness and automatic updates.  New Eclipse IDE tools for developing on Mac.  The download size - including all these new features - is actually smaller than Silverlight 2 (4.4M)!  Beta today, shipping RTM later this year.
  • Expression Blend 3 - design Silverlight 3 UIs.  Supports the new features, and has "SketchFlow" for sketching prototype page flows, transitions, and layouts, then generating documentation and actual Silverlight code.  Very cool, and also something VS needs!
  • Web Platform Installer and Web App Gallery - Make it easier to install framework and related MS features, plus popular applications that run in IIS.  They just called it "an App Store for the Web Server". Some apps included: DotNetNuke, Umbraco.
  • Azure commercial release this year.  Update this week supports PHP & CGI, has ADO.NET support that works with ADO EF, NHibernate, etc. similar to your traditional MS SQL apps.   It also supports geo-locating your applications and storage to enable edge content delivery, geo-load balancing, and other scenarios.  No pricing released yet. New SDK and Visual Studio Tools CTP available.
  • New Virtual Earth Silverlight SDK.

Session videos are now trickling out, but the mix site is not very user-friendly in helping you find the content.  Nigel has a pretty good list of the available videos.

ASP.NET MVC 1.0 is Live!

I'm sure this will be old news in about an hour, but MVC is now live! Download here.  LifeCycle was an early adopter on this - our first production MVC app was deployed for testing at the client last week. After a little learning curve, the result was a clean separation of concerns and a light, clean standards-compliant web UI, with just enough jQuery goodness. 

Monday, March 16, 2009

RollingBindingList

This is a class I've found handy a couple of times when writing viewers for streaming data.  In these cases, we want a collection that has the following unique behaviors:

  • Items are added to the top of the list.
  • Only N items are allowed in the list at once.
  • Once N items are reached, items are removed from the bottom of the list.
  • Can be databound to a DataGrid and not have to write any special UI code to do the above.

So in TDD fashion, I've written the following tests:

[TestFixture]
   public class RollingBindingListTests
   {
    
       [Test]
       public void Should_Accept_Max_In_Constructor()
       {
           var target = new RollingBindingList<string>(10);
           Assert.AreEqual(10, target.MaximumItemCount);
       }
 
       [Test]
       public void Items_Should_Add_To_Top_Of_List()
       {
           var target = new RollingBindingList<string>(10);
           target.Add("test1");
           target.Add("test2");
           target.Add("test3");
           Assert.AreEqual("test3", target.First());
       }
 
       [Test]
       public void Should_Only_Allow_Max_Items()
       {
           var target = new RollingBindingList<string>(5);
           target.Add("test1");
           target.Add("test2");
           target.Add("test3");
           target.Add("test4");
           target.Add("test5");
           target.Add("test6");
           Assert.AreEqual(5, target.Count());
           Assert.AreEqual("test2", target.Last());
           Assert.AreEqual("test6", target.First());
       }
   }

Which the following class passes:

public class RollingBindingList<T> : BindingList<T>
    {
        public int MaximumItemCount { get; set; }
 
        public RollingBindingList(int maximumItemCount)
        {
            MaximumItemCount = maximumItemCount;
        }
 
        public new void Add(T item)
        {
            this.Insert(0, item);
            if (this.Count > MaximumItemCount) this.RemoveAt(MaximumItemCount);
        }
    }

When bound to a DataGridView, the behavior is as you would expect - items get added to the top, and "fall out" automatically as more are added.  One quirk this brings out in the DataGridView is that it automatically scrolls to the bottom when an item is added or removed.  I'm still looking for a better workaround for this, but the following works with a little bit of flicker:

allEvents = new RollingBindingList<LogEventArgs>(25);
this.dataGridView1.DataSource = allEvents;
//...
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    dataGridView1.FirstDisplayedScrollingRowIndex = 1;
}

Some work remains to be done.  Some thread-safety needs to be added, and default constructors and so on- plus I imagine a little work to make it play well in WPF.  But hopefully this will be useful to you!

Friday, March 6, 2009

Useful Batch File For Generating SQL Create Script from .mdf

Need to generate create scripts for your SQL Express database?  Here's a little batch I've used several times recently to do just that:

@echo off
SET DatabaseFileName=DbName
 
ECHO Generating code for %DatabaseFileName%
ECHO Generating create script 'CreateDatabaseSchema.sql'
 
"C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\SqlPubWiz.exe" script -C "Data Source=.\SQLEXPRESS;AttachDbFilename=%CD%\%DatabaseFileName%.mdf;Integrated Security=True;User Instance=True"  -noschemaqualify -schemaonly -nodropexisting -f CreateDatabaseSchema.sql

To use, just drop in a .bat next to the .mdf, change DbName and run.  It will output 'CreateDatabaseSchema.sql containing create script for all of the tables and stored procs in the database. 

Thursday, March 5, 2009

Lovin' Me Some Evernotes

Any friend of mine knows I'm not the most organized person around.  But periodically I do binge-organize: I throw out everything I haven't used in a year, or clean out my email inbox, or spend a few hours defragging my drives and sorting files on my home pc.  Lately, motivated by baby-room-remodeling, I've been eBaying and craigslisting junk I know I don't need but can't stomach throwing away (and I've made $200 doing it)!  Still if I'm perfectly honest with myself, I'd say I like the idea of organization better than I like being organized

Which is why I'm a little surprised that I'm still using Evernote for Getting Things Done a month later.  If you're not familiar with Evernote, the idea is that it serves as a 'second brain' (no comment on the quality of my first one).  You can put all sorts of information in it: pictures, hand-written notes, typed notes, pdf documents, voice notes, all marked with tags and organized in "notebooks" that you can instantly search. You can use any device to take or search notes: Windows or Mac PC/Laptop, web browser, iPhone, and Windows Phone, and they all sync up effortlessly in the background.  For me, this means that as long as I have my phone or laptop, I can shove stuff into my 'second brain', and get it back out instantly.  Some ways I've used it recently:

  • Started a list of favorite wines and beers
  • Took picture of wine label to add to list later
  • Copied addresses for eBay buyers from my desktop, to have at post office on my phone
  • Took meeting notes
  • Jotted down todo tasks on my phone, did them later on my desktop (and visa versa)
  • Jotted down addresses and phone numbers on my phone to add to contacts later on my laptop (instead of using WiMo's wonky add contact form)
  • Snapped pictures of business cards to add to contacts later
  • Stored usernames and passwords(encrypted) for various sites
  • Used the browser bookmarklet to bookmark sites I want to check or blog about later
  • Added PDFs to share in meetings

image

And really, that's just the tip of the iceburg. GTD recommends developing a 'trusted system' - be it a hipster PDA, Palm Pilot or Franklin organizer to get things out of your brain and into sortable lists.  Evernote has quickly become that 'trusted system' for me.

Now, I say "GTD", but I'd imagine Dave Allen would still laugh at my (lack of) organization.  Here's how I'm using it now:

I have 4 important notebooks in Evernote.  The others you see will probably get lumped to 'Reference' soon- the general idea being that since there is fast tagging and searching, keeping notebooks for everything is just overhead:

  • 1. Inbox
  • 2. Next Actions
  • 3. Later
  • Reference

image The numbering keeps them sorted nicely.  As stuff comes in via email, in-person requests, meetings, wifely honey-dos etc., they go to the inbox.  I can manually enter them on my phone, desktop, or laptop, from another computer via the web interface, or forward email to my Evernote email inbox.  Periodically, I review the inbox:

  • Things that I can do in 5 minutes or less I do and move to trash
  • Things that I want to do very soon go in 'Next Actions'
  • Things that I want to do in the next few days or weeks goes in 'Later'
  • Things I just want to be able to remember go in Reference.
  • Contact information, etc. goes in Outlook and then is moved to the trash.
  • I add tags for various contexts: @Church, @Home, @Work, and for various projects: Acme Co, Baby Room, etc. and for statuses: @Waiting On

As needed, I review the Next Actions notebook:

  • I filter by tag so that, for example, only Home items show up when I'm at home.
  • After I do something, I move it to the trash

Periodically, I review the Later notebook:

  • If I'm ready to start on it, I move it to 'Next Actions'
  • If I decide it's no longer needed, I move it to trash.

There are still some areas I'm fuzzy on - at work, we use FogBugz for managing projects and time.  It works pretty well, and I'm not sure I'd want everything from it in my Evernote.  Still, having two systems seems less than ideal.  Some sort of sync between them would be cool.  Also, I'd like a way to share a list with my wife- shopping lists, honey-do lists, etc.  Currently notebooks are public to everybody or private, so lists among friends, family, and coworkers can only be secured via obscurity.

I've been using this a little over a month, which is about a month longer than I've kept up similar drives in Outlook and other GTD apps.  We'll see if it sticks, but so far I'm enjoying my second brain.

Wednesday, March 4, 2009

AT&T Website Rant

imageWhat online store doesn't allow you to use different shipping and billing addresses when ordering items?  AT&T's!  Just about every online store nowadays accommodates this, which tells me that AT&T is trying really hard to mess up their customer's experience.  This stinks for me, because we use PayTrust, so unless I want my shiny new phone to go to South Dakota, I have to use a different address.  Calling support reveals that they have no way to order the iPhone period, much less to a different address.

  When I first ran into this over two years ago with a Windows phone, there was no explanation on the site.  Now, two years later, developers have thoughtfully addressed this issue with a bright red box with a change address link.  If you follow the link to temporarily change your one and only (calling it a "billing address" would imply some other sort of address were possible) address, then go through the order process, you find at the last step that it's not immediately updated!  Add to this all-around quirky UI and it's all enough to make you wonder how they ever made it beyond rotary phones.