My Talk at BarCamp San Diego: How to Create Applications People Love

11. July 2010

I showed up at BarCamp7 this morning and saw that absolutely no presentations were up on the board whatsoever, so me being me I spent most of the day putting together a presentation at the last minute.

I spoke for an hour about How to Design Applications People Love. I’ll add more to this post later after I decompress with some TV, but here’s my PowerPoint:

All in all, it turned out really well – I’ll try to update this post with some more detail tomorrow.

Update 7/13/2010

Ok, here’s the run-down of my talk:

  1. We all begin with ideas for new applications or products, but in order to determine if it’s worth actually pursuing any given idea we have to determine who the product’s core user group actually is and whether or not they’d actually use it enough to merit its production.
  2. We begin this determination using “the onion process,” a name I invented on Sunday morning, which elegantly formalizes the process I’ve been using for my latest group of projects.
  3. During our execution of the onion process, we inevitably make a number of assumptions about our application / product’s users – therefore we have to map out those assumptions explicitly so we can systematically test them when we start our customer / user engagement process. I find that it’s best to use a mind map for this, but a simple outline can work too.
  4. Once we have our assumptions outlined, we have to test them by interviewing potential users and determine if and where we are on/off-target.
  5. Let the process of churning begin.

If you enjoyed this post, remember to subscribe to my RSS feed!

General , , ,

BlogEngine.NET Extension: Footnotes

6. July 2010

I finished this extension up last night but I was reluctant to deploy it to my own blog given that there was a major flamewar in progress on my recent post about Why .NET Adoption Lags Among Startups. Having actually tested this extension on that very post, I feel confident sharing my latest BlogEngine.NET extension with you: Footnotes!1

Once you've installed it, all you have to do to add a footnote is to click on the new "footnote" button visible on your TinyMCE text editor:

Once you click it you'll see a pop-up window - just type in whatever you want2 to include in your footnote (no special syntax required) and it'll automatically be inserted into your blog entry.

And this is what your footnote will look like once it gets rendered by the plugin: 

That's it. Pretty simple, no?

Modifying Footnote Styles

If you need to modify the default styles for your footnotes3, you can do so by modifying User controls/footnotes/be-footnotes.css.

Alternatively, you can also specify your own stylesheet location for footnotes if you wish via the Extension's settings:

Installation Instructions

The only special instructions for installing Footnotes for BlogEngine.NET are thus:

  1. If you are already using the SyntaxHighlighter extension for BlogEngine.NET, make sure you grab the Footnotes 1.0 (SyntaxHighlighter) download below instead of the normal one - otherwise his handy TinyMCE plugin will disappear from your text editor!
  2. If you do not have SyntaxHighlighter installed, grab the Footnotes 1.0 (Normal) version below - otherwise you might get an annoying JavaScript error every time you load up TinyMCE.

For both versions of BlogEngine.NET Footnotes: simply extract the folders onto the root of your blog and everything will slip into its appropriate place.

Downloads

Footnotes 1.1 (SyntaxHighlighter).zip (7.59 kb) New

Footnotes 1.1 (Normal).zip (7.59 kb) New

If you run into any problems with Footnotes, please leave a comment on this page and I will respond as quickly as possible.

Update:

Whoops! Fixed a bug which prevented BE.NET's syndication feed from displaying properly. This has now been fixed in the 1.1 release of Footnotes.


1A lot of credit is due to Ruslan Tur for his awesome blog post on How to Create a Custom Plugin for TinyMCE. I used his code as a basis for developing my own plugin and he's quite masterful with both C# and JavaScript.

2Actually, not WHATEVER you want. The only character to avoid is either of the square brackets since the extension will think you're trying to close the footnote.

3I had to modify the default styles for footnotes for my own theme here - mostly I just had to do some tweaking in order to make the footnotes appropriately smaller than my posts' body text styles.

If you enjoyed this post, remember to subscribe to my RSS feed!

BlogEngine.NET ,

.NET Culture Shock: Why .NET Adoption Lags Among Startups

3. July 2010

One of the other things I took away from Code Camp was a bit of .NET culture shock. As you can tell by glimpsing around on this blog, I am somewhat enamored with the idea of starting my own business. I’m a natural entrepreneur and it is my wont to think about startups constantly.

That being said, I’ve always wondered why a platform as widely adopted and supported as .NET isn’t more visible in startup culture. Many major open source  platforms and languages have very visible and vocal presences in the startup community, everything from mainstays like Python and PHP to even the more obscure and specialized ones like Clojure and Hadoop.

.NET on the other hand is conspicuously absent from the startup conversation despite the fact that it is a singularly larger platform than any of the others.

It’s like there’s a silent majority among the development community that just tinkers away on its own projects without even occasionally raising its hands and saying “here’s something clever and unique we did with this platform that no one else has done before.”

It’s somewhat tragic for the .NET community too – because the perceived lack of sex-appeal on the surface doesn’t match the reality of what the platform is capable of.

Just take a brief moment to peruse through CodePlex for more than a couple minutes and you’ll find thousands upon thousands of examples creative open source projects all built in .NET.

And in the startup space there actually are a number of .NET-based startups making it big, including this week’s Hacker News / Social Media darling Woot. But why oh why isn’t there a louder .NET voice in the startup community? Why aren’t there developers from Woot working with developers from StackOverFlow (also implemented in .NET) to encourage more startups to use the extensive .NET stack to create new and exciting products and services?

And most importantly, why aren’t there more startups adopting .NET?

It’s All about the Enterprise

I’ve heard all sorts of lame answers to this question before: “platform lock-in,” “no open standards,” “licensing costs,” and none of them pass the test of objective reality – yes, those are issues that might prevent some developers from adopting .NET in the startup space, but not enough to bar virtually all of them from using .NET, arguably the most comprehensive and versatile platform with the best tools and the best support.1

At Code Camp I think I finally figured out why this is: it’s the culture of the .NET community itself, not anything specific to the platform or the architecture which supports it.

.NET culture is centered around the concerns of  the enterprise – the large already-established businesses in the economy, not plucky up-and-coming startups. The Promotion PitAnd when I say “culture,” I’m not talking about the development tools – I’m talking about where the hearts and minds of the developers who use the .NET platform are. I’m talking about the blogs and media sources .NET developers read. I’m talking about the networks where .NET developers contribute and the substance of their conversations.

Most of the developers I met developed portals for giant healthcare providers with thousands of employees, worked on legacy code whose lifespan could be measured in decades, worked in teams with hundreds and even thousands of programmers, and lived in ecosystems ruled by large bureaucracies. These are problems to which few if any developers for startups can relate.

That’s why so many of the talks at Code Camp were staked around RAD methodologies for developing internal projects, coding standards, enterprise architecture, and other things that matter to developers who work in giant ecosystems.

And who can blame Microsoft for catering to the enterprise market – that’s where the money is! No one ever became rich selling high-end development tools to a handful of capital-starved, small companies.

However, the consequences of the .NET community’s enterprise-centric culture is that the startup community and the .NET community don’t overlap as much as they do for other technologies.

As a result, developers working for startups and even the startup founders themselves don’t get much exposure to .NET and don’t think of it as an applicable tool for their purposes.

The flipside is that many .NET developers who want to work for hot startups don’t have as many opportunities to do so unless they abandon the platform for a more “startup-friendly” one or start a company themselves.

So what do the members of the .NET community fuss over? They worry about supporting legacy systems, building enterprise architectures which can service multiple departments, they worry about large systems for supporting in-house business processes, and they worry about satisfying the needs of stakeholders throughout their companies.

.NET developers in general, worry about architecture in order to support systems.

Members of the startup community fuss over a very different set of issues – they’re their own stakeholders, they worry about concurrency, they worry about scalability, they worry about user experience design, they worry about supporting multiple clients and browsers, and they worry about how their designs will impact their bottom line.

Startup developers in general, worry about architecture in order to support products.

See the difference? .NET is perfectly capable of fulfilling the needs of product designers and startups, but comparatively little2 of the .NET culture, literature, and conversation is product-centric – instead the majority of it is structured around using .NET to support the needs of the business, not building the business’ products itself!

But It Doesn’t Have to Be

One thing that should be clear here is that any platform, not just .NET, can be used as a platform for building enterprise technology and for building new products. The platforms don’t often dictate their use – that’s the work of the people who develop on them.

If Microsoft wants to make a splash in the startup scene with .NET, and I have every reason to believe they do, then they need to do a better job evangelizing .NET’s capacity from a holistic new service / new product / new business perspective and not just for the enterprise.

Enterprise and startups aren’t mutually exclusive – they’re just different stages in the evolution of software, and there’s no reason why the startup community shouldn’t look at .NET as an attractive starting point for a new business.

The next article I’m going to write on this subject will cover why it’s a good idea for Microsoft to have .NET adopted more readily by the startup community.


1I realize “best” is a subjective term, but please do your best to just stick with me here. I’m not trying to trash Eclipse, XCode, NetBeans, or EMACS, but just face it: Visual Studio destroys those in any feature set-to-feature set comparison.

2Again, this is an observation based on my experience with the .NET community thus far. I'm always on the lookout for any exposure to people who use .NET in a startup setting.

If you enjoyed this post, remember to subscribe to my RSS feed!

.NET, Startup , ,

Lessons from Code Camp 2010

3. July 2010

This time last weekend I was in the middle of the second session of Southern California Code Camp. Ever since I came to the realization that no man is an island and I’m going to ultimately need to work with other programmers in order to be successful in this business, I’ve made an effort to attend as many geeky networking events as I can.

Code Camp was a fantastic learning experience for someone who’s as interested in the .NET platform as I am. During Code Camp I was introduced to:

  • Silverlight 4;
  • Silverlight for Windows Mobile Phone 7;
  • ASP.NET MVC2, which I used this past week to build The Great Wall of Geeks;
  • .NET 4.0 multithreading (Parallel.For, Task engine etc…);
  • .NET coding standards; and
  • Agile Development and working with legacy code.

By far and away the best session for me was the Pair Programming / Agile Development Dojo, namely because I got my first taste for Agile development and the inherent value of rapid prototyping and test driven development was obvious.

More...

General ,

Announcing the Release of Quick and Dirty Feed Parser

30. June 2010

Alternate headline: "never see XML again."

Ok, that may be a bit of a stretch. Regardless, I'm quite pleased to announce the launch of Quick and Dirty Feed Parser, a library for people who want a seamless way to use Atom and RSS feeds in their .NET 2.0+ applications without having to deal with the XML.

"Does the world really need another RSS/Atom parser," you ask? I'll let my source code speak for itself:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QDFeedParser;

namespace QDFeedParserCMD
{
    class Program
    {
        private static readonly string DefaultFeedUri = "http://www.aaronstannard.com/syndication.axd";

        static void Main(string[] args)
        {
            try
            {
                string strFeedUri = args.Length == 0 ? DefaultFeedUri 
                    : args[0];

                Uri feeduri = new Uri(strFeedUri);
                IFeedFactory factory = new HttpFeedFactory();
                IFeed feed = factory.CreateFeed(feeduri);

                foreach(var feedItem in feed.Items)
                {
                    Console.WriteLine("{0} {1}", feedItem.DatePublished,
                        feedItem.Title);
                    Console.WriteLine(feedItem.Link);
                }
                //Just to prevent the window from instantly bailing out.
                Console.ReadKey(); 
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception: {0}", ex);
            }

        }
    }
}

That's about as complicated as it gets, folks. And feel free to download this QDFeedParser example from CodePlex

I wrote Quick and Dirty Feed Parser largely because I wanted to incorporate a really straightforward RSS/Atom parsing tool into a number of BlogEngine.NET modifications I have in mind in the near future, and I wanted a standard interface for dealing with RSS/Atom feeds that was available to me in .NET 2.0.

Quick and Dirty Feed Parser is my first OSS project so I would love your feedback, contributions, and most awesomely - examples of it actually being used! Check out the QDFeedParser project on CodePlex if you want to get involved!

QD Feed Parser in Action - The Great Wall of Geeks

No project worth it's salt would be complete without some sort of frivolous example, right? Well that's exactly why I created The Great Wall of Geeks.

Feel like your geeky blog belongs on the wall? Leave a comment below!

If you enjoyed this post, remember to subscribe to my RSS feed!

.NET, QDFeedParser , , ,

Learning When It's Time to Walk Away from a Project

25. June 2010

I wanted to take the time to follow up on some of the additional lessons I learned from my May startup project, some of which I already shared in The Myth of the Single-Person Startup.

This week I decided to indefinitely postpone my startup project, the same project I spent a month of unpaid leave working on sixteen hours a day. The decision wasn't at all painful, and I came away from it feeling oddly successful and much wiser for it. The project taught me a lot of hard-earned lessons, the kind you only learn experientially, and all it cost me was a couple of paychecks - not bad considering that I don't have any obligations outside of paying my rent on the first of the month at this stage in my life.

But back to the point of this article: learning when it's time to walk away from a project. I have no idea how hard it is for other people to dump something into which they've invested a lot of emotional energy, time, and even money, but for me all it took was recognizing the following things:

  1. The effort needed to actually implement the project's MVP (minimum viable product) grows explosively even though you're not adding any new features or functionality.

    I suspect that anyone who reads this is going to think "well, why don't you reduce the complexity of your MVP then?" to which I reply "the point of an MVP is that that's as simple as it gets - you can't reduce it." Reducing my initial feature set wasn't an option given the competition in my space as it would forgo requiring my product's differentiation - although I had plans for something much more grandiose down the road, my vision of an MVP was assuredly realistic and modest on paper.

    However, when it came time for implementation I came to appreciate just how complicated some of the mundane details of the project truly were. It wasn't over-engineering, it wasn't poor design, and it wasn't any of the usual suspects - it was that I was unable to realize the full scope of the project's complexity without getting into the guts of it.

  2. The competitive space and surrounding ecosystem is changing more rapidly than you can keep pace with.

    My idea (a social media analytics tool for marketers) is in a domain with lots of fast-moving competitors. Although none of the present competitors have built anything that truly captures the value or essence of my idea, they're rolling out innovations and new products at a pace I cannot maintain, and they're better suited than I am to adapt to rapid changes in the surrounding environment, such as Facebook's rapid changes to its APIs.

    I'm a one-man startup trying to compete with well-funded companies in an explosively innovative space - without quitting my day job, finding funding, and building a team, things I'm not suited to do presently, it's a battle that would have been difficult for me to fight.

  3. The technical depth of the product goes beyond your technical expertise.

    This is also called "getting in over your head." As you can probably tell by looking around this website, my real world experience in software development is wanting not for lack of intellectual effort mind you. It's largely because I've been out of a computer science program for two years working full-time as a marketer.

    Nevertheless, I'm enthusiastic about getting back into it and I was excited to take on a big project like this. Unfortunately, I learned quickly that an MVP for a startup is a terrible place to catch up on programming techniques and technologies.

It's was really the combination of all three of these that drove me to ultimately shelve the project, rather than any single one. I'm sure with enough ingenuity and effort one could find the resources and methods to overcome at least one of these problems, but all three at once was too daunting for a young solo entrepreneur who was still working full time.

If you enjoyed this post, remember to subscribe to my RSS feed!

Startup

Programmer's Dilemma: Baby-Proofing vs. Giving Guns to Monkeys

22. June 2010

One of my best friends from college once described a previous job in the financial industry as something akin to "giving guns to monkeys."

He felt that the product he sold, although it was something that could reap tremendous benefits for his customers if used properly, was something that more often than not harmed customers' livelihoods because the tool was too unwieldy and naunced for the average person to use correctly.

Like my friend in the financial industry, programmers are faced with a similar quandry - do we give our users enough rope to potentially hang themselves (more freedom) or do we provide a more authoritarian, constrained, "baby-proofed" experience (less freedom?)

All programmers are UX designers

Giving guns to monkeys and baby-proofing aren't about bugs or errors in the software. The concepts are both about making judgement calls in user experience design, and it's not just the UX gurus who have to worry about this sort of stuff - every programmer does.

Here's a technical example which illustrates my point:

I'm in the midst of creating an open source library for seamlessly parsing RSS/Atom feeds for legacy .NET 2.0-3.5 projects, where we don't have access to .NET 4.0's built in SyndicationFeed classes.

One of my test cases is the Hacker News RSS feed (http://news.ycombinator.com/rss), and when I tried to execute a basic HttpWebRequest against it, the method failed because apparently Hacker News' feed is not fully RFC-complaint and thus HttpWebRequest raises an error as a defense mechanism in order to prevent HTTP response split attacks from occurring.

Microsoft responded to a legitimate security problem with a binary solution - either you turn off unsafe header parsing and run the risk of a split response attack or you simply don't process data from sources with malformed headers. They baby-proofed it.

And what, pray tell, does Microsoft recommend for us developers who want to use HttpWebRequest to download feeds from sources like Hacker News?

"If you find a site that exposes this behavior [non-RFC-compliant HTTP headers], contact them and ask them to fix it."

At no point did this behavioral decision grace the desk of a UX person at Microsoft (that's my assumption at least,) nor should it have. It's a user experience issue, but it's one that affects other programmers trying to leverage Microsoft's .NET framework in their own projects. Therefore the user experience decisions are made by the very programmers who maintain this portion of the framework.

One can hardly fault Microsoft for erring on the side of caution when it comes to security; in fact, the decision to make HttpWebRequest throw an error when a potentially unsafe header is detected is probably the right call.

I suspect a lot of developers honestly don't care to download content from sources with non-compliant headers. However there are a number of developers who want the freedom to make calls to those sources, and since Microsoft made it somewhat difficult to disable this security mechanism there's now an enclave of programmers who all use the same configuration hack to reverse Microsoft's decision, which ultimately isn't something Microsoft wants either.

This decision is one where not enough freedom was given to end-users - one whitespace character in the Content Length (should be Content-Length) HTTP header shouldn't force .NET programmers to deny their own application/service's end-users the ability to consume RSS feeds like Hacker News.

So what do you think? How much freedom should be afforded to the people who use our libraries, APIs, applications, and services? Is it better to baby-proof or give guns to monkeys?

If you enjoyed this post, remember to subscribe to my RSS feed!

General ,

How to Query a User's del.icio.us Feed with RestSharp

14. June 2010

I've been meaning to give RestSharp a go since I first started using Hammock in my startup project's codebase, just because I had heard some good things about RestSharp's auto-parsing capabilities.

This weekend I cobbled together a small example using del.icio.us' RSS feeds (not to be confused with its draconian REST API) for users and RestSharp performed magnificently, although its POCO -> XML Element mapping process requires a lot of experimentation before you get it just right.

Here's an example RSS feed for my personal del.icio.us account:

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/">
  <channel>
    <title>Delicious/Aaronontheweb</title>
    <link>http://delicious.com/Aaronontheweb</link>
    <description>bookmarks posted by Aaronontheweb</description>
    <atom:link rel="self" type="application/rss+xml" href="http://feeds.delicious.com/v2/rss/Aaronontheweb?count=2"/>
    <item>
      <title>Windows Presentation Foundation (WPF) Dialog Boxes Overview</title>
      <pubDate>Fri, 04 Jun 2010 23:48:12 +0000</pubDate>
      <guid isPermaLink="false">[REMOVED]</guid>
      <link>http://msdn.microsoft.com/en-us/library/aa969773.aspx</link>
      <dc:creator><![CDATA[Aaronontheweb]]></dc:creator>
      <comments>[REMOVED]</comments>
      <wfw:commentRss>[REMOVED]</wfw:commentRss>
      <source url="http://feeds.delicious.com/v2/rss/Aaronontheweb">Aaronontheweb's bookmarks</source>
      <description>How to use dialog boxes in WPF (for WPF noobs like myself.)</description>
      <category domain="http://delicious.com/Aaronontheweb/">.net</category>
      <category domain="http://delicious.com/Aaronontheweb/">wpf</category>
      <category domain="http://delicious.com/Aaronontheweb/">dialogs</category>
      <category domain="http://delicious.com/Aaronontheweb/">tutorial</category>
      <category domain="http://delicious.com/Aaronontheweb/">nullable</category>
      <category domain="http://delicious.com/Aaronontheweb/">c#</category>
    </item>
    <item>
      <title>Developer's Guide: Data API Protocol - YouTube APIs and Tools - Google Code</title>
      <pubDate>Mon, 31 May 2010 22:43:47 +0000</pubDate>
      <guid isPermaLink="false">[REMOVED]</guid>
      <link>[REMOVED]</link>
      <dc:creator><![CDATA[Aaronontheweb]]></dc:creator>
      <comments>[REMOVED]</comments>
      <wfw:commentRss>[REMOVED]</wfw:commentRss>
      <source url="http://feeds.delicious.com/v2/rss/Aaronontheweb">Aaronontheweb's bookmarks</source>
      <description>Finally figured it out - how to sign all requests with my API key using a querystring. So simple, yet so difficult.</description>
      <category domain="http://delicious.com/Aaronontheweb/">youtube</category>
      <category domain="http://delicious.com/Aaronontheweb/">API</category>
      <category domain="http://delicious.com/Aaronontheweb/">key</category>
      <category domain="http://delicious.com/Aaronontheweb/">Google</category>
      <category domain="http://delicious.com/Aaronontheweb/">gdata</category>
    </item>
  </channel>
</rss>

The best way to utilize RestSharp to parse any sort of API response, whether it's custom REST XML, JSON, Atom, or RSS, is to first take a look at the raw response format and then to try to model a set of Data Transfer Objects (DTOs) which contain the response format elements you want to actually use in your application. Your DTOs just need to be simple POCO objects for this to work, but there are a set of POCO-XML Element matching rules you need to observe if you're using RestSharp's default deserializer - you can read them here.

Here are the classes that I modeled for this RSS format:

public class RssFeed
{
    public string Version { get; set; }
    public RssChannel Channel { get;set; }
}

public class RssChannel
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public RssItems Item { get; set; }
}

public class RssItems : List<item>{}

public class item
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public string Author { get; set; }
    public string Comments { get; set; }
    public string PubDate { get; set; }
}

This diagram explains how these DTO classes map to the del.icio.us RSS format:

del.icio.us restsharp POCO class to XML document mapping

ProTip: Handling Lists of XML Elements with POCO Classes

One thing that's a bit tricky is handling lists of XML elements, such as the <item> elements in this case. In order for RestSharp to deserialize them, you need create a List<T> object where the name of class T matches the name of the listed element, which is why my class name is item in this case.

Once you have your POCO classes in order, then you need to actually make requests against the del.icio.us feed for a particular user. Here's my code for doing that:

public class DeliciousRequest
{
    public const string DeliciousFeedBase = @"http://feeds.delicious.com/v2/rss/";

    private RestSharp.RestClient _client;

    public DeliciousRequest()
    {
        this._client = new RestClient
                          {
                              BaseUrl = DeliciousFeedBase
                          };
    }

    public RssFeed GetBookMarksForUser(string username)
    {
        var request = new RestRequest {RequestFormat = DataFormat.Xml, Resource = username};
        var response = this._client.Execute<RssFeed>(request);
        return response.Data;
    }

}

All RSS feeds for del.icio.us users can be found using http://feeds.delicious.com/v2/rss/{USERNAME}, therefore you can understand why the RestClient's BaseURL and the RestRequest's Resource arguments are defined as they are. Once you have your RestRequest defined, you simply call the client's Execute<T> method where T is the type of your POCO DTO class.

And that's it - RestSharp is easy, and I look forward to creating some more examples with it down the road.

More RestSharp Examples:

If you enjoyed this post, remember to subscribe to my RSS feed!

.NET, Del.icio.us , , , , ,

The Myth of the Single-Person Startup

12. June 2010

Lonely Road

During the month of May, 2010 I took an unpaid leave of absence from work for the entire month and set off to launch my own web-based startup company.

My objective was to take a month off work, shut myself away in my apartment, spend a month coding up all of the basic plumbing I needed to get the first core part of my service in working order, and profit. Needless to say, I failed to reach my goals,  but not for any of the typical reasons like poor project planning, lack-of-focus, and so forth. No, I failed because I took the experiences of other entrepreneurs too literally and tried to “be my own boss,” without appreciating what that really means.

Success doesn't occur in a vaccuum

I grew up with a father who successfully launched his own self-funded business and made it look easy. Naturally, being the 24 year-old who doesn’t know any better, I figured it was as easy as having the technical knowledge to engineer my own product, having a good eye for end-user requirements, having a decent business plan, and enough time / resources to actually put something to market.

Naturally, when I finally secured the time I needed to begin engineering my product in earnest, I shut myself away, locked out virtually all human contact, and dove head first into my code. After all, that’s all what successful single-person startups do, right? “Sure,” I thought.

Twelve days into my project I had to scrap virtually every piece of code I had written – everything. It was a disaster. I wiped the slate clean and started redesigning and refactoring the entire thing, and I still hadn’t said more than a few sentences about it to anybody. Bear in mind that I was living off of my savings, so the time = money factor loomed large over my head. I went back to work on my project, still determined to get something done.

With one week to go before I was due back at work, I bought lunch for the Chief Architect from my regular job and had him take a look at some of my UML diagrams. I explained the domain I was working in, what I was trying to do, and what trouble I had run into thus far. In that one hour of speaking with him, I learned things that could have saved me the previous three weeks of 16-hour days, sleepless nights, endless debugging, and lessons-learned-the-hard-way.

This is going to seem like a total “no shit” observation for people who’ve been around the block before, but bear with me: though there are many entrepreneurs who successfully start businesses where they are the sole founder and first employee, they never truly do it alone.

They use other colleagues as sounding boards for ideas; they run design ideas by people who are familiar with the business or engineering domain; they stay in touch with potential customers and clients all the way through the process; they operate in professional networks; and they do a much better job keeping friends and family in the loop than I did.

I never looked at any of these contacts as must-have items before I set off on my own, and I got burned big time for it. I spent a substantial amount of time barking up the wrong trees and architecting solutions for the wrong problems, and all it would have taken to avoid that was some more collaboration and idea-sharing with people who were never going to be partners, employees, investors, et al.

Stay in the loop with your people

Lesson learned: the appeal of locking yourself in a confined space with nothing more than an Internet connection, a stack of programming books, and a mountain of pop tarts is significant if you’re young and tired of people telling you what to do.

However, isolating yourself from the world while you undertake a startup project is disastrous – you don’t necessarily need partners working with you day-in and day-out on the project, but you absolutely need sounding boards and supportive people you can share ideas and experiences with, because ultimately if you don’t get some outside perspective on what you’re doing, you’ll make myopic decisions and stumble along the way.

Get feedback where you can; talk database schema with the DBA in the break room at your day job while he’s refilling his coffee; share your ongoing startup problems with family and friends who’ve launched businesses before; join online news groups and connect with other people familiar with your problem domain; just stay in contact.

Remember this: being independent isn't the same thing as being alone - always keep a network to support you even if their contributions never amount to something more than friendly advice and encouragement.

If you enjoyed this post, remember to subscribe to my RSS feed!

Startup

Discussion: How to Use RestSharp / Hammock to Automatically Parse the YouTube Response Format into POCO Objects

8. June 2010

If you've been following me on Twitter over the past couple of weeks, you might have noticed that I've been a little frustrated with the YouTube GData API lately. Simply put: XML makes me sad. Since that frustrated Tweet I've developed a solution using LINQ-to-XML and a bunch of hard-coded namespaces which isn't how I would prefer to do it.

I would much rather use the built in object deserialization capabilities in RestSharp or HammockREST. I'll be honest - I do not have a damn clue how to use Hammock's built-in deserialization capabilities. I tried tinkering with it on my own to no avail, and there's not much documentation to speak of.

RestSharp has some more detailed documentation on its deserialization capabilities, but it doesn't answer some lingering questions I have. So without further aideu, I'd like to solicit the opinion of the developer community.

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007" gd:etag="W/&quot;DkMMRn0zeSp7ImA9WxFWE0k.&quot;">
  <id>tag:youtube.com,2008:user:smartdraw:uploads</id>
  <updated>2010-05-31T22:21:27.381Z</updated>
  <category scheme="http://schemas.google.com/g/2005#kind" term="http://gdata.youtube.com/schemas/2007#video" />
  <title>Uploads by smartdraw</title>
  <logo>http://www.youtube.com/img/pic_youtubelogo_123x63.gif</logo>
  <link rel="related" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw?v=2" />
  <link rel="alternate" type="text/html" href="http://www.youtube.com/profile_videos?user=smartdraw" />
  <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads?v=2" />
  <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads/batch?v=2" />
  <link rel="self" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads?start-index=1&amp;max-results=25&amp;v=2" />
  <link rel="service" type="application/atomsvc+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads?alt=atom-service&amp;v=2" />
  <link rel="next" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads?start-index=26&amp;max-results=25&amp;v=2" />
  <author>
    <name>smartdraw</name>
    <uri>http://gdata.youtube.com/feeds/api/users/smartdraw</uri>
  </author>
  <generator version="2.0" uri="http://gdata.youtube.com/">YouTube data API</generator>
  <openSearch:totalResults>30</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
  <entry gd:etag="W/&quot;CEIHQn47eCp7ImA9WxFWE0k.&quot;">
    <id>tag:youtube.com,2008:video:NJPrllhYZrg</id>
    <published>2010-02-10T23:27:38.000Z</published>
    <updated>2010-05-31T21:48:53.000Z</updated>
    <category scheme="http://schemas.google.com/g/2005#kind" term="http://gdata.youtube.com/schemas/2007#video" />
    <category scheme="http://gdata.youtube.com/schemas/2007/categories.cat" term="People" label="People &amp; Blogs" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="SmartDraw" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="flowcharts" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="visuals" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="communicate" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="visually" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="communication" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="powerpoint" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="presentations" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="mind" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="maps" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="software" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="Business" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="graphics" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="strategic" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="planning" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="solutions" />
    <category scheme="http://gdata.youtube.com/schemas/2007/keywords.cat" term="tools" />
    <title>SmartDraw 2010 Guided Tour</title>
    <content type="application/x-shockwave-flash" src="http://www.youtube.com/v/NJPrllhYZrg?f=user_uploads&amp;d=AWaEdOkfU7AZas-hLyE9s8EO88HsQjpE1a8d1GxQnGDm&amp;app=youtube_gdata" />
    <link rel="alternate" type="text/html" href="http://www.youtube.com/watch?v=NJPrllhYZrg&amp;feature=youtube_gdata" />
    <link rel="http://gdata.youtube.com/schemas/2007#video.responses" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos/NJPrllhYZrg/responses?v=2" />
    <link rel="http://gdata.youtube.com/schemas/2007#video.ratings" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos/NJPrllhYZrg/ratings?v=2" />
    <link rel="http://gdata.youtube.com/schemas/2007#video.complaints" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos/NJPrllhYZrg/complaints?v=2" />
    <link rel="http://gdata.youtube.com/schemas/2007#video.related" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/videos/NJPrllhYZrg/related?v=2" />
    <link rel="http://gdata.youtube.com/schemas/2007#mobile" type="text/html" href="http://m.youtube.com/details?v=NJPrllhYZrg" />
    <link rel="self" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/smartdraw/uploads/NJPrllhYZrg?v=2" />
    <author>
      <name>smartdraw</name>
      <uri>http://gdata.youtube.com/feeds/api/users/smartdraw</uri>
    </author>
    <yt:accessControl action="comment" permission="allowed" />
    <yt:accessControl action="commentVote" permission="allowed" />
    <yt:accessControl action="videoRespond" permission="moderated" />
    <yt:accessControl action="rate" permission="allowed" />
    <yt:accessControl action="embed" permission="allowed" />
    <yt:accessControl action="syndicate" permission="allowed" />
    <gd:comments>
      <gd:feedLink href="http://gdata.youtube.com/feeds/api/videos/NJPrllhYZrg/comments?v=2" countHint="0" />
    </gd:comments>
    <media:group>
      <media:credit role="uploader" scheme="urn:youtube">smartdraw</media:credit>
      <media:description type="plain">Explains the features of SmartDraw, the software that allows you produce any visual, whether it's a flowchart or a floor plan, in a matter of minutes.
Download a free trial of SmartDraw here: http://www.smartdraw.com/downloads/?id=343742</media:description>
      <media:keywords>SmartDraw, flowcharts, visuals, communicate, visually, communication, powerpoint, presentations, mind, maps, software, Business, graphics, strategic, planning, solutions, tools</media:keywords>
      <media:player url="http://www.youtube.com/watch?v=NJPrllhYZrg&amp;feature=youtube_gdata" />
      <media:thumbnail url="http://i.ytimg.com/vi/NJPrllhYZrg/default.jpg" height="90" width="120" time="00:03:21" />
      <media:thumbnail url="http://i.ytimg.com/vi/NJPrllhYZrg/2.jpg" height="90" width="120" time="00:03:21" />
      <media:thumbnail url="http://i.ytimg.com/vi/NJPrllhYZrg/1.jpg" height="90" width="120" time="00:01:40.500" />
      <media:thumbnail url="http://i.ytimg.com/vi/NJPrllhYZrg/3.jpg" height="90" width="120" time="00:05:01.500" />
      <media:thumbnail url="http://i.ytimg.com/vi/NJPrllhYZrg/hqdefault.jpg" height="360" width="480" />
      <media:title type="plain">SmartDraw 2010 Guided Tour</media:title>
      <yt:duration seconds="402" />
      <yt:uploaded>2010-02-10T23:27:38.000Z</yt:uploaded>
      <yt:videoid>NJPrllhYZrg</yt:videoid>
    </media:group>
    <gd:rating average="4.4444447" max="5" min="1" numRaters="9" rel="http://schemas.google.com/g/2005#overall" />
    <yt:statistics favoriteCount="9" viewCount="16206" />
    <yt:rating numDislikes="1" numLikes="8" />
  </entry>
</feed>

Now, here are use cases for how I might want to use this format:

  1. The GData API will only serve a maximum of 50 entries at any given time - one way to paginate through all of the entries in one go is to parse the link rel="next" field and query that URL until the field no longer exists. Is there a way you can use a POCO class in Hammock or RestSharp to automatically grab this field between queries against the API?
  2. Imagine you create a POCO class which contains the YouTube video ID, the author's username, the number of comments on the video, the keywords for the video, the number of views, and the number of the number of favorites. How would you structure this class such that RestSharp or HammockREST can automatically parse it from an ATOM response format like the one above? Bear in mind that these fields come from four of the five different XML namespaces (atom, Media RSS [media], GData [gd], and YouTube [yt]) used in this response format.

If you enjoyed this post, remember to subscribe to my RSS feed!

.NET, YouTube , , , , ,