# Thursday, June 17, 2004

Sigh.  Somewhere along the line (probably because I opened my mouth) I became installer boy for our project.  I've learned some pretty interesting things along the way, mostly having to do with how inadequate the VS.NET setup projects can be if you do anything even mildly out of the ordinary. 

We have two potential targets for our installer, a developer's machine and a production machine, and for a production machine we have to install a subset of the developer installation.  The way to accomplish such an option in a VS.NET setup project is to add a custom dialog called Radio Button (2) and the set it's properties so that your text shows up in the right places on a pre-built dialog that contains nothing but 2 radio buttons.  OK, not so bad.  Then you name an environment variable that will hold the result of the radio group, let's call it SPAM.  You give the radio buttons their own values, like 1 and 2.  Again, OK, not so bad.

The part that really sucks is how you use the results of the dialog box.  For every file that I want to not be installed in production (every single file, not just folders) I have to set its Condition property to "SPAM=1".  I understand that it was probably really easy to implement, and probably meets the needs of many, but really, how lame is that.  Because the Condition property of the folder doesn't propagate to its files, I'll have to add that condition to every new file that gets added to the project.  And, no one but me will be likely to understand how the setup works without asking or doing some research.  Hmph!

On top of that, I've learned how amazingly limited is the support for registering COM interop objects in .NET.  I need to register some COM objects with Version Independent ProgIDs, so clients won't have to constantly upgrade the ProgIDs they use to find our objects.  There's absolutely no support for that in System.Runtime.Interop.  None.  You can't even do registration on a type by type basis.  You can only register all the types in an assembly at once.  Doesn't leave a lot of room for custom behavior. 

So, I ended up writing my own Version Independent ProgIDs to the registry in an installer class.  Not elegant, but there you have it.

Thursday, June 17, 2004 1:37:05 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, June 07, 2004

I'm a volunteer Emergency Responder for the city of Hillsboro, so I signed up for this years CERT Rodeo, which was this past Saturday.  What a blast!  I had a really great time.  We had a really good turnout, with probably 80+ responders, plus plenty of "victims" and amateur radio operators to play along with. 

It was a great chance to refresh our skills and meet people from different teams.  There were teams from all over NW Oregon and SW Washington, and they mixed us all up into different teams for the Rodeo. 

We got to spend the day searching for victims in the Portland Fire department's training tower (6 stories), doing triage, disaster medical care and transport of some really gruesomely made up victims, putting out fires, and extricating dummies from under some really #(@*$ing HEAVY actual concrete rubble. 

We also got some great support from the community, with lots of firefighters volunteering to train and help out, and the Red Cross providing snacks and drinks. 

Check out some pictures and videos of the event here.  The rodeos only happen every other year, and I'm already looking forward to the next one.

<Community service plug>If you're interested in learning how to protect yourself, your family and your neighbors in the event of a disaster or other emergency, check out CERT (Community Emergency Response Teams) programs in your area.  NW Oregon has tons of programs, as do many other parts of the country.  In the City of Hillsboro, you can get a free 24 hour training course open to anyone who lives or works in Western Washington County.  It's a great training program conducted by local police, fire and EMS professionals.  It's a great way to feel more secure about yourself and your family in the event of an emergency, and a great community service opportunity.  CERT teams also get to help out with things like airshows, marathons, and other events where EMS coverage is desirable, which is a lot of fun.  FEMA also has some online training materials you can check out.</Community service plug>

Home | CERT
Monday, June 07, 2004 10:22:38 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

I took the family to see the new Harry Potter flick yesterday with about 20 friends.  What a blast.  I had no idea you could get into a theater an hour before the show these days :-).

I was pretty impressed.  It's amazing what a real director can do with a story, instead of just parroting the book for two hours.  The new one is much more like a real movie, and focuses much more on story than on special effects (although there are some cool ones, they are subtle) and cutesy elves.  It's a much darker film, and really showcases some great British actors.  I'd have to say that the kid who plays Harry has pretty much reached the limits of his acting ability, but Hermione rocks!

Well worth seeing, and much less of a kiddy film than the first two.

Monday, June 07, 2004 10:06:10 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, June 04, 2004

I have been writing a lot of code lately that involves parsing external files, like XSD and WSDL files.  In my unit tests, I need to be able to read in a sample file that I can use to run the unit tests off of.  The problem is my unit tests (using NUnit) get run in several different places: my local dev sandbox, the build server, etc.  That makes it hard to know where to get the test XSD/WSDL files that I need to run the NUnit tests.  Hard coded, absolute paths don't work, because people may have their code in different places on different machines, and the tests should still pass.  Relative paths don't work either, since the test assemblies sometimes run from where VS.NET puts them (xxx/bin/Debug) and sometimes from the build directory, which is a totally different location.

The solution I finally hit upon was to use embedded resources.  Add your external file to your VS.NET project, and make its "Build Action" = "Embedded Resource".  That way, the file will get embedded into your final assembly as a "manifest resource".  

With that done, your test code can write out that embedded resource to a known location every time (like the temp directory) and use that for testing, cleaning up after itself when it's done.

In the following example, the external file is called "Example.wsdl".  It gets written out to the temp directory, then deleted when all the tests are done using the SetUp and TearDown methods.

    public class TestWsdl
    {
        private string wsdlPath = Path.Combine(Path.GetTempPath(),"Example.wsdl");
        private Wsdl wsdl = null;
    
        public TestWsdl()
        {
        }

        [SetUp()]
        public void Unpack()
        {
            Assembly a = Assembly.GetExecutingAssembly();
            Stream s = a.GetManifestResourceStream("MyNamespace.Test.Example.wsdl");
            StreamReader sr = new StreamReader(s);
            StreamWriter sw = File.CreateText(wsdlPath);
            sw.Write(sr.ReadToEnd());
            sw.Flush();
            sw.Close();
            sr.Close();
        }

        [TearDown()]
        public void CleanUp()
        {
            if(File.Exists(wsdlPath))
            {
                File.Delete(wsdlPath);
            }
        }

The only tricky part can be figuring out the name of your manifest resource to pass to GetManifestResourceStream.  It should be the default namespace for your project plus the filename.  The easiest way to find out what it is is to use Reflector, which lists all the resouces in any given assembly.

Friday, June 04, 2004 10:40:24 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, June 02, 2004

I'll be teaching CST 407 Web Services Theory at the Oregon Institute of Technology (OIT) this summer.  The class is Monday and Wednesday evenings for 4 weeks, June 21nd - July 14th.  Registration is open if you are interested.  I'll be focusing on the theorectical aspects of Web Services and Service Orientation, so if you're interested in getting a good grounding in that part of Web Services, come on down!

[Update]

Here's the course description:

Web Services Theory
There has been a lot of buzz in the media of late over Service Oriented Architecture (SOA) and Web Services.  But what does "Web Services" really mean?  Why are they interesting?  What advantages do they offer to companies?  What do they do for you, the developer?


This class will start from the most basic levels of XML and proceed to the fundamentals of Web Services and the SOA.  The focus is on theory, rather than practice, and although there will be practical exercises, the end goal is to understand the fundamentals of how Web Services work, how they can be used, and in what application are they most useful.  This is the first course in a 3-course sequence.  The second course will focus on how to implement Web Services on a specific platform.

Students will leave this class with a firm understanding of how and why Web Services work, and where Web Services fit into the overall picture of modern software development.
For successful completion of this course, some knowledge of programming is required, preferably in C#/C++/Java or VB.
Wednesday, June 02, 2004 3:13:25 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [4]  | 
# Thursday, May 27, 2004

Monopoly or no monopoly, this is what put and what keeps Microsoft on top:

I had an incredible experience today at the sails pavilion - I asked about Speech Server...So I'm sitting at the SQL cabana and the Microsoft helper gets on the radio and asks someone if they've got the Speech Server group at their cabana. About fifteen seconds later, every MS radio in earshot lights up with "Any Speech Server expert, any Speech Server expert, we need an answer in the cabana ASAP!" Really really impressive! [Jason Fredrickson ]

Back in the dim time, I started out as a Mac developer before moving to Win32 (I never had to write a far pointer :-) ).  I was pretty up on developing for the Mac.  I went to two WWDCs in the early/mid 90's.  I was a total Apple bigot.  Why aren't I still?  Because Apple had (and probably has) a habit of completely jerking developers around, when they weren't ignoring them completely.  The barrier to entry was high.  I still have the many $100s worth of Apple Developer books that you pretty much had to buy to write for the Mac.  Apple's own development tools were way overpriced, and horribly under-useable.  Worst of all was the System 8 debacle.  I spent quite a bit of time and effort getting ready for "Copeland" which was Apple's first "System 8" replacement for their antiquated System 7.  I even went and learned Dylan, since Apple said they were going to be moving into the future with Dylan on Copeland.  (Dylan, and particularly Apple's Dylan implementation which was written in Lisp, was awesome at the time.  Everything Java brought to the table later and more useable, IMHO.)  Then Apple pulled the rug out, never shipped Copeland, or any of the DocPart stuff they were touting with IBM, killed Dylan, etc.  I think that was when they really started losing market share.  They were alienating developers at the same time that MS was coming out with Win32 and courting developers.  No matter how cool your operating system is, if nobody writes apps for it, it's not going anywhere (witness BeOS).

I'm not saying MS has never lead developers astray (Cairo?) but overall they have made a concerted effort to attract developers and make them feel valued, which leads to more high quality apps being available on Windows then anywhere else. 

I've been to numerous MS conferences, and always had a good time, and more importantly I always felt like MS was seriously committed to making my life easier and showing me how to better get my job done.  That's worth a lot.

Thursday, May 27, 2004 10:04:49 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, May 25, 2004

If you've ever gotten involved in the Java vs. .NET debate (and who hasn't) check out N. Alex Rupp's blog.  He's a dyed-in-the-wool Java guy who's going to TechEd this week and talking with .NET developers and INETA people about what they like about .NET.  He has some very interesting things to say about the Java developer - .NET developer relationship.  A very fair and unbiased look at the issues and how the communities interact internally and externally.

It's very refreshing to see someone being so open and honest about the pros and cons of both platforms.  (And it pretty courageous, given the longstanding antagonisms, for him to not only go to TechEd, but to advertise his Java-guy-ness.)

Tuesday, May 25, 2004 3:05:22 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  | 

Scott has some comments about WSE 2.0 (which just in case you haven't heard yet has RTMed) and I wanted to comment on a few things...

 Question: The Basic Profile is great, but are the other specs getting too complicated?
My Personal Answer (today): Kinda feels like it!  WS-Security will be more useful when there is a more support on the Java side.  As far as WS-Policy, it seems that Dynamic Policy is where the money's at and it's a bummer WSE doesn't support it.    
[Scott]

It's the tools that are at issue here, rather than the specs I think.  I spent some time writing WS-Security by hand about a year ago, and yes, it's complicated, but I don't think unnecessarily so.  The problem is that we aren't supposed to be writing it by hand.  We take SSL totally for granted, but writing an SSL implementation from scratch is non-trivial.  We don't have to write them ourselves anymore, so we can take it for granted.  The problem (in the specific case of WS-Security) is that we have taken it for granted as far as Web Services go.  Unfortunately, that makes the assumption that Web Services are bound to HTTP.  In order to break the dependence on HTTP (which opens up many new application scenarios) we have to replace all the stuff that HTTP gives us "for free" like encryption, addressing, authentication, etc.  Because to fit with SOAP those things all have to be declarative rather than procedural, I think they feel harder than depending on the same thing from procedural code. 

If we are to realize the full potential of Web Services and SO, then we have to have all this infrastructure in place, to the point where it becomes ubiquitous.  Then we can take the WS-*s for granted just like we do SSL today.  Unfortunately the tools haven't caught up yet.  Three or four years ago we were writing an awful lot of SOAP and WSDL related code ourselves, and now the toolsets have caught up (mostly).  Given enough time the tools should be able to encompass the rest of the standards we need to open up all the new application scenarios. 

Steve Maine makes a good analogy to the corporate mailroom.  There's a lot of complexity and complex systems involved in getting mail around the postal system which we don't see on a daily basis.  But it's out there none the less, and we couldn't get mail around without them.  When we can take SO for granted like we do the postal system, then we'll see the full potential of what SO can do for business, etc. in the real world.

Tuesday, May 25, 2004 11:06:13 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

On a whim last weekend I spent some time trying to learn Smalltalk.  So many of the seminal thinkers around XP, etc. were originally Smalltalk heads, so I wanted to see what all the fuss was about. 

I downloaded a copy of Squeak for Windows and went through several of the tutorials.  Pretty interesting stuff, but I think I'll stick to C#.  I can see why people are hot for Smalltalk (or used to be anyway).  Because it's so rigidly OO, it forces you into doing the right things with regard to object orientation.  And the tools are pretty cool. Having such an advanced class browser and inspection system is a big advantage. 

However, I think I'll stick to strongly typed languages (of which C# is currently my favorite).  I guess my overall impression of Smalltalk is that for people who were very competent, you could get a lot of work done in a very short amount of time because the system is so flexible.  On the other hand, because the system is so flexible, I would guess that people where were less then amazingly competent (or confident) would have a very hard time getting anything done at all because you have to understand exactly what you are doing, and many errors will only present themselves at runtime.  It would be fun to work in such a flexible system, but I really appreciate the benefits of compile-time type checking. 

At the same time, I was playing with a copy of MSWLogo (a free Logo implementation for Windows).  What a blast.  I haven't played with Logo since the Apple II days.  Once upon a time you could actually get a physical turtle that held a pen, and connected to a serial port.  You could write Logo programs to get the turtle to scoot around on a really big piece of paper.  I always thought that was a cool idea.  I was also surprised at how much Logo and Smalltalk have in common syntactically. 

I was trying to get my 8-year-old son interested in Logo, but I think he's still a little too young.  I met with a resounding "whatever, Dad".  I guess I didn't get my first Commodore PET until 6th or 7th grade. :-)

Tuesday, May 25, 2004 10:37:49 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, May 21, 2004

I was just reading Steven Padfield's article on unit testing ASP.NET code by creating your own HttpContext outside of IIS (which is a very useful technique) and it got me thinking about a technique that I've gotten a fair amount of mileage out of lately, namely creating my own context object that will be available anywhere in a call stack, just like the HttpContext is.

When I started looking into how to implement such a think, I was thinking in terms of deriving from ContextBoundObject, which seemed like overkill.  So I fired up the ever-handy Reflector and found out how HttpContext handles itself.  Turns out that no ContextBoundObject is needed.  Hidden in the bowls of System.Runtime.Remoting.Messaging is a method called CallContext.SetData(string, object) that will stick a named object value into your call context, which can be retrieved from anyplace on the current call stack.  Pretty handy.  If you wrap that in an object like HttpContext, you can store your own context values, and potentially provide context-sensitive methods such as HttpContext.GetConfig().

What you end up with is an object that looks something like this:

using System;
using System.Collections;
using System.Runtime.Remoting.Messaging;

namespace MyContext
{
public class ContextObject
{
private const string ContextTag = "MyContextObject";

private ContextObject()
{
}

/// <summary>
/// returns a valid context object, creating one if
/// none exists
/// </summary>
public static ContextObject CurrentContext
{
get
{
object o = CallContext.GetData(ContextTag);
if(o == null)
{
o = new ContextObject();
CallContext.SetData(ContextTag,o);
}

if(!( o is ContextObject))
{
throw new ApplicationException("Corrupt ContextObject");
}

return (ContextObject)o;
}
}

/// <summary>
/// Clears out the current context. May be useful
/// in situations where you don't have complete
/// control over your call stack, i.e. you aren't at the top of
/// the application call stack and need to maintain
/// a separate context per call.
/// </summary>
public static void TeardownCurrentContext()
{
CallContext.FreeNamedDataSlot(ContextTag);
}

private string contextValue1;

///<summary>
/// a sample value to store to/pull from context
///</summar>
public string ContextValue1
{
get
{
return contextValue1;
}
set
{
contextValue1 = value;
}
}
}
}

You can use the context object from anywhere in your call stack, like this

public class Tester
{
public static void Main(string[] args)
{
ContextObject co = ContextObject.CurrentContext;
co.ContextValue1 = "Hello World";
OtherMethod();
}

public static void OtherMethod()
{
ContextObject co = ContextObject.CurrentContext;
Console.WriteLine(co.ContextValue1);
}
}


 

The resulting output is, of course, "Hello World", since the context object retains its state across calls.  This is a trivial example, and you wouldn't really do it this way, but you get the idea.
Friday, May 21, 2004 10:52:34 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |