Scott Hanselman

BUG: Fixing One-Letter Titles in the Title Bar in IE

April 14, '06 Comments [5] Posted in Bugs | Tools
Sponsored By

Weird bug...suddenly IE shows the first letter of the title bar. Like if the title bar should be "MSDN" it'll say "M" - the "SDN" would be clipped.

Fix? Uninstall (and reinstall, if you like) the Google Toolbar. Obscure.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Programming Sudoku

April 13, '06 Comments [11] Posted in Programming
Sponsored By

1590596625.01._AA240_SCLZZZZZZZ_

My wife <gasp> declared last week that she wants to learn to program. We sat down and did the whole hello world thing, but that got boring and not-concrete very quickly.

Enter Programming Sudoku from Wei-Meng Lee. This little gem walks you through building a Sudoku generator and solver in Visual Basic 2005.

This book is easy to follow and at the end you'll end up with a very complete (and extendible) WinForms application.

I'm a fan of programming books that walk the reader through the creation of an application (and the thought behind the decisions) from start to finish. Reminds me of the apps I used to type in from Compute! magazine.

Now playing: Stephen Lynch - Bowling Song (Almighty Malachi, Professional Bowling God)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

CodeGen'ing a Data Access Layer with CodeSmith

April 12, '06 Comments [11] Posted in Nant | Tools
Sponsored By

I mentioned CodeSmith in my podcast post earlier, and we'll talk about it on next week's show, but as a nice coincedence Brian Windheim, one of our architects, posted how he was using Code Generation on one of our internal Corillian (das)Blogs.

Here's what he had to say (some parts redacted):

Brian: I’ve become a huge fan of code generation for data access and object mapping.  The [blank] team has been using a generated data access layer to interface with the [blank] database for a long time now, and the reward has been tremendous.  Without trying to sell it too much, here’s what the client code looks like, inside a hand-coded product API method:

FooThing ReadFooThing(long fooID)

{

   using (SomeDatabase db = new SomeDatabase())

   {

      return FooThing.CreateFromDataReader(db.ReadFooThing(fooID));

   }

}

In the above code, the FooThing and SomeDatabase types are 100% generated code.  Methods are generated for every stored procedure, and multiple sproc calls can be used inside the same using block, as the SqlConnection is maintained for the undisposed life of the SomeDatabase instance.  Classes with single-record and multiple-record column-to-property converters are generated for each table in the database as well.  The codegen implementation will work on just about any database (it is not team-specific), and if you adhere to a few basic rules with your sproc names, the generated code will be very nice.

Some history: last summer I built a CodeSmith template to do the codegen, based on sample code from CodeSmith and some trial and error.  Start to finish was under three hours, and I had no CodeSmith experience before, other than poking around in the [Corillian Voyager SDK’s CodeGen templates].  There has since been some minor maintenance to it, but the overall time commitment has been exceedingly small.  And the benefits?  Here’s a start:

1. Compile-time failures when a stored procedure interface has changed and the application code hasn’t.
2. Type safety for sproc inputs.
3. Automatic column mapping from sproc result sets to strongly typed domain objects.
4. Automatic type mapping from SQL to CLR types and vice-versa.  If the sproc takes in a smallint, you won’t get away with shoving a System.Int64 in there.
5. Automatic mapping of SQL OUT and INOUT params to method return types.
6. Awareness of DbNull and CLR value type collisions.

So what does the generated stored procedure wrapper code look like?  Here’s a sample for a read-single-record sproc:

public IDataReader ReadFooThinglong fooID)

{

   SqlCommand command = new SqlCommand("dbo.ReadFooThing", this._connection);

   command.CommandType = CommandType.StoredProcedure;

   command.Parameters.Add(new SqlParameter("@FooID", fooID));

   return command.ExecuteReader();

}

… and another sample for a create-new-record sproc, which returns the ID of the new record:

public long CreateFooThing(int batchID, long accountID, string checkNumber, decimal amount, string currencyCode,

  DateTime issuedDate, DateTime someDate, string reason, string payee)

{

   SqlCommand command = new SqlCommand("dbo.CreateFooThing", this._connection);

   command.CommandType = CommandType.StoredProcedure;

   command.Parameters.Add(new SqlParameter("@BatchID", batchID));

   command.Parameters.Add(new SqlParameter("@AccountID", accountID));

   command.Parameters.Add(new SqlParameter("@CheckNumber", (checkNumber == null) ? System.DBNull.Value : (object) checkNumber));

   command.Parameters.Add(new SqlParameter("@Amount", amount));

   command.Parameters.Add(new SqlParameter("@CurrencyCode", (currencyCode == null) ? System.DBNull.Value : (object) currencyCode));

   command.Parameters.Add(new SqlParameter("@IssuedDate", (issuedDate == DateTime.MinValue) ? System.DBNull.Value : (object) issuedDate));

   command.Parameters.Add(new SqlParameter("@SomeDate", (someDate == DateTime.MinValue) ? System.DBNull.Value : (object) someDate));

   command.Parameters.Add(new SqlParameter("@Reason", (reason == null) ? System.DBNull.Value : (object) reason));

   command.Parameters.Add(new SqlParameter("@Payee", (payee == null) ? System.DBNull.Value : (object) payee));

   SqlParameter outputParameter = null;

   outputParameter = new SqlParameter("@FooID", new long());

   outputParameter.Direction = ParameterDirection.Output;

   command.Parameters.Add(outputParameter);

   command.ExecuteNonQuery();

   return (long) outputParameter.Value;

}

The generated domain types that correspond to tables are rather big, so I won’t include them here.

I use the code generator in our builds in the following manner:

1. Drop the existing database.
2. Deploy the database (schema + sprocs).
3. Run the code generator to produce SomeDatabase.g.cs.
4. Compile SomeDatabase.g.cs into assembly Corillian.SomeDatabase.Facade.dll.
5. Compile assemblies dependent upon the above.

There are some simple algorithms that I use to determine whether a stored procedure is a read-single, read-multiple, create-new, or something else entirely.  I leave the discovery of this as an exercise to the reader.

My nant build target looks something like the following.  I re-used the [Voyager SDK’s CodeSmith "codegen" task] to kick everything off.  Note that all I need is a connection string …

<target name="codegenDatabaseWrappers">
 <property name="databaseList" value="SomeDatabase"/>
 <echo message="databaseList = ${databaseList}"/>
 <foreach item="String" delim="," in="${databaseList}" property="database.name">
  <do>
   <property name="databaseWrapper.outputFile" value="${database.name}Database.g.cs"/>
   <delete file="DatabaseFacade\DataMapper\${databaseWrapper.outputFile}" failonerror="false"/>
   <codegen template="DatabaseFacade\DataMapper\DatabaseWrapper.cst" outputdir="DatabaseFacade\DataMapper" outputfile="${databaseWrapper.outputFile}">
    <properties>
     <property name="ConnectionString" value="user=${DB_Login};password=${DB_Password};server=${DB_Server};database=${database.name}"/>
    </properties>
   </codegen>
  </do>
 </foreach>
</target>

Scott: Certainly there are dozens (hundreds?) of ways to generate a Database Access Layer (DAL) as there's lots of opinions as to how they should look and what's the best style. The point here is that if your database is nice and regular and needs CRUD (Create, Read, Update, Delete) then there's really no reason you shouldn't be able to generate your DAL (and often even sprocs) from either your sprocs, tables and/or views. You'll lose nothing and gain so much more time, especially in a Continuous Integration environment.

File Attachment: DatabaseWrapper.cst.txt (14 KB)

Unrelated Quote of the Day: "I can't be racist, I drive a Prius!"

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Elder Scrolls - emulated in a Dos Box

April 12, '06 Comments [5] Posted in Gaming
Sponsored By

ElderscrollsarenaThe Elder Scrolls IV - Oblivion is amazing. Buy it. This is the game that the Xbox 360 was made for. This is the Halo 2 launch game that the 360 was missing. It's hardcore enough for the RPG-familar, and casual enough for my wife and I who play thirty minutes at a time. That's my review. There's nothing more to be said.

Ah, but the originals. The original Elder Scrolls - Arena is available for free download on the 10th anniversary side.

However, Window's DOS Support, particularly its extended memory support, leaves something to be desired, so you can (have to) download a DOS Emulator.

"DOSBox emulates an Intel x86 PC, complete with sound, graphics, mouse, modem, etc., necessary for running many old DOS games that simply cannot be run on modern PCs and operating systems, such as Microsoft Windows 2000, Windows XP, Linux and FreeBSD. However, it is not restricted to running only games. In theory, any DOS application should run in DOSBox, but the emphasis has been on getting DOS games to run smoothly, which means that communication, networking and printer support are still in early developement."

In order to get Arena running on my Home PC I needed to change the following values in my DOSBox.conf file:

core=dynamic
frameskip=2
cycles=20000 #YMMV, so use CTRL-F12 to find the right value for you
output=opengl

060322_1gYou'll also need to "mount" your ARENA folder in DOSBox when running:

mount c c:\arena
c:
arena

Very slick, the emulator maps/emulates a SoundBlaster! Ah, SET BLASTER=A220 I7 D1 H5 T6, we hardly knew ye. It's so funny, though, how we remember the graphics being SO awesome at the time...gaming now and then...

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Accessing the Registry from the Command Line

April 12, '06 Comments [1] Posted in Podcast | PowerShell
Sponsored By

In my recent "Utilities you didn't know you had" podcast, I realize now I totally forgot about REG.EXE.

I was reminded while browsing James Manning's blog

From CMD.EXE, this tells you where VS.NET 2005 is installed:

C:\>reg query HKLM\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS /v EnvironmentDirectory

Here's the same thing in MSH (gp is the alias for get-property):

MSH C:\>$(gp HKLM:\Software\Microsoft\VisualStudio\8.0\Setup\VS).EnvironmentDirectory

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.