Monday, July 12, 2004

NUnitAsp First Impressions: I Like It

I've been playing around with NUnitAsp for about 15 minutes now, and I already like it a lot. It gives the ability to make requests to an ASP.NET web page, and then easily verify that the contents of various server controls have rendered correctly. And it plugs into NUnit, so you get that same red/yellow/green display. I even managed to make it populate a login form with my credentials, click the submit button, and verify that it redirected me to the right page. Took about three minutes to write.


In addition to being useful for doing TDD of web apps, this is definitely something that should make writing build verification tests easier. Build verification tests (BVTs) are distinctly different from unit tests, in that they are intended to work against the system as a whole, rather than against a small piece of code. So as one of its last steps, the build script can copy the newly compiled web content to the file system, create a virtual directory, then use nunit-console to run tests that hit various pages, making sure everything works okay as deployed.

Sunday, July 11, 2004

Taking a Small Step to the Left

My blog has moved again! Only, not very far this time: instead of http://pluralsight.com/craig/ it now lives at http://pluralsight.com/blogs/craig/. The Pluralsight guys had to restructure the site a little to make things run more smoothly, and we figured better sooner than later. Everything should already be getting redirected automatically (including the RSS feed), but you can update your bookmarks and aggregators if you like. Please let me know if you find any broken links or missing content.


Also, apologies if your aggregator spewed a bunch of my old posts as new ones, but at least now you know why.

Thursday, July 8, 2004

XmlInclude - Not Quite as Useless as I Thought

Simon Horrell pointed something out to a bunch of us the other day that I thought was quite interesting. It has to do with the [XmlInclude()] attribute that's part of the System.Xml.Serialization stuff. Ordinarily, you use it on a base type to indicate that when serializing instances of that type, they might really be instances of one or more subtypes. This allows the serialization engine to emit a schema that reflects the possibility of really getting a Derived when the type signature is Base. For example, consider the following web service:

<%@ WebService class="Service" Language="C#" %>

public class Animal {
  public int legs;
}

public class Mammal : Animal {
  public int nipples;
}

public class Service {
  [WebMethod]
  public Animal GetAnimal() {
    return new Mammal();
  }
}

Note that GetAnimal is typed to return an Animal, but actually returns a Mammal. Well, if you were to look at the XML that came back from this method, you might be surprised to see that it looks like this:

<Animal>
  <legs>8</legs>
</Animal>

You'll observe that this result does not contain any mention of nipples - the “Mammalness” has been lost. Which makes sense - from an XML standpoint, you told me that the operation returns a type that just has legs.

One way we can “fix” this to give a result more in keeping with our OO expectations is to use the XmlInclude attribute on the base type, to list all the types that we might wind up substituting. It looks like this:

[System.Xml.Serialization.XmlInclude(typeof(Mammal))]
public class Animal {
  public int legs;
}

And if we run our web service now, we get this XML back:

<Animal xsi:type="Mammal">
  <legs>2</legs>
  <nipples>3</nipples>
</Animal>

Note the presence of the xsi:type attribute, which says, “This thing is actually a Mammal.” If you're generating a .NET proxy using VS.NET's Add Web Reference or the wsdl.exe command line tool, you'll even find that when you check the type of the object that comes back from the web service call, it's a Mammal, which derives from Animal. This is possible because in the schema for the web service, there's a bit that says that a Mammal is an extension (an XML schema term) of Animal.

If you're an OO person, however, you probably don't like the fact that you have to hang that XmlInclude attribute off the base type. The idea that a base type has to know about its derived types in advance is, well, just plain weird. This is where Simon comes in. He pointed out that you can actually put the XmlInclude attribute on the method instead of the base type. So if we change our web service to look like this instead:

<%@ WebService class="Service" Language="C#" %>

public class Animal {
  public int legs;
}

public class Mammal : Animal {
  public int nipples;
}

public class Service {
  [System.Web.Services.WebMethod]
  [System.Xml.Serialization.XmlInclude(typeof(Mammal))]
  public Animal GetAnimal() {
    return new Mammal();
  }
}

We'll get the same result (i.e. it'll have legs and nipples and use the xsi:type attribute) as putting the attribute on the Animal type. But putting it on the method is much more attractive from a code point of view, since it doesn't bake assumptions about type derivation into the base type. Rather, you put them on the method, where you probably have a good idea about what exact types are being returned.

Now, that said, I wouldn't write web services using this. Why not? Because if you care about interoperability, writing schemas that make use of extension elements and xsi:type isn't exactly “polite“. You don't know what technology your clients will be written in, and not all languages even have type derivation. Those that do, don't necessarily take the same view of it as C#. And even if they do, not all toolkits are smart enough yet to both map the XSD extension correctly and to look for the xsi:type attri

Wednesday, July 7, 2004

Busted

The wise Scott Hanselman and Richard Blewett both noted that my recent post about SoapParameterStyle.Bare was apparently at odds with Tim's post about the same thing. Well, they're right. The reason? My post was - to use the euphemistic engineering term for “lame“ - sub-optimal. But allow me to explain, hopefully clearing up any web service confusion that may have arisen.

Tim and I had had an interesting conversation one afternoon while I was at his place, in which he explained to me the pattern he describes in his post...of which SoapParameterStyle.Bare is an part, but only a part. More important is combining SoapParameterStyle.Bare with the style of using a single input and single output parameter - without this you don't realize all the benefits that Tim outlines in his excellent blog entry.

Anyway, when I posted, I didn't want to tell the whole story, because I was trying to goad Tim into blogging it, and didn't want to steal his punchline. But by only explaining half, the post wound up missing the point. I've updated my old post to point to Tim's stuff in the interest of community service. :)

Monday, July 5, 2004

Nice Explanation of Direct3D Frame Hierarchies

I get occasional emails from people that go something like, “Hey, I like your Direct3D Tutorial. When are you going to write more?“


D'oh! It's been months since I've written a new one, but between work at two clients, FlexWiki, moving the weblog, and all the other stuff going on, I just haven't had the time (although writing more is still on my list).


Luckily, others are not quite so lax. For instance, Joakim Karlsson has just posted a nice explanation of how to create and use a basic frame hierarchy. He's got another article on fullscreen device recovery, too, so here's hoping that he finds time to write more Direct3D stuff soon.

Sunday, July 4, 2004

dasblog2dottext Released

Peter and I did some work this weekend and got dasblog2dottext released! This is a very handy tool that Peter wrote; it imports all of your dasBlog content into a .Text instance, which is what made it easy for me to move my weblog here. Peter even wrote a little redirector that forwards all comment and permalink pages over to the appropriate entry on the new site.


What's funny is that I'm the one that wrote the BlogXToDasBlogImporter that's part of the dasBlog workspace. Hopefully I won't need to migrate to anything else for quite some time.


Anyway, the project is up on SourceForge...enjoy!

Friday, July 2, 2004

My New Home

If you're reading this, you're aware that I've moved CraigBlog to its new home here at Pluralsight. But why did I move? And why so suddenly?


Let me address the last point first: the move was only sudden from a public point of view. I wanted to throw the switch and have everything flip over to the new site as quickly as possible because I wanted to take all my posts - and the comments on those posts - with me. The longer the lag between the new site going live and the old one getting redirected over, the more information I was going to lose (or have to move manually). So I've actually been talking to the Pluralsight guys about this for weeks, and have spent a fair number of evenings and lunch hours getting it set up.


But back to "why". It's really simple, actually: because I think the Pluralsight guys are an absolutely top-notch group of dudes (as well as being good friends), and hanging out with them in virtuality seemed like it would be fun. They've got an exciting new company going and history, if nothing else, would indicate that they're going to be producing some excellent stuff. When they asked me if I'd be interested in coming over, I figured that if I can help them out by bringing some more traffic their way, I was happy to do it.


Oh, and as a consultant who lives by his reputation, it doesn't hurt me at all to hang my blog shingle up next to names like Aaron Skonnard, Don Box, Fritz Onion, Keith Brown, Mike Woodring, and Tim Ewald. :)


I'd like to thank Fritz and Keith in particular for handling their side the transition of CraigBlog - I've got a fair amount of content, and I had some requirements that they had to run around a bit to meet. I'd also like to think Peter Provost, who wrote the excellent dasBlog2dotText conversion tool, which is what made it possible for me to port all my content in a few hours rather than a few months. He and I are going to be releasing the tool on SourceForge this weekend - I'll be sure to let you know here (at my comfy new home on the web) when it's ready.