Tech Blog

Jay's Technical blog

GRDD - We 'R Published...

30 January 2008
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

Joe and I have been working in secret on the first edition of our  GRDD (Git 'R Done Development) book.  No one knew about it until we started looking for a publisher.  We are happy to announce that O'Reilly saw a prime opportunity to publish a book that presents a clear and concise reference to GRDD by it's creator (Joe) and its chief evangelist (me).

Here's the cover page...

image

Here's the link.


Hah! Gotcha! D-Coder sent the link to a fairly useless but fun item over at O'Reilly.  Basically it's an image maker that let's you create any book cover... wanna create "Mud Stomping for dummies"  Have at it.

IE8 Thoughts...

28 January 2008
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

Bertrand Le Roy had a post over the weekend (actually Friday, but I missed it) about the new IE8 meta-tag fix for standards mode... Well, Bertrand through support for the author over at ArsTechnica.  As a web guy I have given this all some thought.

First of all so you don't have to slough through the 2 pages on ARS let me give you the summary version:

  • IE 5.5 and before was very standards non-complaint.  It had numerous rendering issues that web designers had to figure out how to work around.
  • With IE6, MS tried to fix this by using the DOCTYPE attribute of the page to switch between "standards mode" (the more standard compliant, but not fully compliant IE) and "quirks mode" (the less standard more in line with the way IE used to work).  "Quirks mode" was the default if there was no DOCTYPE or if there was an older DOCTYPE
  • The IE7 came, and MS used the same 2 mechanisms.  The problem was two-fold.  Alot of web design tools go ahead and push in a DOCTYPE, effectively turning off "quirks mode." 
  • The second issue was that IE7 fixed some of the standards renderings, but also created issues where designers had worked through an issue with IE6, and now it was either fixed in IE7 giving an awful rendering of the page (or in some case --I imagine-- IE7 broke something that was working)
  • The IE team has the mentality that they don't want to "break the web." (Hurray for you guys)
  • With IE8 the suggestion is that a new mode will be introduced that will be handled via a meta tag.  The meta tag would effectively create a new "IE8" standards mode... and any future versions of IE would respect this mode render it in an "IE8 standards" mode (which begs the question will there be an IE9 standards mode and an IE10 mode, etc.

I think IE becoming more standard compliant is a good thing.  Even if it means that IE x.0 breaks IE (x-1).0's renderings.  I know this is a pain (I have been there).  I have also written about my pains with other browsers (most notably Safari... FireFox has never really given me fits, FWIW).  I'm not certain this is a good idea.  Well, I don't think expanding IE's size over the next few versions is a good idea.  I wonder if it wouldn't be possible for us to create an archive of IE browsers and somehow notify IE what we have... also what is the point of reaching back to several old versions (that's what I read into this proposal).  Wouldn't one version do the trick?  I mean if IE8 breaks a web site that was all the rage in the IE4 days isn't that OK?  I mean I own software that old... but I don't use it for anything too critical and if it doesn't run on my Windows Vista machine I am perfectly OK with that (it's old... use a VM or in this case an older browser).

Just my thoughts...


LINQ to SQL in under 15 minutes...

23 January 2008
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

This is the first in what I hope becomes a series of video/blog posts from me.  My goal with this video/post is to provide a 10-15 minute video (or text you can read quickly) that covers LINQ to SQL.  You'll learn how to set up the environment, how to do a select from the database, and finally how to save your changes back to the database.  You will NOT learn everything, but this should be a great starting point (if someone wants to copy this format for a video/post on some other topic, please feel free).  So start your stop watch... 13.5 minutes from now you will be knowledgable in LINQ to SQL.

Video

The video runs in 13.5 minutes (sorry I wanted to do it in 10 minutes or less but I couldn't without removing content or sacrificing the demo... the first title for the post was "LINQ to SQL in 5 minutes" that ended up being too ambitious).  Also this is my first demo so please forgive the slight clicking noise (I will get better at this)...

Direct link to the video

Background

Everyone has their pet project that they try to build with a new technology.  My pet project happens to be a lightweight content manager.  For this demo/post we will be building simple lightweight content control that is given a pagename and a contentkey and will retrieve the appropriate html from the database and will place this on the screen.  It will also provide a logged in user with the admin role access to an editor (in this case a text area) where this content can be edited and updated in the database.  It will do an insert if no content exists yet (that way the programmer can add content controls as needed).  Caching of content will be seen but not described in the demo.  Also, the database is a variation of one that I pretty much always use, so not much will be explained about it's creation... the focus afterall is LINQ to SQL.

Step 1 - Create LINQ to SQL Classes (map)

First step is to create LINQ to SQL Classes DBML file.  If you are creating this directly in the project as I am you'll want to add this to App_Code (or if you are using Web Projects you can create it anywhere -- I think...). 

LINQ to SQL Classes (add item) dialog

The dialog for adding a LINQ to SQL Classes item

DBML designer

First of all sorry that this is image is so large (but I wanted you to be able to read it).  Essentially all you need to do drag tables from the server explorer over to the tables area of the dbml (LINQ to SQL Classes) designer.  There's also an area for procedres, but we will not look at that right now. Our surface has 4 tables: cms_Content, cms_ContentType, cms_ContentPage, and cms_Site.  Site will contain the various sites (so 1 database can house the data for multiple sites), ContentPage contains the pages names we will be using, ContentType contains the types of content we will support (right now the only content type is HTML), and finally Content contains the actual content.

We will spend much of our time in the next section where we will retrieve content and will store that content in the database.

Step 2 - Creating a ContentSupport class

Next step is to go into App_Code (or anywhere if you are using a Web Project), and create a new class called ContentSupport.  We'll be creating a class that can read/write the content. Initial code will look like this:

  1:using System;
  2:using System.Data;
  3:using System.Configuration;
  4:using System.Linq;
  5:using System.Web.UI;
  6:using System.Data;
  7:using System.Data.Linq;
  8: 
  9:publicclass ContentSupport
 10: {
 11:privatestring SiteName { get; set; }
 12:publicstring PageName { get; set; }
 13:publicstring ContentKey { get; set; }
 14:private Page page;
 15: 
 16:public ContentSupport(String SiteName, String PageName, String ContentKey, Page page)
 17:     {
 18:this.SiteName = SiteName;
 19:this.PageName = PageName;
 20:this.ContentKey = ContentKey;
 21:this.page = page;
 22:     }
 23:
 24:publicstring GetHTMLContent()
 25:     {
 26:     }
 27: 
 28:publicvoid SaveHtmlText(string ContentValue)
 29:     {
 30:     }
 31: }

I went ahead and included all the Namespaces we will need.  Beyond that we have a couple properties (the key information that we will need to query the database for our content).  The consturctor let's us pass this information in and also a reference to the page.  This is so we can get to the page's Cache object (which we aren't explaining in detail).

We also have the methods for retrieving the HTML and saving it back although we haven't written these methods yet.

Step back

Before we continue I need to step back for a second and explain something that we gained when we created that DBML file (the LINQ to SQL Classes).   We created a whole bunch of new types.  The most important of which is a derivative DataContext class.  In my project this class is called "CMSDataContext."  This class encapsulates all our communications with SQL Server.  It's similar to the Database object in Enterprise Library except that it does more.  One of the things it gives is Get methods that will retrieve data from a table (well at least one of the tables we dragged over).  If we have a CMSDataContext instance we can simply call "instanceOfCMSDataContext.GetTable<cms_ContentPage>()" this gives an instance of a Table<cms_ContentPage>.  This generic provides a way that we can interact with the table via LINQ and when the query is executed then the database will actually be contacted (LINQ queries don't actually execute until the results are used).  So this DataContext class is extremely important for our use.  The next thing we want to do then is to create a way to get the CMSDataContext. So Let's add a property to manage this for us.

  1:private CMSDataContext _ctx = null;
  2:private CMSDataContext ctx
  3: {
  4:     get
  5:     {
  6:if (_ctx == null)
  7:             _ctx = new CMSDataContext(ConfigurationManager.ConnectionStrings["IntraD"].ConnectionString);
  8:return _ctx;
  9:     }
 10: }

Our derived DataContext has a way to provide a connectionstring (which means we can easily swap in a different ConnectionString if need be).

Reading data (simple)

In the save routine I need to retrieve the ID for the HTML content (so I can use it for inserting/updating data).  Here's the important code:

  1: Table<cms_ContentType> ContentTypes = ctx.GetTable<cms_ContentType>();
  2: 
  3:int? contentTypeID = (from ContentType in ContentTypes
  4:where ContentType.ContentTypeDescription == "HTML"
  5:                       select ContentType.ContentTypeID).FirstOrDefault() asint?;

As you can see I am using the DataContext to get the cms_ContentType table int a variable called ContentTypes.  I could have skipped this step and simply used the ctx GetTable right in the LINQ query.  The LINQ just seems easier to read to me this way.  If you have done much LINQ the query should seem fairly simple to you.  Essentially gets the ContentTypeID from the record in the cms_ContentType table that has a description of "HTML."  We call FirstOrDefault() to return the first value (believe it or not this will return an array.. I should have probably used one of the other Select methods, but I wanted to show off some of the tools you have at your disposal).  The value is then cast to a nullable int and giving us the first int that gets returned (we should really only receive one, but that's because of our table structures).

Writing data (insert)

Writing data back to the database is a little trickier, but not that tricky.  We do need to handle things differently for inserts versus updates.  Let's look at the insert code first.

  1: ctx.cms_Contents.InsertOnSubmit(new cms_Content()
  2:                {
  3:                    PageID = pageID.Value,
  4:                    ContentKey = this.ContentKey,
  5:                    ContentTypeID = contentTypeID.Value,
  6:                    ContentValue = ContentValue
  7:                });
  8: ctx.SubmitChanges();

The insert takes advantage of the DataContext (again).  Actually an instance of the derived/specialized CMSDataContext contains a cms_Content object that contains some methods for adding a new object, and will insert when the DataContext is submitted.  This creates a cache of changes that will all be submitted at once (this lets you make a couple changes and then submit the results to the database).

Writing data (update)

Writing data back is equally easy.  Here's the code:

  1: cms_Content updatedRow = ctx.cms_Contents.Single(c => c.ContentID == contentID);
  2: updatedRow.ContentValue = ContentValue;
  3: ctx.SubmitChanges();

We simply retrieve a row using the same cms_Content object that is a property of our data context, set the valuefields we need to update and then call ctx.SubmitChanges to save the data back to the database.  BTW, that call to cms_Content.Single call retrieves a single row from the database using the Lambda expression.

Read Data (complex)

If you paid attention you probably have realized that a we need to query more than just the cms_Content table.  We have the SiteName which is really the SiteName field in the cms_Site table, the PageName which is really the PageName field in the cms_Page, and the ContentKey which is in the cms_Content table.  cms_Content has a PageID and a SiteID.  It would also be nice to factor in that we only want to handle HTML content.  Well, the good news is that joins are possible with LINQ (and LINQ to SQL).  Here's what it looks like:

  1: Table<cms_Site> Sites = ctx.GetTable<cms_Site>();
  2: Table<cms_ContentPage> ContentPages = ctx.GetTable<cms_ContentPage>();
  3: Table<cms_Content> PageContents = ctx.GetTable<cms_Content>();
  4: Table<cms_ContentType> ContentTypes = ctx.GetTable<cms_ContentType>();
  5: 
  6: var ContentObject = (from Site in Sites
  7:                      join ContentPage in ContentPages
  8:                        on Site.SiteID equals ContentPage.SiteID
  9:                      join HtmlContent in PageContents
 10:                        on ContentPage.PageID equals HtmlContent.PageID
 11:                      join ContentType in ContentTypes
 12:                        on HtmlContent.ContentTypeID equals ContentType.ContentTypeID
 13:where
 14:                        Site.SiteName == SiteName &&
 15:                        ContentPage.PageName == PageName &&
 16:                        HtmlContent.ContentKey == ContentKey &&
 17:                        ContentType.ContentTypeDescription == "HTML"
 18:                      select new { HtmlContent.ContentValue, HtmlContent.ContentID });

As you can see this query is a little more complex, but not so much so if you are familiar with SQL.  We're joining 4 tables together.  Primarily we are doing this via the table's ID column.  We then use each of the parameters (PageName, SiteName, and ContentKey) in the where clause.  Finally we are returning an anonymous type that contains the HTML content and the ContentID (we use the latter for caching, so we don't have to run this query often).

I have attached the code to this post.  The only change you may want to make is that the code should auto add page's if the page name is not found (making life a little more convenient for the developer).

[Since LINQ to SQL was the focus here I'll leave the User Control code for you to take a look at on your own.  One thing to note.  The attached project has example controls that have as an editor: a TextArea, FCK Editor v2.5 control, FreeTextBox v3 control, and an OpenWyswyg control... Eventually I'll publish a FreeTextBox4 version (and other free controls).]

Attached File: DTCMS.zip


Wow! Someone gets it!

22 January 2008
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[This post is in response to a post (actually a couple posts) that Roy Osherove has recently posted on TypeMock... go read it first].

Roy is hitting right into what I was trying to say all those years on CodeBetter when I was "battling" a few of my then co-bloggers. It's the dogmatic aspects of TDD that scare many of us.

Not only that one has to do TDD, but to do it as a "way to a better architecture" which implies that "thou shalt always use pattern x."  I have argued many times over... what if what I'm doing is fairly trivial or there is no need for a large architecture (yet).

Roy's post is a defense of TypeMock, but in the midst of talking about it's ability to lure non-agilist's over he makes this statement (copied directly from his blog):

agile is about embracing what works for a particular team...

That's sounds like a very GRDD (Git 'R Done Dev) statement...

As a (for the most part) non-agilist have gravitated to MbUnit as a unit-testing framework (I still test after design). MbUnit appears to be extremely pragmatic and extensible which is what I need. 

I have looked at the mocking frameworks, but the fact that they impose certain tenets of the TDD faith (AKA imposed patterns that are ALWAYS used to make things more "testable"), I have yet to use any of them.  I just installed TypeMock, and will be using it soon...


Missing Gunderloy's Daily Grind? How about an alternative?

18 January 2008
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I have to say that until recently I have really missed Mike Gunderloy's Daily Grind.  I respect his reasonings for moving on (even if I don't agree 100% with him).  He always had a good way of distilling the news for me.  And often found things before I could read them elsewhere.

There are a few others out there, but one recently linked to a blog post of mine and I would like to draw your attention to it.  It has replaced the Daily Grind in my RSS reader, and since I found it I don't miss Mike's daily blog as much...

It's called "The Morning Brew", and it's by Chris Alcock.  I like that he not only links but breaks everything up by category and also has a little comment next to each (just like Mike did).

I also read Jason Haley's Interesting Finds, but Jason evidently hasn't discovered Chris yet (maybe he will now... I doubt it since I don't think he reads my blog).