Tuesday, December 18, 2007

Bundling an ASP.NET web site and its content into one DLL

One of the design criteria of Project Melbourne is to have the entire editing framework contained within one DLL for ease of deployment into an existing ASP.NET web site. The reason for this is that when we want to install the framework into an existing web site, we don't want to have someone need to follow a long list of instructions on what files to copy where, dealing with name conflicts, specific file versions, etc.

There are some exceptions to that criteria, such as files used for licensing certain redistributed software, and also the database.

However, there is a relatively easy way to combine the ASCX User Controls, ASPX Pages, HTML files, images, etc. that exist in an ASP.NET Web Project into a DLL. This post will be expanded, with examples, however in the meantime, and so I don't lose these links, these pages were instrumental in achieving the design criteria.

Use XML in SQL Server 2005

If you haven't yet seen the built-in XML capabilities of SQL Server 2005, take a look at this document from Microsoft, it's a walk-through that will ease you into the concept.

First, install the AdventureWorks full sample database for SQL Server 2005 (AdventureWorksDB.msi): http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004

Then, the walkthrough document: http://download.microsoft.com/download/c/4/3/c4320e49-f8fb-44f0-b00f-d3cee272b5dc/sqlhol112%20-%20sql%20server%20-%20xml%20capabilities.doc

An Errata (some of the document may be from the SQL Server Yukon days):
  • Instead of SELECT * FROM sys.xml_namespaces on page 7, try sys.xml_schema_namespaces.
  • Instead of:

    SELECT TOP 10 Demographics.query('
    declare default element namespace=
    "http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey" /IndividualSurvey/YearlyIncome') FROM Sales.Individual

    ... try:


    SELECT TOP 10 Demographics.query('declare default element namespace
    "http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey";
    /IndividualSurvey/YearlyIncome')
    FROM Sales.Individual
  • (next)

Some notes:

Monday, December 10, 2007

Enabling SQL Service Broker in SQL Server 2005 Express

A piece of project Melbourne seems to crave the features provided by the SQL Service Broker and the SqlCacheDependency of .NET 2.0. It's the fact that we're using data that doesn't change all that often and we want to avoid going to the database each time to look it up.

Off we go, the first thing to do is to enable Service Broker in the database, since by default it is disabled. If you don't believe me, try this query that shows whether the broker is enabled or not in each of your databases:

USE master;
SELECT name, is_broker_enabled FROM sys.databases;

Then, the code to enable the Service Broker in your database is:

USE master;
ALTER DATABASE melbourne SET ENABLE_BROKER;

Now, after watching that little green dot chase its tail for about 5 minutes, not seemingly getting anywhere, I found this blog post, where the solution was in a comment - this query will not complete if other connections are open to the database! So be sure you have no other windows open in the Management Studio and that users are not connecting to this database.

Monday, December 3, 2007

Project Melbourne Kick Started!

After messing with way-too-overcomplicated CMS's, I've decided to make my own. Dave and I are going to be working over the next few weeks on a version 1.0 that will hopefully become the editing system that I use in new web sites that I create and host.

We're tackling it using an Agile approach (or as Dave says, a
do-exactly-what-is-good-enough-right-now-and-no-more approach) with one-week iterations. We've done some preliminary research on which HTML editor we're favouring and we like CuteEditor. We've got a rudimentary login system in place, and Dave already has an inside track on bundling resources into a DLL (one of our design guidelines).

I'm pumped!

Sunday, December 2, 2007

Screencasting as Video Documentation

If you're new to screencasting, it's a video capture of a computer screen with the narration of the person who is capturing the video. Take a look at one of the video help screens that I did for the High Q Greenhouses web site editing system: How to Edit Text.

The software that I use is called Camtasia Studio. I recall some sort of promotion they have during Christmas where you can get a free copy of one of their older releases. Ping me back for that and I'll dig it up!

You're probably aware of the video help that I have created in the past. I created some video help files for Alberta Advanced Education & Technology a few months ago to walk through the implementation, setup, architecture and documentation of a web security system that I created for them.

Security Video Documentation

I presented them at the ISWG meeting where architects and developers on other teams saw some excerpts. Some of them had not seen screencasting before, and I was glad to share the concept with real examples. I remember Darcy, who had just taken over that security project from me, said "they're awesome". Thanks, Darcy - no, you're awesome!

I don't own the IP rights to the videos, so I'll have to describe them. Hopefully this will kick start your imagination for what you could use such a medium for in your work!

The video describing the implementation was very interesting. I used the video to go through the Visual Studio project structure, Also the code, pretty much line by line - this was great to talk about the smallest of details that would have taken much too long to type comments for, but were nevertheless important. Also, I went through the configuration file and what things were important and what things weren't.

There was a video on workstation setup, which tackled some strange issues involving permissions and group membership for identity accounts. Perfect material for a video, because who wants to read documents! Also, the why was explained at the same time as the what, which I'm sure would start to bring a new developer into the game faster.

The architecture video walked through the architecture document and explained the diagrams and brought the text and pictures together as I scrolled through a Word document on the screen.

Web Site Editing Video Documentation

The latest videos that I produced were for the office administration staff at High Q Greenhouses, the latest web site that I have set up. Various tasks like adding images to a photo gallery and adding news items are all covered. Hey, beats writing help documentation!

Video Documentation as a Solution

So how far does this solution go towards solving the documentation problem? Truth is that it suffers from the same problem that all other forms of documentation do, so it's no worse off. It's my opinion that in the right situations, for the right audience, it's just killer!!! Conveying complex code, long-running sequences of events, etc. It has a place in my toolbox for sure.

Production Tips

Here are a couple of reminders for producing a good screencast:
  1. Start with good equipment. Get a good microphone.
  2. Plan the presentation. Jot down a couple of notes for yourself and rehearse a little bit.
  3. Turn off things that are going to distract you like IM programs, your cell phone, etc.
  4. Remember: show and tell.
  5. Keep your mouse movement and scrolling to a minimum, it's distracting to watch afterwards.
  6. Talk slowly.
  7. When you make a mistake, just reposition everything on the screen to a point where you could erase to, and re-do the sequence you just did. Afterwards, you can just cut out the part you missed - chances are that the frame rate will hide the jump from one cut scene to another. Worst case, you could create a transition.
  8. EDIT. Trim the fat. Tighten up empty air by cutting it out. Cut out the audio where you are saying "um" etc.
  9. Try to keep the produced file size low. Record at 800x600 and downsize the production to 640x480. Use flash video (custom settings), MP3 encoding, 16-bit color, JPEG compression at 50%, 5 FPS.

Good luck and have fun!

NullReferenceException when using a Threading Timer with a dueTime of 0

I found a very interesting behaviour the other day when working with some multithreaded code. Take a look at the following example:


Module Module1

Private Ticker As System.Threading.Timer

Sub Main()
' Construct a timer with a dueTime of
' 0 so that it is called immediately.
Ticker = New System.Threading.Timer( _
AddressOf DoThreadedWorkJustOnce, _
New Object, _
0, _
System.Threading.Timeout.Infinite)
End Sub

Sub DoThreadedWorkJustOnce(ByVal state As Object)
' Reset the Ticker so that it
' doesn't get executed again.
Ticker.Change( _
System.Threading.Timeout.Infinite, _
System.Threading.Timeout.Infinite)
' Do actual work...
End Sub

End Module

What this module does is when it starts execution, it spawns another thread using a System.Threading.Timer object. The other thread is to start work immediately, with a dueTime of 0. Looks harmless enough.

But there's a subtle problem. It's that the Timer object can become instantiated, and the other thread can start executing, before the Timer object can be assigned to the local variable Ticker. What you can end up with in the DoThreadedWorkJustOnce method is a NullReferenceException.

Very interesting!

So what's the solution? Here's one way:



Module Module1

Private Ticker As System.Threading.Timer

Sub Main()
' Construct a timer with a dueTime of
' 0 so that it is called immediately.
Ticker = New System.Threading.Timer( _
AddressOf DoThreadedWorkJustOnce, _
New Object, _
System.Threading.Timeout.Infinite, _
System.Threading.Timeout.Infinite)
Ticker.Change( _
0, _
System.Threading.Timeout.Infinite)

End Sub

Sub DoThreadedWorkJustOnce(ByVal state As Object)
' Reset the Ticker so that it
' doesn't get executed again.
Ticker.Change( _
System.Threading.Timeout.Infinite, _
System.Threading.Timeout.Infinite)
' Do actual work...
End Sub

End Module


I suppose you could have instead changed the declaration line of Ticker to the double-infinite statement. You could have also wrapped the assignment in a synclock and then have another synclock inside the DoThreadedWorkJustOnce method on the same locked object.