GeekSpeak comments edit

I’ve started a new project where we’re doing our best to get every developer familiar with all the parts of the system by moving people around a bit, XP style. The idea is that we want to break down the knowledge silos so there’s not just one person who knows how each system works. I think that’s a great idea. If someone wins the lottery (or gets hit by a bus), we don’t want the whole project to crumble.

That said, there’s a particular undertone to some of the moving that worries me: the notion that somehow we can get rid of subject matter experts and everyone will know everything about the system.

I don’t think that’s a realistic goal. I think it’s a great idea to get folks familiar with how the various parts of the system work, but the system itself is far too big and there are too many changes going on over the course of time for anyone to keep intimate familiarity with the entire system in their head. At some point, you’re going to have someone who has more knowledge about how one area of the system works than anyone else, and you’re back to the knowledge silo of a subject matter expert.

The topic of skill set comes up here, too. Some people are better than others at certain tasks, be it due to education, experience, or both. Good idea: peer mentoring involving these folks. Bad idea: thinking you can make everyone on the team as proficient as experienced individual just by switching people around. Not everyone is a DBA. Not everyone is an architect. It’s not realistic to expect you can swap people into those roles and hope the system comes out as coherent and high quality as if you just trusted the tasks to the folks with the relevant skill set.

From a time/savings standpoint, it also occurs to me that putting someone who is good at a task on that task will cost less and get the task done faster than if you decided to put a less familiar person on the task. And if you keep moving people around, you may never actually gain momentum - it’s hard to work fast when you’re trying to learn at the same time. Great experience for the developers, great knowledge distribution, not so great velocity.

There’s a reason the phrase “jack of all trades, master of none” came about. It’s great that folks want to be generalists, and spreading the wealth of knowledge is an admirable goal. But there will always be subject matter experts, and that’s not a bad thing. Rather than try to get rid of them, I might recommend taking advantage of their expertise and doing a little peer mentoring to spread knowledge without trying to abolish the notion entirely. You’ll educate your developers and be able to gain project momentum by targeting the specialized skill set to pertinent tasks, and that’s a Good Thing.

I, like most of America, tuned in for The Sopranos series finale on Sunday night, stoked for a cool ending to a cool show. And, like most of America, I left with nothing.

When I say “nothing,” I really mean it. The show didn’t really have an ending, it just sort of “stopped.” I picked up my remote control and flipped around to see if other channels were still broadcasting, pissed off thinking that I had lost my HBO signal at the last second. That’s not actually what happened - that ridiculous “instant cut to black in the middle of a scene” thing they pulled… that was the ending.

To be clear, after I sat and thought about it for a while and talked to my wife about it, I got it - the whole uncertainty thing, life going on and Tony always looking over his shoulder, never knowing what’s coming next. I get it.

I also get the whole “art vs. entertainment” debate. Was the show “art,” where series creator David Chase just finishes up his creation and calls it done? Or was it “entertainment,” where there should have been more fan service?

Does it even matter? The Sopranos was a great show, primarily driven by great characters, with an intriguing plot. This last season, which we waited a heck of a long time for, sort of jumped the shark by going entirely character driven and really just losing the whole “plot” portion. I watched week after week waiting for something to happen, and it only ever ended up being sort of the way Seinfeld described itself: A show about nothing.

Sure, we see Tony going around doing his mob thing and his family getting worried or going through trauma or whatever. But what actually happened in the last season? Aside from the last little bit where Tony’s crew starts getting killed off and Phil Leotardo getting killed, nothing.

Now, I’m all for great characters and character development. They’re integral parts of great storytelling. On the other hand, the word “story” is actually half of “storytelling,” and you can’t just lose the story part and just have character development.

The end of The Sopranos, to me, was the very definition of anticlimactic. If I had a time machine, I think I’d have to go back in time and tell myself not to watch because it’ll only piss me off. Or maybe I’d have to grab David Chase and force him to call a mulligan and do it over. Much as it might be construed as art on some level, people watch for entertainment.

Travis Holds a Baby Goat - Click for the full
albumYesterday Jenn and I went over to my parents’ house because there were strange things afoot. My parents’ condo association has this overgrown area they need to clear the vegetation from but they wanted to do it in an environmentally friendly way. After looking at all the options, they hired a company called Noah’s Nibblers to do the work.

What they do is bring in goats - a lot of goats, like over 100 goats - and basically just cut them loose in the area that needs to be cleared. The goats eat the vegetation away, clearing the area without use of chemicals. Apparently they do a lot of work with the Army Corps of Engineers. I had no idea.

I’ve never seen that many goats in one place. I think my goat experience was pretty much limited to childrens’ petting zoos and such. Seeing literally a herd of goats mowing their way through an area is definitely something new.

Along with the herd, they brought a baby goat with them, less than 24 hours old, that the mother had rejected. We got a chance to hold him and feed him, and it was neat to see him walk his first few steps.

Anyway, that made for a pretty interesting Saturday. I’ve posted some pictures in a web album for those who want to see more. I don’t think the pictures really do it justice. The area they were eating down was on a hill, so it was tough to get a shot that really showed the craziness.

I’m constantly looking for ways to make deployment of ASP.NET applications easier. One of the things that makes it difficult is the ASPX markup files that have to be deployed with the app. Wouldn’t it be nice not to have those? Wouldn’t it be nice to be able to drop the application .dll into the bin folder, pop in your web.config file, and let ‘er rip?

Since I work primarily in ASP.NET 1.1 right now, the solution I came up with is for ASP.NET 1.1. There is a different/better way to do this in ASP.NET 2.0 and I will be writing/posting that as I get time.

UPDATE: The ASP.NET 2.0 version is here - based on System.Web.Hosting.VirtualPathProvider.

The idea: Embed your ASPX files in your ASP.NET application assembly. To deploy the app, drop your .dll in the bin folder and set up your web.config file. At runtime, embedded ASPX pages get extracted to a temporary location and get served up from there. When the app shuts down, the temporary fileset gets cleaned up. Easy deployment, easy upgrades.

The solution: An HttpModule that does exactly that. You set your application web.config file to use the EmbeddedPageHandlerFactory and in your ASP.NET project set your ASPX files from “Content” to “Embedded Resource.” At application startup, the module will go through the assemblies you registered as containing pages and extracts the ASPX to a temporary location. A replacement for the standard PageHandlerFactory redirects requests to the temporary location so pages get served up just like usual. When the application shuts down, the temporary files get cleaned up.

Here’s a snippet of the relevant bits in web.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section
      name="embeddedPageAssemblies"
      type="System.Configuration.DictionarySectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"
      />
  </configSections>
  <embeddedPageAssemblies>
    <add
      key="Paraesthesia.EmbeddedPageHandlerFactory.Demo"
      value="Paraesthesia.EmbeddedPageHandlerFactory.Demo" />
  </embeddedPageAssemblies>
  <system.web>
    <httpModules>
      <add
        name="EmbeddedPageHandlerFactory"
        type="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory, Paraesthesia.EmbeddedPageHandlerFactory" />
    </httpModules>
    <httpHandlers>
      <add
        verb="*"
        path="*.aspx"
        type="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory, Paraesthesia.EmbeddedPageHandlerFactory" />
    </httpHandlers>
  </system.web>
  </appSettings>
    <add
      key="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory.AllowFileSystemPages"
      value="false" />
  <appSettings>
</configuration>

Key points:

  • The embeddedPageAssemblies section is how you tell the module which assemblies have ASPX in them. The “key” is the name of the assembly; the “value” is the root namespace in the assembly.
  • The httpModules section is where you register the module portion of the solution. This is how the pages get extracted at app startup.
  • The httpHandlers section is where you tell all requests for ASPX files to go through the EmbeddedPageHandlerFactory and get served up from the temporary location.
  • The appSettings has an optional key for AllowFileSystemPages. Setting this to true will allow you to “override” ASPX by putting a file of the same path/name in the ASP.NET application file system. If the file exists in the app, it will be served from there. If not, it falls back to the temporary filesystem.

In your web project, change your ASPX pages in your application to be “Embedded Resource” rather than “Content.” Embedded resources get named based on namespace and file path. For example, if you have an assembly called “MyApp.Web” where the default namespace is “MyApp.Web” and you have a file at “~/Admin/Default.aspx” then when it gets embedded as a resource, it’ll be called “MyApp.Web.Admin.Default.aspx” - notice the namespace, then the path, then the file, all delimited by periods.

What the module does is look for resources that end with “.aspx” and, if it finds them, removes the namespace from the front (as specified in web.config) and substitutes out / for . to convert back to a path. In this example, “MyApp.Web.Admin.Default.aspx” would become “Admin.Default.aspx” and then “Admin/Default.aspx.”

Once the mapping is done, a temporary location is generated and the page is extracted to that location with the full relative path intact. As requests come in, the EmbeddedPageHandlerFactory will look at the request, map it into the temporary location, and serve the temporary file.

Using the appSettings key, you can specify that you’d like to allow pages in the actual ASP.NET filesystem to override the extracted pages. In this case, the actual ASP.NET filesystem would be searched for “Admin/Default.aspx” and if it is found, serve it from there just like a standard ASP.NET application. If it isn’t found, then it’ll fall back to look in the temporary location.

Caveats:

  • This won’t work for sites that rely on file system security. I primarily work with forms authentication, so this isn’t a problem for me. It may be for you.
  • This is definitely not the way you’d want to do this for .NET 2.0. This is really meant for .NET 1.1.
  • It only works for ASPX. The ASCX load process is different and doesn’t pass through a handler factory like pages. The .NET 2.0 mechanism should work for any files, not just ASPX.
  • This is going to be a one-shot deal. I’m not going to be posting updates or actively supporting it or anything. Take it at your own risk, your mileage may vary, etc.
  • The source bundle includes the source for the EmbeddedPageHandlerFactory as well as a demo web application and unit tests.
  • I wrote the unit tests using TypeMock so you’ll need to go get that if you want to build/run the tests.
  • It’s totally free and open-source. Do whatcha like.

Download EmbeddedPageHandlerFactory Compiled Assembly

Download EmbeddedPageHandlerFactory Source

This Memorial Day weekend was very relaxing and one of the nicest weekends I’ve had in a while.

Saturday Jenn and I ran some errands, mostly on a mission to find the Guitar Hero dual gig bag to store our guitars in. We didn’t find it, but had a nice day out and ended up at my parents’ place, heading out to see Shrek 3 at the end of the day.

Sunday was chore day, cleaning things up around the house. In the evening we headed over to Jason and Tracy’s place where we played four-person Mario Kart until all hours.

Monday was my easy day, though Jenn got a lot of great stuff done that had been needing to get done around the house. I caught up on my comic reading, watched some shows, and generally took it easy. Long about 1:00p I finally hit that point when I had totally decompressed and was stress-free (yeah, it takes about three days to get there) and was suddenly dead tired. The sun was out, the wind was gently blowing, and I could barely keep my eyes open.

That’s about the time Jenn wanted to go to the store and ask for my input on which plants would be best to put in containers. Any other day I might have had an opinion, but my brain had just turned off and I could not engage it.

We got home, I had myself a little something caffeinated to wake me up, and I played some Settlers of Catan and Marvel: Ultimate Alliance, finally breaking through the 10,000 Gamerpoint barrier. I admit I stood up and did the happy dance with that.

My brain is once again engaged this morning, I’m sipping some crappy generic French Roast coffee, and I’m ready to face the week, slightly less stressed.