CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

June 2004 - Posts

  • Taking the SOA Plunge

    So,  I've been designing a new application here at the Port.  The functionality I'm enabling consists of a pretty complicated business process involving conversations with a variety of legacy/back-end systems.  I've been feeling like I really need to get this one “right“ for a couple of reasons.  First, This new functionality represents a central part of our business here.  Second it's the first time .NET code is going to be involved in operational aspects (versus mostly front-end stuff like queries via the web etc).  It could represent the future model for everything we do here on the windows side of the house. 

    I would consider my current implementations here service-oriented, but this really boils down to each application having local service dlls...  Not-really SOA in the true sense of the acronym.  So, like I said, I've put myself under a lot of pressure to do things right.  I've got a pretty good handle on how to do most of what I need to do, except for two big issues:

    1. DataSets vs. Custom Entities
    2. Web Services (WSE/ASMX) vs. Remoting for behind-the-firewall cross-application domain communication

    Now.  Here's the direction I'm going in, and I'm going to periodically post about the process of implementing this.  DonXML has really convinced me to go the route of Custom Entities and this was backed up by some discussion on DNR.  What convinced me here was Michèle Leroux Bustamante's question “Isn't that just a defacto agreement, that DataSets are bad? ” (Benjamin Mitchell and John Bristowe with special appearance by Michele Leroux Bustamante @ 1:09:20)   So, Custom Entities it is.  Specifically, I'm interested to know if I'll miss the rich feature set of DataSets, and I'm curious to know if DataBinding is any more difficult without my trusty typed DataSet.

    As to issue #2, I'm going to jump into using WSE.  I am a bit reluctant, however.  Don't get me wrong, ASMX rocks, and we rely heavily on it for a number or apps here, but is there a big payoff behind the firewall?  Folks like Clemens and Dare again have helped convince me that there is a payoff, but none the less,  I'll be curious about performance, ease of use, and overall cost/benefit in terms of re-use.

    So, look for more posts on this topic as I dig in to this stuff. 

    -Brendan

  • Blogging Guilt

    Grant shares with us a conversation he and I had and his feelings on blogging.  I'd actually characterize it as “Blogging Guilt“ ... Felling bad about not enough posting content, all the while holding back on content because it's not .NET related, thus not appropriate for DNJ.  He's said he's got some skunk-works project that will help him alleviate this, wonder what it'll be? 

    I've been thinking more about our conversation about blogging too. I, on the other hand, have no blogging guilt. I never thought twice about posting whatever crud came to mind, just because my blog happens to be on DNJ.  Here's how I've always understood it:

    1. Content is good for the folks at DNJ.  Now, this is not to say they don't have a certain reputation to improve/maintain, but in general, they're in the content business, the more the better.
    2. Off-topic postings should be noted as so, so that they can be ignored, but are not necessarily out of place.
    3. Most readers find posts through Google searches and aggregators.  The main feed is too cluttered to be of much use.  So, if someone gets sick of off-topic stuff, they can remove your feed.  Hopefully they'll keep reading, but if not, cest la vie.
    4. The folks that find you through Google won't see your off-topic stuff, unless of course they're looking for it.

    Much stuff that's outside the scope of the .NET Framework, runtime and languages is certainly .NET related.  Take XML for example, nothing about it is inherently .NET but if you don't have a handle on it, you're lost.  For this reason, I post about practically anything that I end up doing at work.  Now, I probably wouldn't post about how to work with PalmOS, but I have a hard time thinking of too many other examples of technical things I wouldn't post about...

    I do understand why some folks will have separate “Political“ or “Religious“ blogs, this is an obvious reason to separate blogs - these topics are not really polite to bring up with strangers, as some will tell you.  This is the way I've been approaching it.  Personally, I'm not a fan of people having different blogs for different things.   I feel like I'm missing out if I don't know to aggregate all their blogs. 

    Anyone care to weigh in? 

  • Off Topic: Adventures In Barbecuing

    So. My wife's out of town.  We haven't spent a night apart since we started dating...  Before she left, I was wondering what I would do with my evenings while she's gone. Last night I found out...

    I watched the first 10 minutes of “2 Fast 2 Furious” on cable.  I listened to .NET Rocks!  Live.  (no google weirdos again, BTW) and I had adventures in barbecuing.  Here's how it all went down:

    See, I've been on a quest to make the perfect Pizza.    I've experimented with different dough, etc. But never can get that great NYC thin bubbly crust.  I recently realized that my oven just doesn't get hot enough.  So, I've been thinking of how I can get a hotter oven.  I then realized that this new BBQ grill I got gets really really hot, like 500 something degrees.  Could I make a pizza on my grill?  I decided find out if this would work...

    Now, of course I couldn't put the pizza directly on the grill, and luckily I have a pizza stone, that I placed on the grill, on which I could put my pizza.  So I let the grill heat up, checking the temp now and then.

    I got my pizza all ready to go.  I went to place it on the grill, but the grill was so hot I couldn't get near it!  Then I realized I needed one of those wooden pizza paddles to allow me to safely place this pizza onto the inferno that I managed to create in my backyard.

    Enter the power tools.  I went down in the basement and quickly cut out of plywood a makeshift pizza paddle using my radial arm saw.  Went back upstairs and put some flour on it, and used it to slide the pizza onto the grill.  Worked like a charm.

    About 3 minutes later, literally, the pizza was done.  It looked beautiful! Perfect, bubbly crust!  Until I looked at the bottom, which was burnt to a crisp.  So, back to the drawing board.  I think I can get this to work.  I just have to put the pizza stone in later on in the process.  

    Did I mention there was a bit of wine involved?  Anyhow. Luckily I didn't burn the house down or cut my arm off in the process. I did eat the burnt pizza.  What else was I going to do? Starve?

  • Now This Looks Cool : Class Designer for VS 2005

    Via Dave Donaldson's post, I came upon this post describing the Class Designer for VS 2005:

    “But the real benefit is the real-time code synchronization. The Class Designer is in your project and is directly generated from your code. It is not generated from meta-data, but instead is generated from your VB or C# (or J#) code directly. This means that changes to the diagram are changes to your code. Changes to your code are changes to the diagram. The two are totally linked, because the source for the diagram is the code.“

    I've always had to force myself to do class designs.  And honestly, I might as well draw them on the white board and erase them after I write the code rather than use Visio.  Why?  Well, the Visio code generation never worked right for me, and when it did work, my diagrams quickly became out-of-date. All these diagrams just ended up as “Source Safe Sludge” - You know, all that crap that ends up in VSS that you'll never use, but don't want to delete either.  Hopefully, this will be the answer for me. 

    -B

  • Web Services vs. Remoting : Sorry to bring it up again, but...

    OBSOLETE CONTENT
    The author of this post has determined that this content is obsolete. Use at your own risk! Blog posts are a point-in-time snapshot of the blogger's thinking and should not be assumed to represent this blogger's current opinions. This post was left up for historical purposes.

    There's lots to read out there on this topic, but recently I've been confused about the discussions about the support for Remoting in Indigo, so I thought I'd ask for some help here..

    So, we've developed a base framework here at the port that's getting a good deal of re-use.  We've got solid, stateless single-call business objects, all being reused from a slew of endpoint applications. The problem is that each time we deploy one of the endpoints, we're re-deploying the business tier, and all of its dependent .dlls, configuration, etc.  Needless to say, we're getting to the point where we need to consolidate our services, so that we can simplify their management and deployment, and scale them up, when needed.

    I've seen this day coming (hence the stateless single-call business model) but now that it approaches, I've run into some confusion about which model of inter-process communication to use: Remoting or Web Services.  From everything I've read (1, 2, 3), it looks like the general gist of things has been the following: If your client endpoints are .NET and performance is a concern, use Remoting, otherwise, use Web Services.

    But, then I ran across the following article about the future changes to Remoting that will accompany Indigo.  As to when to use what, this is what they say:

    • Use .NET Remoting for calling between components hosted in different app-domains inside the same process
    • Use .NET Remoting for handling custom wire protocols and formats.

    It goes on to say:However, we recommend minimizing your use of .NET Remoting to these niche areas, and suggest that you utilize ... ASMX/WSE for exposing your services at your boundaries.“

     

    So, I'm kinda confused.  I want to use Remoting.  It seems like it will be simpler, faster and easier to code.  We've had some good success with Web Services, but from what I can tell, managing changes to web services over time is going to involve more work, will create more network traffic and will be slower overall.  So, other than the “Use Web Services because it'll work better with Indigo” (which isn't very compelling, btw) what compelling reasons do I have for using Web Services internally for inter-process communication accessing my buisness objects? 

     

    Is anyone out there doing this one way or the other successfully?  Can you offer any advice?

     

    Thanks in advance,

     

    Brendan

  • Another Cool Red Gate Project - SQL Packager

    I've posted about these guys before, but Red Gate puts out some great tools for SQL.  Their latest, SQL Packager will generate a .NET exe or even a Visual Studio Solution that will allow the user to install or update an existing deployed database with your applications.   Pretty cool stuff!

    More info and a free trial at:
    http://www.red-gate.com/sql/sql_packager.htm

  • Off Topic: Conversations With Ian

    These are too funny to me, not to document somewhere.  See, my 6-year old, Ian, says some pretty funny things.  We're starting to have real converstations with him, which is something new. By real conversations, I mean two-sided interactions where my wife and I can actually gain some peice of information from the interaction.  What I learned yesterday is that you can't always trust his account.  Take this conversation he had with my wife:

    Her: So you went to the grocery store with Brendan?

    Ian: Yes.  And guess who we saw?

    Her: Who?

    Ian: Bob!

    (now keep in mind that Bob's not married)

    Her: Cool, what did he have to say.

    Ian: Um.  I think his daughter's pregnant.

    (now, I was there, and I have no idea where this came from)

    Her: Really?  I didn't know he had a daughter, or a wife for that matter.

    Ian: Yes, his daughter's pregnant.  Mom, I have a question:

    Her: Okay, shoot.

    Ian: You know that new pregnant Barbie doll?

    Her: Yes.

    Ian: What kind of baby is she going to have?

    Her: Well, I don't know, we'll have to wait and see, won't we?

    Ian: Hmmm.  Maybe she'll have Spongebob.

     

     

  • When a Little Development Knowledge can be a Dangerous Thing.

    So I had this meeting with a developer yesterday that we're having to do some Web Services integration with.  This guy was interesting to say the least.  Now, I think that this guy probably is a coder.  But, have you ever seen that Brendan Fraser movie where his parents keep him locked in a fallout shelter, and one day he emerges with absolutely no knowledge of what has happened in the last 35 years?  Well, let's just say that it may as well have been this guy locked in the fallout shelter.  His knowledge of Web Application development was about 10 years old.   Here's a snippet of one conversation we had:

    So what platform are you using to develop this web application?
    Him: It's an ISAPI dll.  All of the HTML pages are dynamically generated by the dll.
    Um.  Wow..  So what programming language are you using?
    Him: Delphi.
    Oh.  Have you used the Delphi for the .NET framework?
    Him: No, haven't had the time to check into it.
    (thinking: that's because you're wasting so much time developing ISAPI dlls in Delphi!) Yeah.  I know how that feels.

    So, this guy can obviously figure stuff out, but he's down such a one-way dead-end street, that it's scary!  Take this other conversation we had about how we're going to implement our Web Services:

    So, I'm seeing a service with three methods here.
    Him: Well, can you make me one service that I can call and pass a string that instructs the server how to respond?
    (thinking: That would be a nightmare!  Can you imagine testing that? Maintaining it?) Um. No, I'm not really comfortable with that. 
    Him: I've already got a bunch of services running that way. I've implemented some Credit union software that way.  I've invented my own format that you just have to parse out to figure out what I need. 
    (thinking: holy shit!  Is he serious?  Why is he even using a Web Service? Remind me not to join any Credit Unions!) The more I think about it, no we're not going to do it that way.  I'm going to provide you with one service with three strongly-typed methods.
    Him: Okay.  That's fine.  Just more work for me, that's all.
    (thinking:  Oh, I feel sooo bad for you, you lazy *#&$#) Yeah, I think it'd be better in the long run.

    Did I mention that he says he's a CIO?  Well, anyway.  So, we've all met developers like this.  Is there any hope for them?  What do we do?  The fact that this guy is out there giving birth to all this nightmarish code is scary!  He must be stopped!

    -Brendan

  • Latest Dotnet Rocks - No Google Weirdos

    So, last night, I convinced my wife to listen to Dotnet Rocks.  I promised her a good laugh with Google Weirdos - but lo and behold, they decided to leave it out!  Now, in the chat room Rory did say that next week it would be back... Wheew!   If they could just play the Google weirdos theme song, I'd be happy.  That cracks me up. 

    -B

  • Microsoft SQL Server Best Practices Analyzer

    This is pretty cool.  I'd suppose that any one writing .net/SQL apps will find this tool helpful for identifying potential problems in their database design and deployments... Get your copy here.

    “Microsoft SQL Server Best Practices Analyzer is a database management tool that lets you verify the implementation of common Best Practices. These best practices typically relate to the usage and administration aspects of SQL Server databases and ensure that your SQL Servers are managed and operated well.”

    -B

  • Windows Service Administration with .NET Part 3 - Controlling Your Service

    A while back I posted the following two articles about administering a Windows service using ASP.NET:

    Windows Service Administration with ASP.NET - Part 1 - Marshalling Status Information

    and

    Windows Service Administration with ASP.NET - Part 2 - Remoting to the Marshalled Object

    I promised to write part 3, how to start and stop a service over the web, and a few people have been asking me, “What Gives?, Where's Part 3?”   It turned out to be so simple, using the ServiceController class.  So here's part three, two static methods you can use in your ASP.NET code that will stop and start a service:

    public static void StopService(string strServiceName)
    {
       System.ServiceProcess.ServiceController sc2 =
             new System.ServiceProcess.ServiceController(strServiceName, [YOUR SERVER NAME] );

       
    if (sc2.Status.Equals(System.ServiceProcess.ServiceControllerStatus.Running))
        {
           sc2.Stop();
       
    }
    }

    public static void StartService(string strServiceName)
    {
       System.ServiceProcess.ServiceController sc2 =
             new System.ServiceProcess.ServiceController(strServiceName,  [YOUR SERVER NAME]);
       
       
    if (sc2.Status.Equals(System.ServiceProcess.ServiceControllerStatus.Stopped))
        {
          sc2.Start();
        }
    }

    -Brendan

  • The .NET Gnome #5

    Darrell had a funny rant today about the overuse of the term agile.  I started thinking, what if other functions outside of IT adopted agile methods, and, well, a new cartoon was born:

    Check out all my cartoons here..

  • Create a Self-Updating WinForms App with the Application Updater Block

    During the past couple of weeks, I've been doing some of my first real dotnet WinForms App development.  It's been a fun journey, I'm still learning stuff like crazy.  One of the things I wanted to do was enable the app to be self-updating using the ApplicationUpdater Block from MS.  This took me a considerable effort to get working right, and I thought that the MS samples lacked a step-by-step example.  Duncan Mackenzie has a good blog post here that was a great start, but the examples were VB and it didn't go into the specifics of the Public and Private RSA key stuff, so I thought I'd post this walk through.  I hope it works for you!

    Step #1 Install the Application Blocks

    Download the Updater Application Block from Microsoft .

    Run the MSI Installer.

    Step #2 Add the Code and References to Your Project:

    Add the following projects to the solution containing your Winforms project :

    Microsoft.ApplicationBlocks.ApplicationUpdater
    Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces
    Microsoft.ApplicationBlocks.ExceptionManagement
    Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces

    They should be located in the following folder, if you've accepted the defaults

    C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater

    Reference the following projects from within your Winforms Project

    Microsoft.ApplicationBlocks.ApplicationUpdater
    Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces
    Microsoft.ApplicationBlocks.ExceptionManagement

    Add the following namespaces to your form's .cs file.

    using System.Runtime.InteropServices;
    using System.Runtime.Serialization;
    using System.Threading;
    using System.Diagnostics;
    using System.IO;
    using System.Xml;

    Then add the application updater code located here to your code.  You'll need to call InitializeAutoUpdate() from your MainForm's Initialize method.

    Step #3 Create your Application's Deployment Directory Structure and Configure AppStart.exe

    Create a folder for your client installation.  For example purposes, we'll use the following directory:

    C:\Program Files\YourApp\1.0.0.0\

    Now copy the AppStart.exe and AppStart.exe.config into the root directory like so:

     C:\Program Files\YourApp\AppStart.exe
     C:\Program Files\YourApp\AppStart.exe.config

    Note: You can find these two files in the “C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\AppStart\bin\Debug“ directory. 

    Step #4 Modify the AppStart.exe.config File

    AppStart.exe will launch your application and allow a restart once an update has been downloaded.  It needs to know the directory to use to launch the latest version of your app. 
    Modify this config file to match the current version like so:

    <appStart>
     
    <ClientApplicationInfo
    >
       
    <appFolderName>C:\Program Files\YourApp\1.0.0.0</appFolderName
    >
       
    <appExeName>YourAppName.exe</appExeName
    >
       
    <installedVersion>1.0.0.0</installedVersion
    >
       
    <lastUpdated>2004-06-10T15:33:17.3745836-04:00</lastUpdated
    >
     
    </ClientApplicationInfo
    >
    </appStart>

    Step #5: Create Your Public and Private Keys

    Run the ManifestUtility "C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\ManifestUtility\bin\Debug\ManifestUtility.exe"

    Choose “File..Generate Keys”  You will be prompted to save the following keys: PublicKey.xml and PrivateKey.xml  You'll be using these keys in the next steps. 

    From what I can tell it's best to create these keys once, because you'll need to reference these RSA public and private keys in a couple of places.  You'll want to keep your keys in a safe place, because you'll need them when pushing new updates. 

    Step #6 Create Your IIS Virtual Directory

    Create a directory on your WebServer to house your updates.  You will end up with two things in this directory 1) a ServerManifest.xml file which will contain the latest version information, and 2) your new application directory. Within this directory, create a directory to house your new application version.  So, for our example, we'll create the directories, C:\Inetpub\AppUpdates  and C:\Inetpub\AppUpdates\1.0.0.1

    Use IIS Manager to create a virtual directory pointing to this physical directory.  Remember your URL, as you will need it in an upcoming step.  You will have to enable directory browsing for this virtual directory.

    Step #7. Configure Your Version 1.0.0.0 App.config File

    Here, we'll need to add a few things.  First, we need to add a configSections element to define our appUpdater section:

    <configSections>
     
    <section name="appUpdater" type="Microsoft.ApplicationBlocks.ApplicationUpdater.UpdaterSectionHandler,Microsoft.ApplicationBlocks.ApplicationUpdater"
    />
    </configSections>

    Next we need to add the Version key to our appsettings key, we're first going to set our local versoin to 1.0.0.0, so that we can test the auto-update to version 1.0.0.1

    <appSettings>
     
    <add key="VERSION" value="1.0.0.0"
    />
    </appSettings>

    Finally, add the appUpdater section to your config file.  I've put brackets where you need to edit the values.  You can just copy the <RSAKeyValue> element from the PublicKey.xml file that you created in the previous step.

    The <xmlFile> elements should point to your Virtual directory's  URL that you created in step #6.

    <appUpdater>
      <UpdaterConfiguration
    >
       <polling type="Seconds" value="120"
    />
      
    <logListener logPath="C:\Program Files\YourApp\UpdaterLog.txt"
    />
       <downloader type="Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader"

    assembly
    ="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/>
     
      <validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator" assembly
    ="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
     
    <key
    >
      
    <RSAKeyValue
    >
      
    <Modulus>[YOUR MODULUS KEY]</Modulus
    >
     
    <Exponent>[YOUR EXPONENET]</Exponent
    >
     
    </RSAKeyValue
    >
     
    </key
    >
     
    </validator> 
      <application name="[YOUR APP NAME]" useValidation
    ="true">
       
    <client
    >
         
    <baseDir>C:\Program Files\YourApp</baseDir
    >
         
    <xmlFile>C:\Program Files\YourApp\AppStart.exe.config</xmlFile
    >
         
    <tempDir>C:\Program Files\YourApp\temp</tempDir
    >
       
    </client
    >
        <server
    >
         
    <xmlFile>http://[YOUR URL]/ServerManifest.xml</xmlFile
    >
        
    <xmlFileDest>C:\Program Files\YourApp\ServerManifest.xml</xmlFileDest
    >
        
    <maxWaitXmlFile>60000</maxWaitXmlFile
    >
       
    </server
    >
      </application
    >
     </UpdaterConfiguration
    >
     
    </appUpdater>

    Step #8 Deploy Version 1.0.0.0

    Version your app.  You do this by setting the version attribute of your app's AssemblyInfo.cs file.

    [assembly: AssemblyVersion("1.0.0.0")]

    Build the Application and copy version 1.0.0.0 to your program file's 1.0.0.0 directory. “C:\Program Files\YourApp\1.0.0.0“

    At this point, you should be able to run AppStart.exe.  The update process should fail, since we haven't deployed the ServerManifest XML file which tells our app that there's a new version available.  You can inspect the log files that should be created in your C:\Program Files\YourApp\ directory.

    Step #9 Buld Version 1.0.0.1 

    This is the fun part.  First, create revision 1.0.0.1 by updating your application's AssemblyInfo.cs and App.config files to reflect the new version.  Build your application, and copy the files to the web server directory created in step #6. 

    Step #10 Create Your Server Manifest File

    This should be the last step.  Any changes you make to the .config files from this point on will require repeating this step.  To do this:

    1. Launch the ManifestUtility program again. 
    2. Choose the 1.0.0.1 directory from the “Update files folder“ chooser. 
    3. Enter the URL of the update location. 
    4. Enter version 1.0.0.1
    5. Open your PrivateKey.xml file created earlier.
    6. Choose the validator class “Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator”
    7. Click CreateManifest, and save the ServerManifest.xml file to your virtual server directory.

    That's it!  Pheeew!  Run your AppStart.exe from your C:\Program Files\YourApp\ directory.  Your app should launch, and you should now be prompted that “A new version is available” when you launch your application.  The new app should be downloaded into your C:\Program Files\YourApp\1.0.0.1 directory, and the app should re-start itself.  If you have problems, be sure to check the log files that are created during the process.  They can be very helpful in tracking down bugs.

    -Brendan

  • Off-Topic: My Grandfather's Book Would make a Nice Father's Day Gift...

    Father's day is the 20th of June.  Don't know what to get your Dad?  Well, you're in luck!  My father just put his father's humor book online as an e-book.  You can download it here for $3.  Now that's a bargain. I've done some calculations, and this is perhaps the cheapest humor on the planet, word for word. :) Don't believe me? I've included an excerpt here where he explains that Alexander Graham Bell didn't want us to have caller ID:

    -Brendan

    I am persuaded that if Alexander Graham Bell had wanted us to have Caller Identification, he would have invented it himself.

    Of course, I cannot be positive about this, but by putting two and two together, so to speak, I am reasonably comfortable with the guess that Watson and Bell had discussed the concept before that historic occasion on which Bell placed the first telephone call. Why do I say this? Look at the call—probably the most important in the history of humankind up to that moment. Did Alexander call his mother? Did he call the President of the United States? Did he call Larry King? No, he called Watson! Watson was just down the hall! Why didn't he stick his head out, if he couldn't see him, and yell? And what did he say? Did he tell Watson they might be on to something … or to go out and buy some stock? No, the message was: "Mr. Watson, come here I need you." What for? Why did he need him to come there ...didn't he already have him on the phone? Why not tell him what was on his mind and hang up?

    My research did not unearth any clear answers, but I have my own ideas. First let's say for the moment that I'm right and they had talked already about Caller Identification and Watson was pushing it, but Bell was against it. It is my guess that when the phone rang, Watson was sulking over the latest rejection of his idea and Bell was getting mad because Watson was taking his sweet time in answering.Working from this hypothesis, it is fairly easy to surmise how the conversation went, after Watson hung up and went into the boss's office:

    You're working for me and you don't even answer the phone?

    I answered.

    Yeah, you answered after it had almost rung off the hook! What was the problem?

    I'm here, that means I answered.

    I almost hung up! Why didn't you answer on the first ring?

    How was I supposed to know who was ringing?

    Couldn't you have picked up the receiver right away and at least said "Hello," so I would know that we had invented the telephone?

    How could I be sure who was calling?

    If you answered the phone and said "Hello," I would have told you who was calling.

    "Hello" is a question? You never told me that.

    No, it's not a question, it's more like an invitation to tell whoever it is that it would be nice to know who's calling.

    Could I answer and say, "Who's calling"?

    You could.

    O.K., Graham, I'll go back to my office and let's try it with the "Hello," but I still say Caller Identification could be a real moneymaker.

    I knew that's what's been bugging you! Well get this straight; I don't want any more argument about any tomfool scheme. If we keep this thing simple, the public might go for it. Drop the caller identification idea. We're not in the name-tag business!

  • DonXML's Up for Grabs...

    DonXML has posted that he's looking for a new gig.  Not only is he looking, he alludes to the fact that his entire team may be available too.  Now, unfortunately, we're not in need of such a team, but if I were a company in the NJ area and I had the resources, I'd jump on the chance to hire the entire team.   As I'm sure folks like Darrell Norton will tell you, building superstar teams is a hard task, and the chance to snap up one all at once is a golden opporutunity. 

    I also find it interesting that a person like Don can post that he's interested in a new position and he'll probably ultimately have his choice of opportunites.  If he gets any bites via blog posts, this may be a good way for the rest of us to find positions when we need them.  That's just another cool thing about this blogging community we're all a part of.  I'd like to know how the process comes along.  Keep us posted Don!

    Brendan

More Posts Next page »

Our Sponsors