January 2005 - Posts

Microsoft Architecture Journal 4 Out Now

From the Blog Clippings Category The Microsoft Architects Journal 4 is now available here as a pdf. The table of contents lists these articles.
  • Choosing the Right Presentation Layer Architecture
  • Information Bridge Framework
  • Benchmarking a Transaction Engine
  • Enterprise Architecture Alignment Heuristics
  • Razorbills
  • Next Generation Tools for OOD
with 1 Comments

Adapting The Virtual Cellar Domain Objects to .Net using the ObjectDataSource

I've been ever so slowly adding new .Net 2.0 features to the Virtual Cellar code. The most apparent changes are driven by the use of ASP.Net 2.0 features, most notably the GridView control and the new suite of DataSource controls.

I wasn't too happy to see the introduction of the SqlDataSource control, I thought it just encouraged bad layering practices, allowing the population of the new Data Controls through straight ahead SQL statements. Sure, I could setup a stored procedure and call that with the SqlDataSource control, but I was still programming to the database. It just felt wrong.

So, I was rather dejected, I really wanted to use the new GridView control in my application. That's when I found out about the ObjectDataSource control. There's a great MSDNTV Episode that talks about this. This was the perfect solution. I would be able to use my Domain Objects directly with the GridView control. There was only one problem, the object used as the data source needed to have a default contructor.

As you may (or may not) remember, I based the Virtual Cellar model on the Repository Pattern. Unfortunately, I based my domain objects on a base class, RepositoryItemBase, that does not allow for a default constructor, instead it includes a reference to the RepositoryFactory, should any of the classes such as the Wine class need to expose properties of another aggregate root (Producer). Part of this was to get around the problem of having a reference to the ProducerRepository in the Wine class, instead a request would be made to the RepositoryFactory to generate a Factory instance (in this case a ProducerFactory) for re-hydrating the Producer class from the ProducerRepository, from information stored in the Wine class.

The short answer, is that I am unable to use the ProducerRepository as an ObjectDataSource, because it does not support a parameterless default constructor. So my immediate fix is to create an adapter class ProducerDataSource that wraps the functionality of the ProducerRepository, yet has a parameterless default constructor to satisfy the requirements of the ObjectDataSource.

Here's a shot of the class diagram modeled in the new VS2005 diagram tool.

As you can see, I've defined only one method "SelectByName" for the purpose of my testing. The method takes a string that is used for matching on the Producer.Name field. It simply calls the QueryByName method in the repository, which maps to the GetByNameAsDataReader in the IProducerProvider interface. This example is using the OleDbProducerProvider for the purposes of acting on an OleDb data source.

I've used another 2.0 feature (Generics) to return a IList<Producer> from the ProducerDataSource.SelectByName method. The GridView can now take this IList<Producer> and map it to grid columns.

Here's a quick code excerpt that illustrates the ProducerDataSource object and the ProducerGridView interaction.

<form id="form1" runat="server">
  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
  <asp:Button ID="Button1" runat="server" Text="Button" />
  <asp:GridView ID="ProducerGridView" runat="server" DataSourceID="ProducerDataSource" AutoGenerateColumns="False">
    <Columns>
      <asp:BoundField HeaderText="Id" DataField="Id" SortExpression="Id"></asp:BoundField>
      <asp:BoundField HeaderText="Name" DataField="Name" SortExpression="Name"></asp:BoundField>
      <asp:BoundField HeaderText="Address" DataField="Address" SortExpression="Address"></asp:BoundField>
      <asp:BoundField HeaderText="City" DataField="City" SortExpression="City"></asp:BoundField>
      <asp:BoundField HeaderText="State" DataField="State" SortExpression="State"></asp:BoundField>
      <asp:BoundField HeaderText="Country" DataField="Country" SortExpression="Country"></asp:BoundField>
      <asp:BoundField HeaderText="PostalCode" DataField="PostalCode" SortExpression="PostalCode"></asp:BoundField>
    </Columns>
  </asp:GridView>
  <asp:ObjectDataSource ID="ProducerDataSource" runat="server" TypeName="Lorengo.VirtualCellar.Business.ProducerDataSource"
    SelectMethod="SelectByName">
    <SelectParameters>
      <asp:ControlParameter Name="name" ControlID="TextBox1" PropertyName="Text" DefaultValue="Robert Mondavi"
        Type="String" />
    </SelectParameters>
  </asp:ObjectDataSource>
</form>

You'll notice that the ObjectDataSource has a SelectMethod attribute which maps to the SelectByName method on my ProducerDataSource. Also the <SelectParameters> node maps the TextBox1 controls Text property to the "name" parameter of the method. This allows the user to enter a value in the text box to search for.

The resulting pages looks like this

Unfortunately, the page does the query when it is loaded, so the DefaultValue attribute of "Robert Mondavi" is used and displayed. What I would like to do is prevent the initial lookup from occurring, presenting the user with just a search box and button. Does anybody know of hand how to accomplish this?

In the meantime, I'm going to revisit my Repository / DataSource classes and see if I can't come up with a better solution. Now that I know there is an easy way to utilize my business objects with the data controls, I'm excited.

with 2 Comments

Creating a MasterPage for the Virtual Cellar

I've begun creating the website that will house the Virtual Cellar data model and form the main user interface for the application. My next couple of entries will pertain to some initial tasks that need to be done so that I start hanging pages on the website. In this entry I'll discuss the setup of the site master template for the Virtual Cellar.

The General Layout

I plan on having a three column layout along with a header section, as illustrated in the picture below.

There are four major sections

  • Banner
    The Header section will contain the application title bar as well as the main menu navigation for the application
  • ContextBar
    The ContextBar will contain information that will vary depending on the context of the application. For example, if the user is not logged in, it will contain a username, password prompt. If the user is logged in, it could contain statistics about her account, an overview of her cellar statistics or latest headlines via rss feeds.
  • Main
    The Main section will be where the user spends most of her time interacting with the application. The content of the section will be the data pulled from the Virtual Cellar catalog in the form of reports or where the user will enter new information into the Virtual Cellar.
  • SideBar
    The sidebar section is where items of interest will be displayed depending on the type of information being displayed in the main section. These could be Google AdSense links, or links to items for sale on Amazon and eBay.

Creating The MasterPage

In Visual Studio, I create a new MasterPage template by Right-Clicking on the web project and select to add a New Item. I'm then presented with the following dialog box.

After adding the VirtualCellar.master file to the project, I'll go ahead and create the following <div> tags that define each of the sections.

<body>
<form id="MainForm" runat="server">
  <div id="Banner">Banner
  </div>
  <div id="ContextBar">ContextBar
  </div>
  <div id="Main">Main
  </div>
  <div id="SideBar">SideBar
  </div>
</form>
</body>

The next step is to add the <style> section to arrange the <div> sections in the order above

<head>
<style type="text/css">
	body {
		margin:10px 10px 0px 10px;
		padding:0px;
	}
	#Banner {
		background:#fff;
		height:70px;
		border-top:1px solid #000;
		border-right:1px solid #000;
		border-left:1px solid #000;
		voice-family: "\"}\"";
		voice-family: inherit;
		height:69px;
	}
	html>body #Banner {
		height:69px;
	}
	#Banner p {
		font-size:14px;
		padding:10px 10px 0px 10px;
		margin:0px;
	}

	#ContextBar {
		position: absolute;
		left:10px;
		top:80px;
		width:200px;
		background:#fff;
		border:1px solid #000;
	}

	#Main {
		background:#fff;
		margin-left: 199px;
		margin-right:199px;
		border:1px solid #000;
		voice-family: "\"}\"";
		voice-family: inherit;
		margin-left: 201px;
		margin-right:201px;
	}
	html>body #Main {
		margin-left: 201px;
		margin-right:201px;
	}

	#SideBar {
		position: absolute;
		right:10px;
		top:80px;
		width:200px;
		background:#fff;
		border:1px solid #000;
	}
</style>
</head>

You may notice the use of the infamous "voice family" hack, this is to get around the various browser bugs or interpretations of the css box model. This code also allows us to view our layout semantically. For the longest time I did layout using tables, little did I know that was a major crime according to the css folk. This article on retooling slashdot with css got me hooked on using css for layout. Another great site is the CSSZenGarden, but I digress. The above css code will give us the nice layout we set out to construct.

Creating a New Page Based on The Master

Now that I have the VirtualCellar.master page created, I can begin using it in new pages that I create. So I'll right click on my web project and select Add New Item. I'm present with the same dialog box as before, but this time I choose, Web Form. I also check the box that says Select Master Page. After selecting Add, a listbox containing all of the defined MasterPages are shown, and I select VirtualCellar.master. A new file Default.aspx is created that contains the following code.

<%@ Page Language="C#" 
    MasterPageFile="~/VirtualCellar.master" 
    CodeFile="Default.aspx.cs" 
    Inherits="Default_aspx" 
    Title="Untitled Page" 
%>

And the output looks like this!

Next time I'll look at adding a menu to the application using the new <asp:Menu /> and <asp:SiteMapDataSource /> controls

with 2 Comments

Setting Up The December CTP VSTF

1.1      Setting Up The December Team System Preview

I've recently downloaded the Microsoft Visual Studio Team System December CTP from MSDN, and have begun the process of setting up the full blown system. I’m using a Dell PowerEdge 2550 Dual P3-1Ghz system with 2GB of memory running Virtual Server 2005. The plan is to setup 2 virtual machines running Windows Server 2003 each having 640 Mb of memory.

 

Here’s how it will break down

Ø      Hercules: The Dell rack server configured with Window Server 2003, running Virtual Server 2005, DNS, and Active Directory for the “LanThrash” domain.

Ø      Hades: The first Virtual Server that will function as the “Data Tier” for the Visual Studio Team System.

Ø      Hermes: The second Virtual Server that will function as the “Application Tier” for the Visual Studio Team System.

I'll be following the instructions found here http://go.microsoft.com/fwlink/?LinkId=40042&clcid=0x40

1.1.1      Configuring Hercules for VSTS

Not much needs to be done since Hercules is already setup as the Domain Controller for the LanThrash domain.

1.1.1.1  Create New Domain Users in Active Directory on Hercules

Start/Administrative Tools/Active Directory Users and Computers/Domain/Users/New/User

Add TFSSetup

Add TFSService

1.1.2      Configuring Hades for the Data Tier

1.1.2.1  Add New Domain Users to Local Administrator Group on Hades

Start/Administrative Tools/Computer Management/Local Users and Groups/Groups/Administrators/Add to Group...

Add LanThrash/TFSSetup

Add LanThrash/TFSService

1.1.2.2  Install IIS 6.0

Start/Adminstrative Tools/Manage Your Server/Add or Remove a Role

Add Application Server Role

Enable ASP.Net

1.1.2.3  Install Microsoft SQL Server Beta 2

Download Microsoft SQL Server Beta 2 from msdn subscriptions

Use the Virtual Server 2005 Administration website to mount the .iso file to the Hades CD/DVD Virtual Drive

Run the Install Program

Follow the instructions "How to: Install Microsoft SQL Server 2005 for the Team Foundation Data Tier" in the setup guide

Reboot the server

Finish installation of SQL following the "How to:"

1.1.2.4  Install VSTS Data Tier on Hades

Logon to Hades with the TFSSetup user

Run the Data Tier Setup program following the prompts. (Note: Apparently you can’t mount an .iso file larger than 2.2Gb under Virtual Server, so I used the Virtual CD-ROM Control Panel to mount the .iso file on Hercules, and then copy the /VSTS/DT folder to Hades directly. Apparently you cannot share a mounted .iso either, the other work around was to add the mounted drive on Hercules as a resource to the Hermes machine, but I couldn’t get that to work on Virtual Server)

1.1.3      Configure Hermes for the Application Tier

1.1.3.1  Add New Domain Users to Administrators group on Hermes

Same as Hades

1.1.3.2  Install IIS 6.0

Same as Hades

1.1.3.3  Install Windows SharePoint Services

Download and run Windows SharePoint Services with SP1

Choose the Typical Install

1.1.3.4  Logon to Hermes under the LanThrash/TFSSetup user

1.1.3.5  Run the Setup program according to the directions

It should be noted that I had a couple of problems while doing the install. First this one, while trying to find the Data Tier databases, but it went away, for whatever reason. The next one was an Error 3200, which someone else reported here, I simply hit Retry and it worked, although another solution or cause was having a website running on the same port 8080, that Team System was attempting to use.

1.2      Conclusion

All in all it went rather smoothly, of course this was over a period of a couple of days as I had to configure my new domain, and all my other miscellaneous client computer, etc. I’ll now perform the straight ahead installation of the Client Tier on my Dell Optiplex, but that should be easy J

with 2 Comments

Vonage So Far So Good

Well, I got fed up with Qwest charging me over $50 a month for my local & long distance service, so I signed up for Vonage VOIP on December 7th of last year. I’m now giving my one month update.

 

First let’s investigate my Qwest bill

Feature

Qwest

Vonage

Basic Residence Line

12.50

24.95

Federal Access Charge

5.94

0.00

Regulatory Recovery Fee

 

1.50

Non Published Service

.75

 

Voice Messaging

6.95

 

Total

26.14

26.49

 

So a quick look shows the two to be about equal. But now let’s figure in the local long distance, and the other long distance

Feature

Qwest

Vonage

Local Long Distance (Avg Charges)

6.76

 

Long Distance Charges (Avg Charges)

4.60

 

Total

11.36

0.00

 

Hmm, so I can save on average about 10 bucks a month by going with Vonage. Now, here is where the real advantage comes in. Let’s compare the traditional phone company and VOIP on the “other charges” spreadsheet. The Qwest bill says to look at www.qwest.com for charge explanations. The closest I found (I didn’t look too hard) is in the table below.

 

Qwest Charges (Explanation Here)

Qwest

Vonage

Federal Excise Tax @ 3%

.84

0.75

State Sales Tax @ 6.5%

.47

 

Local Sales Tax @ 1.9%

.14

 

Special District Sales Tax @ 0.4%

.03

 

City Occupation Tax @6.382%

1.72

 

State 911 @ .20 / line

.20

 

Local 911 @ .50 / line

.50

 

Federal Universal Service Fund @ 8.9%

.53

 

TRS Excise Funds Federal ADA @ .14 / line

.14

 

Telephone Assistance Program @ .13 / line

.13

 

Total

4.70

0.75

 

Now let’s look at AT&T’s charges

AT&T Charges (Explanation Here)

AT&T

Vonage

Bill Statement Fee (What!)

2.50