ViNull: This site is best viewed with VT100

ORM talk at CodeStock Open Spaces

tagged:

One thing I'm hearing from a lot of people who attended CodeStock last Saturday is how well the open spaces "track" was.  This is one area I can't take any credit for, my only role in planning open spaces was requesting a room from the college; all credit for success goes to Alan Stevens the facilitator.

An Open Spaces conference is explained as the "un-conference" - a very hippy, free flowing conference where the sessions self organize and the topics are chosen by the attendees.  This in contrast to a traditional conference of set speakers and topics.  Each have an advantage; an open space isn't the best place to get a first look at a technology but once you've used a technology an open space is a great place to discuss with others how it should be used.

Rather than choose one format, CodeStock featured both.  This worked out better than I could have imagined because it mixed two camps - the open space people hung out with the "straight laced" conference people.  This created a stage for some great conversations with all views represented and an exchange of ideas can commence.  Wally McClure was breaking in a new Flip, and managed to capture an ORM discussion for the latest ASP.NET Podcast - I would have loved to have been there, but I was fighting gnats at the time.

More video formats available at ASP.NET Podcast

PostStock

tagged:

Warning: this is going to be a grilled cheese post.

I woke up this morning, amazed there is an August 10th.  I mean, I knew there was a full August this year, but for the last two months I haven't given much thought to any date past August 9th, the date of CodeStock.  I've pretty much wasted the whole day - slept in, made a run to Sonic, played Rock Band with Cicelie and the girls and made it through another level in Bad Company.  I figure (hope) many people will blog about CodeStock, so instead of giving the overall picture, I'll tell you what my day was like.

5:30 am Alarm goes off.

6:15 am I wake up, realizing that somehow I fell back to sleep.  I need to be at Pellissippi by 7am and it's a 20 minute drive.  The truck isn't loaded with the 4 boxes of shirts, 3 boxes of bags, 2 boxes of books, and many other boxes of giveaways, and misc. needed items.

6:45 am After an amazing display of speed and strength, Cicelie and I are on the road to Pellissippi with a fully loaded truck.  I even remembered to get dressed.

7:05 am Glenn Zahn and the RecruitWise are already at the Performing Arts Center (PAC), as well as Gabriel (a volunteer).  We unload and begin setting up the registration area.  Catering is setting out juice and coffee, I grab a badly need cup.  This would be my first of 5 cups of coffee that I grab, take one sit, set down somewhere and can't find it later.

7:30 am Cicelie and Lisa (of RecruitWise) have the registrations down to a science.  I keep trying to help, but I'm just making things worse, so I setup the giveaways on stage.  I'm also getting a question every two minutes, but I'm delegating tasks as much as I can so my constant distractions don't seem to be a problem.  I have an awesome team of volunteers.  Thanks Cicelie, Jim, Gabriel, Crystal, and the RecruitWise team.

8:05 am At 7:55 it looked like there was about 20 more minutes of registrations - I underestimated how fast Cicelie and Lisa were, because at 8:00 there was no one in the line.  We start only 5 minutes off schedule.

8:20 am My opening over, I hang around the ticket booth.  A number of small issues seem to work themselves out.  Example, Alan needs power strips for Open Spaces, Wally calls on his way in asking if we need anything - so I tell him power strips.  There is something Zen going on, and I'll not dare question it.

8:40 am Scott Spradlin is here from INETA to film interviews on the "making of" CodeStock.  I help him setup a T-shirt for a back drop, and then do a short interview.  Not thinking of Murphy, I talk about how well planned everything is.

9:00 am The last 20 minutes felt like three hours - that's the speed difference in the day from the morning registrations.

9:30 am Right on time, attendees are in their first sessions.  I grab my camera to snap photos of the speakers in action.  I fail at getting a shot of Amanda Laucher without her noticing.  I also get flipped of by James Bender.  I have photos to post later.

10:30 am It occurs to me that offering to help Nathan Blevins fill in for Wally McClure's session has put me in a session right before lunch (also known as the next chance for panic).  I fill Glenn in and ask him to lead setting up a "human chain" to direct people to the cafeteria for lunch.

12:00 pm Session over, it went okay but I'm feeling it sucked hard.  This is mostly because this was an ad hoc session and I'm used to my highly planned sessions.  Having never rehearsed the session together, the handoff's between Nathan and myself flowed almost as smooth as wet cement.   The content is good however, and we can turn this into a pretty good talk in the future.

12:05 pm I expected to find a long line of people waiting for lunch, and some catering crisis in the kitchen.  What I found was everyone had their lunch and was sitting down eating and having a good time.  This was the best execution of a lunch I've ever seen at a community conference - and I had little to do with it.  I grab a box and talk to a few people before going back to the open spaces room to eat.

12:45 pm The open spaces room is attracting a lot of people during the lunch hour.  I get back to the ticket booth and round up 3 other people to hear out to the after party tents so we can setup tables and chairs.

1:05 pm The running track around the pond at Pellissippi is covered in an amazing amount of crap.  All kinds of crap: bird crap, dog crap, duck crap.  I see people running on this track all the time and think to myself if running on crap is as healthy as these people think it is.  I walk beside the track in the grass.

1:10 pm The tents are filled with about 30,000 gnats.  Freaky ones I've never seen before - they look like a mosquito but instead of a sucker for a mouth they have two little fuzzy balls.  They don't bite, but no one would eat a hot dot with these guys around.  They appear not to have come from the pond around the tents, but from the stack of chairs left in the tents.  There are also a few wasp nests under the stairs leading up to the stage.

1:20 pm Glenn and crew will finish setting up the chairs, I'm off to buy an arsenal of anti-gnat weapons of mass destruction.  On the way out I run into John Kellar and Brian Prince.  John organizes DevLink and Brian organizes CodeMash - the two "biggies" in our region.  We joke a bit and then Brian mentions Kentucky Day of .Net is in 3 weeks - both John and I (who will be speakers at the event) are shocked it's so soon.  Just like I didn't see past August 9th, John's not thinking past August 22nd and DevLink.  I'll call this condition "conference blindness."

2:45 pm I return with my gnat WMDs and launch a full scale invasion with outdoor foggers and citronella candles.  I also drop 3 wasp nests before I run out of wasp spray (the kind that shoots a stream).  The cans of fogger say they kill wasps, and there are a few wasps that escaped, so I hit them with the fogger.  Do not use a fogger on a wasp unless you really want to piss it off.  Axiom: if it doesn't kill on contact, don't use it on a wasp.

3:00 pm I call Cicelie to she if she can send out a few volunteers to watch the tents for an hour or so.  I have 10 citronella candles burning under two tents and I think it's against fire code to leave them unattended (probably against common sense too).  The band will be there to setup at four, and they can come back to the PAC then.  She finds someone from RecruitWise (whose name I can't recall) to relieve me.  Update: His name is Eric.

3:30 pm Things are quiet from now until closing - I mostly hang around the registration desk and chat with passing speakers.  Nathan juggles Microsoft stress balls, and I learn Dave Redding called attendees jackasses, one guy an asshole, and gave my ex-wife beer all during his session.  I make note to attend Dave's sessions in the future.

5:00 pm Closing, and raffle off of the goodies.  I pretty much just rattle off ticket numbers for 30 minutes, and let people choose their prize in a "first come / first choice" fashion.  We picked up so much extra items to raffle off during the day it's crazy - including a Halo 3 Legendary Box Set (the one with the Master Chief helmet) from Brian Price and Microsoft which went second to the MSDN subscription donated by Wally through Scalable Development.

I had five copies of Petzold's Turing book to give away, and was amazed at the level of interest among speakers to win the book.  I'm pretty sure one speaker (I won't name them) stole the book off the stage during the raffle.  There were some speakers opting not to take anything when they won, letting me draw another number, so a swap could have been done instead of theft.  I want to find out the rest of the story - what happened, and was the book really that sought after?  It's a great book, don't get me wrong, but it's a little crazy to think it would cause such a commotion.

Update: Got the whole story, no thefts just some mixups, and the Petzold book was really in demand.  I guess I did a good sales job holding up the title and talking about my review!

5:45 pm Steve Andrews, Cicelie, and I do room checks to make sure nothing is wrong with any of them and clear out trash.  I'm impressed that the rooms need very little cleaning - people took care of the place.  I stop by as Scott is finishing an interview and do a short interview on end of the day thoughts.

6:10 pm I arrive at the CodeStock After Party, slightly late.  My biggest blunder of the day was forgetting to tell everyone there was food (hotdogs, chips, and drinks) at the party.  About 20 people are there, looks like many had left to eat.  Hanover Fist put on a great show, and I got up and sang "Oh Well" by Peter Green era Fleetwood Mac.  I dedicated the song to my MVC brethren.

7:45 pm The band finishes the last song, and people start heading home or to Alan's "After After" party.  I tell people I plan on getting to Alan's around 9:30.  I stay behind with Cicelie and my brother Willie to fold up chairs and tables.  I thank the band and drive home.

9:30 pm I've been trying to talk myself into going to Alan's party for the last 30 minutes, but I give in.  Cicelie, my daughters, and I share some ice cream.  I went to bed right after.

Using LINQ to generate HTML

tagged:

image I hate seeing code mixed with markup.

Seeing a template page with <% if(show) { %> makes me want to claw my eyes out.  Seeing String htmlTitle = "<h1>" + title + "</h1>" causes me to vomit up a little something in my throat.

Mixing code with markup is not a magic chocolate and peanut butter combination - it's a volatile cocktail of vinegar and baking soda waiting to explode your application to tiny Server 500 Error giblets.

The time comes however when we find ourselves needing to generate some well formed HTML in code, and I found myself in just such a position last night adding the agenda to the CodeStock website. (Less than one week away now!)

Background: On the CodeStock site, the speakers and sessions list lives in an XML file.  The agenda page has a grid of session times and my task was to fill in each session "cell" with the session planned for that room and time.  I wanted to link to the full session and also list the speaker's name in the cell.  In the XML I have created Key elements that are used as HTML anchors in a link to a session.  It's all very low tech, simplistic goodness.  An example of the XML for a speaker:

<Speaker>
    <Key>Brownell</Key>
    <Name>Steve Brownell</Name>
    <Website>http://enthusiasticprogramming.blogspot.com</Website>
    <Photo>~/Speakers/SteveBrownell.png</Photo>
    <Bio>
        Steve is the manager for research and development at AllMeds in Oak Ridge, TN.  Steve
        has been programming one thing or another for over twenty years.  AllMeds makes and
        sells a commercial software product which is an electronic medical record system.  We've
        been .NET based since 2000.  AllMeds is a VB.NET shop at heart, but the AllMeds system spans
        many areas of Windows development.
    </Bio>
    <Session>
        <Key>Hobbled</Key>
        <Title>
            The Hobbled:  There And Back Again, or Code Automation:  how I made it from the
            presentation layer to the database and back.
        </Title>
        <Abstract>
            Stop writing code, and start writing code that writes code.  There's never been more
            choices to help you automate the creation of the data object layers immediately above
            the database.  Writing class factories and data access classes is boring, time consuming
            and wastes valuable time with expensive developer resources.  This course will examine
            two current approaches:  using a template engine and programming with the CODEDOM.  We'll
            also briefly discuss other ORM techniques like LINQ to SQL Classes.
        </Abstract>
        <Level>200</Level>
        <Technology>VB.NET, C#, LINQ, SQL</Technology>
    </Session>
</Speaker>

(Steve was our CodeStock Speaker Idol winner, and I enjoyed seeing System.Codedom in action; something I'll be playing with and posting on in the future thanks to Steve!)

LINQ to XML, and the new "X" classes that come with it make working with XML as easy as it should have always been.  Armed with LINQ, I decided that putting <%= SessionInfo("Hobbled") %> was something I could live with (had this been a larger site that needed to live longer than August 9th, I would have opted for a user control <CodeStock:SessionInfo Key="Hobbled"/>).  My first LINQ expression looked something like the following:

var info = (from s in speakers.Descendants("Session")
            where s.Element("Key").Value.Equals(SessionKey)
            select new {
                key = s.Element("Key").Value,
                title = s.Element("Title").Value.Trim(),
                speaker = s.Parent.Element("Name").Value
            }).First();

This yields a very useful info object with just the information I need.  *If* I was in a hurry, and didn't mind a little vomit, I would follow on with the following:

String hmtl = String.Format("<a href='{0:s}' title='{1:s}'>{2:s}</a><br />{3:s}",
    new object[] { ExpandURL("~/Pages/Agenda.aspx", info.key),
                   info.title,
                   info.title.Length > 30 ? info.title.Substring(0, 27) + "..." : info.title,
                   info.speaker });

Why do I despise this so much?  It's not easy to read, and it can become cumbersome to change.  ASP.NET has a collection of server controls just for generating HTML, intended for use in user controls but they are not limited to user controls alone.  To generate the html above would look something like this:

HtmlAnchor aHref = new HtmlAnchor() {
    HRef = ExpandURL("~/Pages/Agenda.aspx", info.key),
    InnerText = info.title.Length > 30 ? info.title.Substring(0, 27) + "..." : info.title,
    Title = Title
};
HtmlGenericControl div = new HtmlGenericControl("div") {
    InnerText = info.speaker
};

StringBuilder html = new StringBuilder();
using (StringWriter sw = new StringWriter(html)) {
    using (HtmlTextWriter hw = new HtmlTextWriter(sw)) {
        aHref.RenderControl(hw);
        div.RenderControl(hw);
        hw.Close();
    }
    sw.Close();
}

There are times when working with parts of the .Net framework I have wonder if some Java types didn't design the class.  The mess here to render the HTML is one of those times.  The lack of a RenderControl that returns a String is the problem - thankfully we now have extension methods to fix the framework, but that's another post.  No matter how much I hate markup in the code, I cannot endorse this version over the vomit inducing first solution.

It occurs to me that HTML is (or was once) fundamentally XML, and I can return XML from my LINQ expression.  In fact, this is what LINQ is about - not just getting the data you want, but getting it in the format you need.  Here is the new LINQ query:

XElement info = (from s in speakers.Descendants("Session")
                 where s.Element("Key").Value.Equals(SessionKey)
                 let key = s.Element("Key").Value
                 let title = s.Element("Title").Value.Trim()
                 let shortTitle = title.Length > 30 ? 
                    title.Substring(0, 27) + "..." : title
                 let session = new XElement("a",
                              new XAttribute("href",
                                  ExpandURL("~/Pages/Agenda.aspx", key)),
                              new XAttribute("title", title),
                              shortTitle)
                 let speaker = new XElement("div", s.Parent.Element("Name").Value)
                 select new XElement("span", session, speaker)).First();

This may not seem to some as better.  I myself have trouble looking at most LINQ expressions, but as I'm learning to Thinq Linq I'm seeing that writing the LINQ expression is where the power lies, not in the syntax.  The mental dialog goes something like this:

"Okay, from my list of speakers I want a session where the session's key matches SessionKey.  Now, let me grab some fields I need, first the key, then the title which I need to trim off excess whitespace, then let's make a short version of that title since Steve's title is so long - love that title though.  I'll need an link tag for the session; set the href and title attributes, and then add the speaker's name in a div tag so I get a cheap line break.  I'm really in XML not HTML, so I'll need a root node and a span tag will work without affecting layout, and I'll add the link and div tags as children."

Writing LINQ like this I feel much closer to the problem I'm trying to solve, and not bogged down by syntax.  There is still some moments I'm thrust back to code, such as the use of First() to select only one result.  I'd like to have a "select first" option in LINQ expressions instead of just the extension methods. 

Is this something I'll be using now every time I have this problem?  Not sure yet, but it's another "tool in the box" I'll keep around and use when it feels right.

Back into gaming, thanks to Jeff

tagged:

image

Update: The GiantBomb.com crew have made a video explaining the site!

A decade ago I would have no problem talking about the latest in gaming.  Then I got into MMO's, and that led to me leaving gaming all together.  There is something about realizing "gameplay" is a nice marketing term meant to cover up the fact you're just playing Diablo for $15 bucks a month to turn you off the industry completely.

Then came my Wii, and an XBox 360 followed.  The Wii is great for games with groups and my younger daughters, but games like Legend of Zelda: Twilight Princess reminded me there was another class of games I used to play, before the MMO blight.  Playing Mass Effect, Bioshock, and Gears of War on my 360 reignited my passion for gaming.

I've always hated the mainstream game review sites like IGN and GameSpot - the reviews never feel honest and I have to spend a good deal of time reading user reviews to gauge the game.  I have many things going on in my life; I don't have time to waste on bad games.  I started following Ars Opposable Thumbs and soon learned of the new site Jeff Gerstmann was behind.

Jeff was the editorial director of GameSpot, and was fired for giving bad reviews to games that publishers were advertising on the site.  WikiPedia has some of the details, and Jeff himself doesn't talk about it, but it's pretty obvious what went on.  The fact many editors left GameSpot in protest after the firing speaks volumes.  I found Jeff's podcast, and became instantly hooked.

The "bombcast" is easily one of my top three podcasts - first just Jeff and Ryan Davis then later adding Brad Shoemaker and Vinny Caravella to the cast.  These guys all hail from GameSpot, and are not your polished art critics, but gamers who speak about games the same way you and I would.  They are honest, clear, and pretty damn funny.  These four have also worked on launching a new game review site: www.giantbomb.com

The website is part news, part wiki.  The search feature is slick, and the pages go beyond just the games and into the characters, developers, and concepts.  The amount of user contributed content is staggering, considering the site has been live for little more than a week.  If you haven't checked it out already, and are into gaming at any level, take a look at Giant Bomb.

The ASP.NET MVC Definition

tagged:

image A few days ago I posted a question to the community, looking for a definition of the ASP.NET MVC framework that didn't depend upon faults in ASP.NET WebForms - after all, faults can be fixed.  I also do not like the implication that ASP.NET MVC is for those looking to use the MVC pattern, as I've been using that pattern for a decade and I use it in WebForms today.  Credit goes to Lucas Goodwin for helping me with the following definition:

ASP.NET MVC is the evolution of Classic ASP.

I've helped a number of developers move from Classic ASP to ASP.NET, and each one has said to me, "wow, this is nothing like ASP" once they groked it.  This is true, and mostly because WebForms introduced an event based paradigm to ASP.  Classic ASP had problems, but was the lack of events one of them?

Classic ASP's number one problem was lack of separation of concerns.  This is the same reason I don't like PHP, my code is far to friendly with my HTML (gotta keep em' separated).  True you can discipline yourself to provide a separation, but it's not something the framework designers gave much thought to.

WebForms fixed the separation issue, but at the same time brought in the event model.  I liked this "magic controller" approach, because it saves me the time I used to spend wiring up controllers that just ended up back at the same template I started with.  (For the record, I was mostly working with python before moving to WebForms, first with a framework called Albatross and later SnakeSkin)  An event model is not required to have separation of concerns, and this forced an event model on to many Classic ASP developers.  So I will add a bit to the definition:

ASP.NET MVC is the evolution of Classic ASP, adding an easier separation of concerns while not using an event based model like WebForms.

So do you agree or disagree?  I like this definition because it's not claiming either approach is better, and I can look to the pros and cons of an event based model to guide me in selecting MVC or WebForms for a project.  It also is less likely to cause rioting in the streets at your next user group meeting when the topic comes up!

The Open Source Web Design Toolbox

tagged: design web templates
Great source for web design resources

The .NET 2.0 Framework Provider Pattern

tagged: .net provider programming
Example of creating your own provider in .Net

Seth's Blog: Just one post

tagged: writing blog for:captquirk
Seth Godin tells you why you need a blog. Older Posts