Express Versions and Visual Studio and the Extensibility story


One thing I have seen asked many times in the past few months is whether someone should uninstall the express products when they install Visual Studio proper. My answer is no and this blog entry will explain a bit about this.

Visual Studio is one of the most extensible products on the market. Essentially, Microsoft create a shell where components plug in. At one time, it was going to be the MMC shell, which is used by the Defragger, Event Viewer, Computer Management and .NET Configuration, to name a few items. The current shell is not MMC, but it does take a very similar approach.

The Express products contain the basic shell components along with bits specific to the type of development. If you download Web Developer Express, you get the basic web developer bits. If you download Visual C# Express, you get the C# bits. By bits, I mean the additions to the editor, projects, etc. that are necessary for that type of development.

If you later install a full version of Visual Studio, you do get a small amount of duplication, as you have two instances of the shell, but many of the components used by Visual Studio are the same ones used by Express. In many cases, you just get more of them. So the only real savings from uninstalling Express is a few components (very few) that are not shared. As disk space is very cheap, I would personally not uninstall. But, I also will demo Express from time to time (to show development can be done in Express, for example), so your mileage may vary.

The current version of Visual Studio is designed to make it easy to add new bits. Install ASP.NET MVC and it adds new templates, some additional Intellisense rules, etc. Add Silverlight development and you get more plugged in.

The next version of Visual Studio will still take these extensions to the product. And it is even more extensible, as it also will extend with MEF and the main surface uses WPF, which makes it easy to tailor the UI to your needs.

Back to the point. While they look like very different products, Express and Visual Studio share a lot. You cannot add all of the Visual Studio bits to Express, but this is a purposeful limitation, as Express is a free product. If you need the power of full extensibility, you have to buy the product. It is not a huge price to ask.

As for the Visual Studio SKUs, when you install Visual Studio Professional on top of standard, you get more stuff. When you then install a Team System SKU, you get more stuff. Want proof? Just look at your uninstalls. You can uninstall many of the features independently of the entire product.

So, should you uninstall Express before installing studio? If you really think saving a bit of space is worth it, perhaps. If you have the time to do it, then more power for you. Yes, leaving it there leaves another product you are not using, but since the Visual Studio installer checks for many items, leaving it on there may cut down your install time. In the end, it is your choice.

Peace and Grace,
Greg

Twitter: @gbworld

Of Mice and Anti-Patterns


This post primarily focuses on initiating behavior in a constructor. In order to use a real world illustration, there are a few other anti-patterns initiated, which I might further expound on in later posts. 😉

Background

I started out this morning examining new code (from 2008) that was produced in Visual Basic 6. I know some may see something inherently wrong with initiating new development in VB6 (and others who will hate me for the mere suggestion it might be wrong to start new development in VB6). I am not here to focus on the language, but that patterns.

As I do not have Visual Studio 6 installed, I was forced to read the code in notepad. Opening one of the two forms in the project, I find the following form load (shortened a bit, but still illustrating the point):

Private Sub Form_Load()

strCommand = Command()
If strCommand = "" Then
Else
    If (strCommand = 1) Then
            ‘Code for command 1
        ElseIf (strCommand = 3) Then
            ‘Code for command 3
            Unload Me
        ElseIf (strCommand = 2) Then
            ‘Code for command 2
            Unload Me
    End If
End If

End Sub

Note that command 1 does not unload the form, as this is where the issue started.

Here is the basic usage scenario:

  1. User starts windows form application
  2. User clicks on first command
  3. Command event handler loads Inet form with command id
  4. When the form loads, it uses command id to run code
    But this allows the loading of information messages and other buttons – more on this in a bit

Now, let’s look at the code you would use for this scenario. First let’s look at the main form, which the original developer did attempt to refactor a bit by putting all command buttons through the same event handler.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void commandButton_Click(object sender, EventArgs e)
    {
        Inet form = null;
        Button button = (Button)sender;

        if (button.Text == "Command 1")
        {
            form = new Inet(1);
        }
        else if (sender.ToString() == "Command 2")
        {
            form = new Inet(2);
        }
        else if (sender.ToString() == "Command 3")
        {
            form = new Inet(3);
        }
        form.Show();
    }
}

As in the original code, all of the code is sent through a single event handler. And here is how the Inet form is set up (using the same pattern as the original):

public partial class Inet : Form
{
    public int Command { get; set; }

    public Inet()
    {
        InitializeComponent();
    }

    public Inet(int command) : this()
    {
        Command = command;
    }

    private void Inet_Load(object sender, EventArgs e)
    {
        if (Command == 1)
        {
            MakeButtonsVisible();
            RunCommand1();
        }
        else if (Command == 2)
        {
            RunCommand2();

            //Can’t close on load, as in the original
        }
        else if (Command == 3)
        {
            RunCommand3();
            //Can’t close on load, as in the original
        }
    }   
}

The original code is much more complex than this (the original does not have RunCommandX() methods, it embeds the entire code in the Load() routine, with the exception of the command 4 and command 5 button events). The code does run like this, however.

How did this code get like this?

This is an interesting question. The history is this is part of an “automation” process, whereby automation means creating a batch script that runs an executable that then calls an Access file. And that is a simple step in the process, as often times a single process has multiple vbs files prior to getting to the executable. It is a nightmare, to say the least. It appears each developer developed with the tool he was familiar with, with absolutely no regard for consistency.

I am not sure exactly what happened, but running through the code, I think I have the basic process. It runs something like this:

Developer created VB app, as he was familiar with VB and not .NET or batch scripts, etc. He created a simple windows forms application that fired a macro in an Access database (don’t ask). he then found out the process needed additional user input, so he created a second form to actually run the command. The only way he could figure to accomplish this was to have the form instantiated with a command number and then check the command number in the Load() method.

If this was written up as a usage scenario, it would look like this (including the scripts that call the process):

  1. Operator runs script 12A
  2. Script does some processing and then fires off the application in question
  3. Operator presses the topmost button
  4. Second form is spun up and command runs (unloading for command 2 and 3)
    1. If is command 1
      1. form buttons are visible
      2. User presses command 4 button and it runs
      3. User presses command 5 button and it runs
      4. At end of command 5, form unloads
  5. Repeat for other commands
  6. At the end of command 3, application closes with a dialog stating “Compete”

Looking at the original specifications, the goal was to automated the process of creating clearing files, so this scenario really misses the mark.

Anti-Patterns and the Universe

The way anti-patterns are introduced, normally, is a combination of ignorance and sunk costs. Let’s run through this idea:
The developer, not truly understanding the language or the problem comes up with something he has used before that appears to work. He then begins to work on it and after spending hours he does not want to throw it away. So he continues to kludge things up until the code has the desired effect.

In this case, the user needed extra buttons, which, in his mind, dictated an extra form. When he spun up the extra form, however, he was unable to get the code running in the middle of the process, so he moved the process code to the second form. The only way he could figure to get the code running was to put it in form load method. And, having already spent time on this pattern, he set up the other commands in the same way. At least consistency was in order.

There are so many things wrong with this pattern, but my biggest beef with this pattern is the load is initiating behavior.

Perhaps someone can show me an exception to this rule, but I am firm on separating state from behavior. When an object loads, there is nothing wrong with setting up state. For example, we might have a person object:

public class Car
{
    public string Make { get; private set; }
    public string Model { get; private set; }
    public int Year { get; private set; }
   
    public Car(string make, string model, int year)
    {
        Make = make;
        Model = model;
        Year = year;
    }
}

I also have the ability to add behavior to an object’s constructor. But is it correct? Look at the following code and think about your own car. Would you want it to act as it does in the following code?

public class Car
{
    public string Make { get; private set; }
    public string Model { get; private set; }
    public int Year { get; private set; }
   
    public Car(string make, string model, int year)
    {
        Make = make;
        Model = model;
        Year = year;
        Accelerate();
    }

    public void Accelerate()
    {
         //Code to pump extra gas in engine to make it move faster
    }
}

What is wrong with this idea?
First, it is extremely hard to test a system that has behavior spin up when an object instantiates. You cannot independently test the instantiation of the object unless you code in a way out. Examine this, for example:

public class Car
{
    public string Make { get; private set; }
    public string Model { get; private set; }
    public int Year { get; private set; }
   
    public Car(string make, string model, int year, int command)
    {
        Make = make;
        Model = model;
        Year = year;

        if(command == 1)
           Accelerate();
        else if (command == 2)
           PlayRadio();
        else
        {
          //added so I can send in bogus command to test instantiation without action

        }

    }

    public void Accelerate()
    {
         //Code to pump extra gas in engine to make it move faster
    }

    public void PlayRadio()
    {
    }
}

This solves the problem in the same manner as the application that started this blog. There is a fall through condition to ensure action does not take place if an unknown command number is sent to the form. If you unit test, this means you end up with a test like the following:

[TestMethod]
public void should_have_model_of_Mustang()
{
     //Command = 42 to avoid running other commands
     Car car = new Car(“Ford”, “Mustang”, 1965, 42);
    
     Assert.IsTrue(car.Model == “Mustang”);
}

I would normally set up the test with variables, but the point is my short circuit of behavior allows me to actually test if an object instantiates. It solves the problem, but look at how kludgy the code is now.

Getting Help

I participate in UseNet groups and forums on a regular basis. Often I see people asking for help asking a “how do I” question that makes me question whether or not they have moved into an anti-pattern. For example, this query was recently posted:

I need to be able to include an .aspx or .ascx file that will then process
simple variable substitutions prior to sending the file to the browser.

In the following example when I call sample.aspx I would like the string
printed at the browser to be …
    loaded-2.aspx … sample string.
… it is currently printed as …
    loaded-2.aspx … .

Suggestions would be greatly appreciated.

After the poster answering back, it was determined that using the Membership and Profile bits along with themes made the most sense. But, had the questioned been answered at face value, the poster might have developed a very complex application with different controls “included” on the page depending on user preference.

Unfortunately, for each one where the poster is asked for clarification, I see at least one illustrating how to make the car automatically accelerate when it is instantiated. Thus the anti-patterns propagate from developer to developer.

Final Notes

The code in this post illustrate, at least to me, why we developers need to go back to basics. Until we look at the rules, we should not be breaking them willy nilly. There are some great books out there, like McConnell’s “classic” Code Complete.

One thing to remember is anti-patterns are generally born out of ignorance, not maliciousness or stupidity. Education is the key to stomping them out, not punishment. The idea “the beatings will continue until you are educated” is about as counter productive as “the beatings will continue until the morale improves”.

Peace and Grace,
Greg

Twitter: @gbworld

Raising Childhood Cancer Awareness with Microsoft .NET Technologies


All we need to make us really happy is something to be enthusiastic about.
Charles Kingsley

September is childhood cancer awareness month. Thus far, not a lot of traction has been made with this month or its associated day (September 12th). I have decided to join the troops on changing this. Fortunately, the trail has already been blazed by the Komen foundation, so a few years from now, we may see gold ribbon branded products everywhere. I would like to see awareness raised this year.

I cannot detail the entire project now, as it is incubating, but it is centering around our family vacation 2009. We are heading on a 12 day tour of Montana, Wyoming and South Dakota (essentially a Yellowstone/Grand Teton to the Black Hills loop). It could either end up really big or flop. I have some people in the background trying to help me make it on the bigger end.

Childhood Cancer Details

Everything can be taken from a man or a woman but one thing: the last of human freedoms to choose one’s attitude in any given set of circumstances, to choose one’s own way.
Viktor E. Frankl

As many of you know, my daughter Miranda was diagnosed with Ewing’s Sarcoma on September 6, 2007. We found the lump on her back on August 23rd in Louisville and she entered the hospital on September 6 with a 104.5 degree fever. We spent most of the next four months (sans 16 days) in the hospital. She is now 1 year and 4 months out of treatment, with her next oncology visit on August 6.

Here are some stats

  • Every 40 minutes, a child is diagnosed with cancer in the United States
  • Every 4.5 hours, a child dies in the United States
  • Worldwide, 25 children are diagnosed every hour and 18 die
  • In the United States, pediatric cancer is the number one disease killer of children
  • In the United States, only child abuse kills more children than cancer
  • Worldwide, pediatric cancer is the second disease killer of children, second only to pediatric AIDS
  • If Africa is excluded from stats, pediatric cancer is the number one killer disease, killing 4 times the number of children than AIDS
    85,000 for cancer, 22,000 for pediatric AIDS
  • We cannot firmly pinpoint the cause of most forms of pediatric cancer. This means we cannot simply alter behavior and avoid it. Every child is potentially at risk.
  • Most childhood cancers are treated the same way they were decades ago.
    For Ewing’s the chemo drugs used are the same used in the 1960s, although the time schedules and combinations have changed
  • Much of the NCI funding for pediatric cancer goes to study pediatric AIDS
  • Most children that live have long term effects from treatment
    • Miranda is 70% likely to develop some form of heart disease/condition from her treatment
    • Miranda is still undergoing physical therapy for treatment related side effects
    • Mentally and emotionally, most children take years to recover from treatment

As it “only” affects around 12,500 children each year (median of stats), the drug companies are not going to rush to research new regiments for childhood cancer.

The Tour

Our task is not to fix the blame for the past, but to fix the course for the future.
John Fitzgerald Kennedy

While it was not explicitly planned as a cancer tour, our vacation has the following dates:

September 1, 2009 – exactly 2 years after Miranda was first admitted to the hospital
September 12, 2009 – Childhood Cancer Awareness Day 2009

What I have decided is to use our vacation as an awareness trip, as well as a vacation. We are going to make hundreds of gold ribbons to hand out to people we meet along the way. In addition, I am working to get the press involved in raising awareness.

The Geeky Side

In the next week, I am going to launch a new site to detail our trip and our awareness efforts. The site is going to be built around the latest Microsoft technologies and will include a blog on how the site was built, so those of you struggling with Silverlight, ASP.NET MVC might enjoy the details. I have chosen these technologies as any links back to the site help raise awareness of the site and, more importantly, of childhood cancer.

I will have more details very soon. Whether the site is big news or small, it will be a good launch pad to learn the following, as they pertain to a real life site:

  • SketchFlow
  • Silverlight – primarily on media
  • ASP.NET MVC
  • Test Driven Development
  • Refactoring

Hopefully that stirs you a bit

Other Notes

Don’t say you don’t have enough time. You have exactly the same number of hours per day that were given to Helen Keller, Pasteur, Michaelangelo, Mother Teresea, Leonardo da Vinci, Thomas Jefferson, and Albert Einstein.
H. Jackson Brown, Jr.

This is a very personal thing for me. While my daughter has not yet reached five years, I firmly believe she is going to live a long, happy life. I wish I could say the same for Cody Robinson or Cassidy Schuttinga, two children we have been close to who did not win the cancer battle. While I would much rather put the past behind me and forget the pain we endured, there are so many children who are hurting now because we have not cured this disease.

But the cure will only come with research and research will likely only be fully funded with awareness. I don’t want to have my vacation spent campaigning, but life deals funny cards some time (just ask James Butler (aka “Wild Bill” Hickok). If I can do something, perhaps something a little silly, and raise awareness, then I will have spent a bit of time doing something good. If we can’t do something good, what is life for?

What I Want From You

Do you know what my favorite part of the game is? The opportunity to play.
Mike Singletary

All I am asking is you get what you want from the site, when it launches, and spread the word. Each click is a person and each person brings awareness. In return, here is what you can get from this:

  • If you are a cancer parent, or know a cancer parent, you can help raise awareness without cost
  • If you are developer, you can learn from my site building escapades
  • If you are helping us raise awareness, you can do good for others

I am going to do this. You can come along for the ride.

Peace and Grace,
Greg

Twitter: @gbworld

Expression Web 3 for the ASP.NET Developer (First Glance and Tutorial)


In previous years, I would have kept up with what was going on in Expression Web from the get go. But, this year, with so many new technologies, I have largely stayed in the background and ignored what was going on in this space. This blog entry is a quick whirlwind tour through Expression Web 3 from the eyes of someone experienced in web design.

Tutorial

This section is designed to show what I did to play with Expression Web 3. The next section are my feelings on the product (although i have some nice comments to interject, I am sure).

Create a New Site

The first step in new web development is creating a new site. So, I open Expression Web 3 and click File >> New and see the following:

File.New

What, no new site on the menu? Hover around for a bit and I find the means of creating a new site is found on the buttons underneath the menu.

NewSite

That is not so bad, but why complete neuter the menu of the creation of a new site? This has been a standard in web applications for quite some time and is how I would do things in Visual Studio. Fortunately, Cheryl got this before I tweeted and pointed out this blog post. There is a new Site menu in Expression Web 3. You find it in the middle left of the menu. You can find Cheryl’s review of new features at http://by-expression.com/content/ExpressionWeb3.aspx.

Add a Configuration File

As this is an ASP.NET website, it needs a configuration file. To do this, you choose File >> New >> Page … The next step is to choose ASP.NET in the left most panel and then Web Configuration 3.5. The dialog to choose the configuration file is found below:

newCOnfig

Create a SiteMap

This is not necessarily a second step in a .NET application, but I want to be able to play with the menu I am going to throw on a master page, so first step is to create a site map. To do this, choose File >> new >> Page … then the ASP.NET tab and then Site Map. I then edit the three nodes to end up with something like this:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="
http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="default.aspx" title="Home"  description="Home Page">
        <siteMapNode url="about.aspx" title="About"  description="About us" />
        <siteMapNode url="contact.aspx" title="Contact Us"  description="Contact Us" />
    </siteMapNode>
</siteMap>

Create a Master Page

As I work with .NET, this is my general first option for pages. The only way to create a master page is to use File >> Page… and then chose master page in the dialog, as we have before with config and site map. After I create the file, I am going to add a menu above the content area. The menu control is in the toolbox under ASP.NET Controls >> Navigation. Here are the steps to link things together.

  1. Drag the menu control on the page above the content area and choose new datasource

    AddSiteMap

  2. You will now get a popup. Whether you ignore this or not depends on how you want the control set up. I would personally leave it off, as you can edit in the code view by clicking on the asp:SiteMapDataSource tag. Having it in design view is a pain. You can turn it off again unde rthe view menu. Just unchecked the highlighted option.

    TurnOffVisual

  3. The first property you are going to want to set is the StaticDisplay Levels. You do this by going into Tag Properties and choosing 2 for StaticDisplayLevels (found under Behavior) – You can separate it from the side, as I have below, by double clicking on the header. This makes it a free floating window. Useful when you don’t have a lot of resolution, as I have on this particular box.

    TagProperties

  4. You will also want to change the menu to horizontal (Layout >> Orientation).
  5. Done with adding a menu to a master page. Now add the SiteMapPath and link to the same site map. Notice that I have the site map data source visible (see point 2 for how to turn it off).

    MasterPage 

Yes, this is an extremely easy (and ugly) master page. There are a couple of things I notice that I am not too fond of right now.

 

Add Pages

I need to add 3 pages

  • default.aspx
  • about.aspx
  • contact.aspx

To do this, I can either choose File >> New or click the left most icon underneath the menu. I then select Create From Master Page. I now see one of the features I wish they had added that is missing. To make things easier, you can specify a default master page. I have suggested in the past that Microsoft add the option to save the master as a default, or right click and make default. As the tool is used by non ASP.NET developers, it is not critical, but it makes things much easier for newbs. Even if this was not an option by right click or when saving a master page, it would be nice to add “Make default” when you select a master page, or at minimum select the master if there is only one in the project. Points off for this one still being like this.

Point of irritation 1: The damned visual aid popup that pops up with every page.

VisualAidPopup

Every time I add a page with my master, this popup comes up, as the page is linked to a page with a master with a non-visual control on it. This would absolutely annoy the crap out of me if I was building a larger site (for the record, I would normally create the site layout in Visual Studio).

Point of Irritation 2: Content areas not automatically added to pages. When you first start a page from a master, it looks like this:

<%@ Page language="C#" masterpagefile="site.master" title="Untitled 1" %>

To actually implement the page, look for the smart tag on the side of the content placeholder and choose Create Custom Content.

CreateCustomContent

The page now looks like this, in code view.

<%@ Page language="C#" masterpagefile="site.master" title="Untitled 1" %>
<asp:Content id="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1">

</asp:Content>

Much better. I had really hoped they would fix this, as well, in Expression Web 3, as this is a useless extra step in the process of creating a page. At least give the option to implement content regions.

Code Behind

Expression still does not handle code behind. If you want code in your page, you have to do it like this:

<script runat="server" language="C#">

    protected void Page_Load(object sender, EventArgs e)
    {
        //Page set up here
    }

</script>

I personally think this is very yucky. It even makes me feel dirty to do it this way. So, what about round tripping, etc. Let’s create a file in Visual Studio. Look, it creates the content placeholder regions for me (no  need to click on each one):

<%@ Page Language="C#" MasterPageFile="~/site.master" AutoEventWireup="true" CodeFile="CreatedInVS.aspx.cs" Inherits="CreatedInVS" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
</asp:Content>

I then go back to Expression Web and there is no refresh on the folder. But, I can right click and go to properties and have it refresh for me. As expected, Expression still shows the C# file in the folder list. No improvement here.

FolderList

Toolbox for ASP.NET

The Toolbox is pretty much the same as it was in previous versions. One thing I noticed right away, however, is Silverlight 2.0 controls are a link (see below). Clicking on the link takes me to an MSDN page that describes the beta controls for Silverlight 3.
Toolbox

First, that page does not help me at all. I am sure this was missed in QA, but it is kind of stupid to send someone to a site that does not even tell them how to add the Silverlight controls to Expression. In Expression 2, the controls were here, but now I have a link that takes me to a page that really has NOTHING to do with Expression. If you are trying to educate me here, why not links for all ASP.NET controls? Rant off.

It turns out the controls are in the toolbox. Scroll up to HTML and the Media.

Toolbox2

Here you can add Deep Zoom, Silverlight and other media files. But, did they do it right? My answer is … yes. in Expression Web 2, it was such a pain to add Silverlight bits. Fortunately, with Expression Web 3, it is fairly easy. Just select a media file and the encoder pops up and allows you to encode it for the web. I am going to have to play with the rest of the controls here to see if they are as easy to use. I will blog that one later.

Super Preview

Now that I have a page, I can preview. My first thoughts of Super Preview are it should be called Super Slow Preview, as it takes an awfully long time, As my page has nothing on it, there is no use on screen capturing it. I will, instead, show my blog site.

superPreview

This is a fairly neat feature. Being able to see sites either side by side or on top of each other is useful. If you click on an item in one panel, it is highlighted in the other. My biggest issue is it is little more than a preview. I can certainly click on the DOM and see what I am working with, but that is about it. Here are a couple of suggestions I have for a new version (yes, I probably should have been involved in the beta):

  • Allow changing of DOM elements in preview, as you can currently do in Internet Explorer 8.
  • Have a CSS view along with the DOM view
  • Allow a person to traverse more easily to the CSS (double clicking in DOM view?)

I think SuperPreview is a nice addition, but the main value I see in it is finding differences from one browser to another. As there are other tools that allow me to actually fix things, even if I have to pop back and forth from IE to Firefox (I actually do not as there are add ins for that, as well).

Feelings Thus Far

Other than adding a few controls, Expression Web has not made many strides for the ASP.NET developer. Here are some points:

  1. There are no web templates for ASP.NET sites built in
  2. You have to manually edit the web config for simple things, like default master page (although there are tools for editing these files elsewhere in a visual manner – IIS for example)
  3. The content regions in master pages are not implemented automatically, forcing you to do a little song and dance for every page.
  4. There is no option to turn off warnings when you have invisible controls on a master page (yes, this one got me enough to state it twice)
  5. They moved things off the menu and on to a button bar. Why not in both places? I have no clue
  6. There is still no option for a code behind file and adding one shows the code file in the designer.
  7. There is no straightforward refresh button when moving back and forth from Expression to Visual Studio

Let me touch on a couple of points:

On point 6: The story Microsoft sells at MIX and other events is we have Expression for designers and Visual Studio for developers. Hey, I get that. But if my designers are creating a lot of pages that force me to write all of my code in the pages, it is not a good thing. And, if I add the code behind files (or initially set up the site), they see the code files as a separate file. What are you guys thinking here?

Summary

Overall, Expression Web 3 is a nice release. The addition of the Encoder and Design to web makes the package more attractive and make it, in my opinion, well worth the price of admission ($159 or $79 upgrade).

On the plus side, SuperPreview is a good way to see your results in multiple (as in 2) browsers and see what is different. i wish it were more, but I will take it for a 1.0 release of a feature. The Silverlight and media bits are also very nice additions, as it was a royal pain in Expression Web 2. I do think you might be in a tight box with this feature, but I will have to play to make sure. I am sure there are other PHP bits, as well, but I am not a PHP developer (at least not now), so this is not a big thing for me. I have yet to play with the import PhotoShop bits, but I can see how they add something for designers, as I have designed in PhotoShop before.

I am not particular fond of the neuvo look (all black and grey), but I guess it fits the suite better.

On the negative side, the developers have not done much for ASP.NET development. Expression Web 3 is just as clunky as Expression Web 2 in this arena. I might even say a bit worse since the menus have been pushed around, but this is a personal thing. you will have to decide this one. And the extensibility picture is pretty much the same (dismal), although I have heard of possibly fixing this in a service pack or something.

i guess the questions now are: Should I buy? and Should I upgrade?

BUY:
As far as the buying decision, $159 is awfully cheap for a suite like this. Expression Web 3 is a nice editor. My biggest beefs are not taking it too far beyond Expression Web 2, which I also think is a great editor. The CSS support in Expression (any version but 1) is worth the price of admission. Now that Expression has Encoder and Design included, it is a very attractive package.

UPGRADE:
The SuperPreview is probably reason enough for many, although it is not overly compelling for me. Beef it up with something more than a set of visual diagnostics and I am all in. I can see how it is useful, however. For $79, however, the addition of Encoder and Design make it worth the money for me. if I were making that decision (I have MSDN which includes the entire studio). if you prime reason for upgrading is better ASP.NET design and development, you are going to be sorely disappointed, however.

I give Expression 3 a thumbs up, but with caveats (read the blog entry, if you have not).

Peace and Grace,
Greg

Twitter; @gbworld

Microsoft to release Windows 7 and Expression 3 Studio soon


UPDATE: Expression 3 Studio now available for MSDN Subscribers.

I just saw a Jon Box comment on Facebook (assume it was a tweet he has connected) that Windows 7 was in the can and ready for release. Within the next couple of weeks, MSDN subscribers should be able to download the final version of Windows 7 and start using it as their main OS. The Official release for the public, as I understand it, is in October.

I also heard that we should see Expression 3 studio shortly, but since it was not from a Microsoft source, I am assuming it is a guess rather than “inside” information. It would not surprise me, however, as Silverlight 3 was released earlier in the month with a Blend 3 Preview. Since the Expression Web MVPs were released to blog about Expression Web 3, the final build has to be in the can and just awaiting someone to put it out.

The next major thing, for me at least, is the release of Visual Studio 2010, which I suspect will go to beta 2 soon and then be released to RTM by 1Q 2010 (perhaps even earlier, as MS has a habit of releasing to MSDN in November). Don’t try to hold anyone to these dates, as I am just taking an educated guess.

I am expecting something big surrounding SharePoint 14 (aka SharePoint 2010) as well. Microsoft has retooled Groove to become SharePoint Workspace and there are developer tools for SharePoint baked into Visual Studio 2010. My guess is we will see some of the baked in goodness in Visual Studio 2010 beta 2.

By the way, if you are curious about Office 2010, you can join the Connect site and download the bits. The products currently available are:

  • Office Professional 2010
    • Word
    • Excel
    • PowerPoint
    • OneNote
    • Outlook
    • Publisher
    • Access
  • Visio 2010
  • SharePoint Designer 2010
  • InfoPath 2010
  • SharePoint Workspace 2010
  • Business Contact Manager for Outlook 2010
  • Other Products
    • Outlook Connector
    • Language Packs
    • Business Contact Manager Database Tool

Realize that you play with this at your own risk, as with all ‘betas”.

Peace and Grace,
Greg

Twitter: @gbworld

How the Recruiting “Game” Works


Check out this question:

I see you have written about recruiting in the past. I was recently offered a job for $45 an hour as an ASP.NET developer. As I have never contracted before, I am not sure if the recruiter is taking advantage of me. Are they treating me fare or is this a raw deal?

The short answer: I can’t tell you if the rate is fare, or even if it is fair. 🙂 What I can do is tell you how the recruiting business works and you can run the numbers yourself. I can also give you an idea of what the current rates are here in Nashville.

Business 101

All businesses are in business to make money. Whether a company sells meals, insurance plans, widgets or even warm bodies (perhaps knowledgeable workers is a better word here?), they have to make money to stay in business. The amount they make is generally calculated in percentages and called a profit margin. This is true of the recruiting firm as much as it is of the company you are contracting or consulting at.

Allow me a little aside. When I say contracting in this post, I mean you are there to code, do business requirements, etc. As a contractor, your position is not to advise the business as much as sit down and get to work. When I say consulting, it is a subset of contracting where part of the contractor’s value is being able to advise the business to improve their business and not simply code new software. There is a very grey area and contractors, hired as contractors, can often add value by consulting. In general, if you are just starting your career, you are what I would call a contractor and not a consultant.

Back to the point, all businesses have to have more money coming in (income) than going out (expenses) in order to survive. Employees and contractors are their primary expenses, percentage wise, but they also have bad debts (companies that stopped paying for contracting services, etc) as well as utility expenses and rent. If more is coming in that out, they are making a profit. If less, they are probably out of business (although short periods in the red will not kill most companies).

Recruiting 101

The recruiting company has two basic roles. There is an account manager, who is responsible for getting the contract (or working with the business that needs work done) and a recruiter, who deals with the talent. The account manager is the one that gets the company to agree to pay X dollars an hour for talent at a certain level and the recruiter finds the talent.

The way the money works is the recruiting company gets X dollars and pays you Y dollars out of that X. The number of dollars you are paid is determined by your deal with the company. The deal is based on a percentage the company feels it needs to make to make a profit plus anything else they can negotiate. Your rate is determined by a bunch of factors, some of which are easily quantifiable (Joe is W2, so we have to pay a portion of his FICA) and others are not (Joe has a reputation of not finishing contracts, we have lots of contractors at the business, etc.).

What is a fair rate? This is a hard subject to put an exact number on. I can name some examples of unfair rates, however.

  • It is unfair for a recruiting company to charge $100 and hour and pay you $20
  • It is unfair for a subcontracting company to take $20 per hour and then tell you it is a 10-99 contract

I will hit these later.

How the Money Works

Let’s take an example. Do not take these numbers as gospel, however, as different companies have different overhead, etc. These are just a guideline of how the money works and nothing more.

Tech Talent LLC gets a contract with Sudoku Inc. at $75 an hour. They then try to get talent. There are three basic ways they structure the deal:

  • Corp-to-Corp: A company subcontracts the position or the contractor is incorporated and has liability insurance
  • 1099: Contractor is not considered an employee, but is normally covered by their liability insurance
  • W2: Contractor is, for tax purposes, considered an hourly employee of the recruiting firm

There are also other items that can be negotiated like retention bonus (complete full contract), vacation, sick days, holidays, benefits, 401K, etc. Not every recruiting company will be able to offer all of the varieties of possible extras, so these items are negotiated on a case by case basis.

Let’s look at some sample numbers:

paid to recruiting firm                                           $75.00
taken off the top for expenses   (10%)       $7.50     $67.50   – sample corp to corp rate
Liability adjustment (2%)                           $1.50     $66.00  – sample 1099 rate
W2 expenses (10%)                                  $7.50     $58.50  – sample W2 rate
Vacation (2 weeks per annum)                   $4.00     $54.50  – sample W2 rate with vacation
Paid Holidays                                           $2.00     $52.50  – sample W2 rate with vacation and holidays

These sample rates are actually fairly accurate for some companies and represent an okay level of “fairness”. The markup on W2, in this example, is 28% ($75 is 128% of $58.50). While I did not completely plan it out, 28% is the “minimum” acceptable rate for at least one of the major recruiting firms I know. I have seen companies with lower overhead that have even dropped down in the 15-20% markup range. I have even had one contract where the recruiting firm lost money on my deal every time I worked overtime (it was in the original contract and it was a government contract, so they had to honor overtime)*.

* The reason they agreed is I was available quickly and they were up for vendor status (only 3 vendors are allowed to bid on their contracts). Better to lose money on one contract than lose all of the business.

What else can alter this rate?

  • The recruiting company offers insurance: lower rate
  • The recruiting company offers insurance that is partially paid by the recruiting company: lower rate
  • The recruiting company has a 401K: lower rate
  • The recruiting company offers 401K matching of some sort: lower rate
  • The contractor has a great reputation: higher rate
  • The recruiting company has numerous contractors at a single location and is in danger of losing them if they don’t fill this position: : higher rate
  • The contractor is offered a bonus for completing the contract: : higher rate
  • The contractor gets paid overtime at a higher rate: lower rate
  • The contractor has guaranteed bench time: lower rate

The bottom line is the recruiter will determine the deal based on money coming in, the expenses going out and the profit they wish to make. Any time you ask for something, expect the reduction in rate to equal the amount per hour it cost the recruiting company, plus a bit more. A bit more? Now that sounds unfair? Perhaps it is, but the reality is certain extra payments get paid out before they are accrued. As an example, if you take a contract in December (unusual, but it can happen), chances are the recruiting company will have to pay you at least 16 hours (Christmas and New Years) in the first few weeks, which puts them in the red. To recoup these situations, they take a bit more than the “fair” exchange for the risk they are taking on.

What is fair? What ultimately is fair is what you feel is fair and what the recruiting company thinks is fair. If they can get you for $60 an hour and another person for $50 an hour, guess who does not have a job. This is not completely true, as once you develop your reputation, they may want you in there and be willing to pay more (generally not $10 an hour more, and certainly not $10 an hour or more based on our original sample numbers.

You are not supposed to find out what the recruiting company is being paid, but I have found you do from time to time. Here is my feelings on that. If you find out the company is billing you out at $85 and hour and paying you $35, then you have two choices: quit or stay.  I think a recruiting company (note I am not talking a full time consulting company where you are a full time employee with bench time) that takes the lion’s share of the pool is screwing you.

What should you do if they are screwing you? This is your choice. The only options, right now, are leave or stick it out. Of the two, stick it out is generally smarter, lest you get a reputation of leaving in the middle of contracts. How bad leaving a contract is depends on your skillset, general reputation, etc. If you are new to programming, it could be a really bad career move to walk before a contract is over. Just remember when you signed the contract you agreed to be screwed. Chock it up to experience and move on. You probably want to mark down that company as someone you don’t want to work with again.

This is not 100% accurate, as you have to consider your reputation. If you have a reputation of leaving contracts, you will find it harder to get work. You have to consider that in the mix.

Some Variations on the Story (Recruiters Screwing Contractors)

let me ramble a bit (the story does lead back into how recruiters ARE screwing contractors). If you want to skip the back story and get to the “variation”, skip the parts that are italicized.

About two months ago, I got a call from a recruiter that wanted to beat me up over the phone. I, of course, hung up on him. The details of the story are located in the blog entry 7 Things Recruiters Do That Irritate Me. Here is the short version:

Phone rings – Ignore
Phone rings – Ignore
Phone rings – Ignore
Phone rings – Ignore
Phone rings – Ignore
Phone rings – Ignore

When my phone was dialed the seventh time in a row, I thought “It is a Michigan number, maybe it is Dale and he needs help”. Here is the basic gist of the conversation:

Recruiter: Hello Gregory Beamer
Me: Is my house on fire?
Recruiter: I do not understand your query.
Me: If my house is not on fire, you have no reason to call me seven times in a row.
Recruiter: I have a very important job you must listen to.
Me: Send me an email.
Recruiter: No, you must listen now.
Me: I am hanging up now (click)

I then got three emails (one each for Dice, Monster and Career Builder) in my inbox. Now to “the variation”. The position was advertised at $35 an hour 1099 in his email. I recognized the company and compared reqs to other reqs out there to be sure. I then called a recruiter friend and asked what the rate was for the particular position. The answer was “I would say $55-60. You could easily get the $60 with your reputation”.

What is happening here?

There are a group of companies out there who do not have what we would traditionally call account reps. Instead they call every company that has a position on the Internet job boards asking if they can represent the position. If it is a real company, they want to be the recruiting company. If it is a recruiting company, they want to subcontract.

Here is where they screw you. The company that got the req is going to be paid $75. They pay this company $67.50. This company then advertises the position at $35. Here is the breakdown.

Paid from company                            $75.00
Amount paid to original company       $  7.50
Amount paid to contractor (1099)       $35.00
Amount for subcontracting company   $32.50

What this amounts to is highway robbery. The company that did the least amount of work gets almost half the profit. I am all for capitalism, so i don’t see a need for a law, but this is ridiculous. i know of contractors that will not even talk to anyone with the last name of Patel, as it is primarily the East Indian companies that are attempting to subcontract in this manner. I also know recruiting firms that will not deal with these guys, as they don’t want their own reputation soiled by being the top company on the list in these types of deals.

Back to “Fair”

The person asking about a “fair” rate was probably being offered something I would consider fair. I can only answer for Nashville.

The majority of contracts here are in the $40 – $45 range now. They are primarily mid-level skillset. Last year, it was possible to get $50 for the same mid-level type of job, but the “economic downturn” has hit. I have personally been able to keep in the $55 to $60 range. Anything in these ranges is probably fair, but there is nothing wrong with attempting to negotiate a better deal.

Final Notes

I have quite a few friends that are recruiters. And, in the past, I have only had one deal that I felt I was completely screwed over on (my first) and I finished that contract and did not renew when I was asked if I wanted to go for another stint (I moved on for close to double the money). I have been around long enough I can generally smell a rat and $40 1099 when the prevailing rate is $40 W2 is a sign something is probably up. When the position is senior enough to warrant $60 and they are offering $35, it is either a clueless company or someone is trying to make a huge amount of money off of me.

The first question of fair or not is how you feel about the rate. If you feel good, then it is a good rate. if you don’t, you can either negotiate the rate or refuse the position. The second question is what the market is paying. If the rate is good for you, but much lower than market, you should at least question. It could well be a company that cannot afford the normal rates.

Peace and Grace,
Greg

Twitter: @gbworld

Lunch and Learn: Why Refactor?


This is the first (?) blog entry on why developers should refactor. I just noticed the situation today at my assignment, and I felt it was prime time to have a lunch time type fest and illustrate the why(s) of refactoring in a concrete, real world example. As I find other code samples, I will likely blog again.

I wrote the following code based on code I recently documented for some changes in a system. The code has the same basic branching logic found in the original, but I have altered the actual code and obfuscated out the variable names and even the name of the individual responsible. This is not a “look what so-and-so did” post, but a learning exercise.

Here is the code. A quick examination should show we are setting and resetting a value numerous times. The actual code sample had many more cases of branching logic throughout the routine (most of the routines in this Access module contain hundreds of lines of code). But this small snippet of one routine is enough to illustrate how code is bolted on rather than refactored.

First, the code, as it stands:

‘ Added by XXX per specs 10/30/2008
If recordset![Item1] = "1" And Item2 = "X" And Item3 = "Y" Then
        recordset![Item4] = "XX"
End If

‘ Added by XXX per specs 10/30/2008
If recordset![Item1] = "1" And Item2 = "Z" And Item3 = "A" Then
     recordset![Item4] = "XX"
End If

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008

        recordset![Item4] = "UU"

        ‘ Added by XXX per specs 10/30/2008
        If recordset![Item1] = "1" And Item2 = "Z" And Item3 = "A" Then
            recordset![Item4] = "UU"
        End If
Else
    recordset![Item4] = "XX"
End If

The code should clue in that we need some changes, as the same value (Item4) is changed over and over again. All we need to get the same answers is this:

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008 
        recordset![Item4] = "UU"
Else
    recordset![Item4] = "XX"
End If

There is one other refactor we would have to look at here, if the code actually changed the values. Item2 is a subset of Item3, set up in a hierarchy. All Xs are of parent set Y and all Zs are of parent set A. It looks something like this:

Y
   > X
   > U
   > T

A
   > B
   > Z

etc. So, if the code actually was an exclusion, as it is elsewhere in the code, we would do the following:

‘ Added by XXX per specs 10/30/2008
If recordset![Item1] = "1" And Item2 = "Z" Then
     recordset![Item4] = "XX"
End If

This covers when we are dealing with items that are a subset. The more specific item (child) will always have the same parent and you avoid a test that simply wastes cycles).

How Does Code Get Like This?

There is a very simple answer. New rules come in and they are bolted on. This generally comes from one or more of the following conditions:

  1. The person coding does not have the technical knowledge to think through the paths (inexperience)
  2. The person coding does not have the business knowledge to determine the impact of the changes (lack of business knowledge – ignorance)
  3. The person needs to ensure the path is there for possible future changes
  4. The person coding does not FEEL he has the time to refactor

Lets take these in order:

Item 1: The person coding does not have the technical knowledge to think through the paths(inexperience): Inexperience, at least with the code contained in this routine, is a poor excuse. Anyone taking a moment to run down the code path, sees the following.

IF Item2 = Z

  • Change Item4 to 29
  • If 4900 change Item4 to WJ, and then change Item4 to WJ
  • If not 4900 change Item4 to 29

End result: 4900 is the only key to determining the value of Item4.

The solution is to code out the branches that can NEVER be hit:

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008 
        recordset![Item4] = "UU"
Else
    recordset![Item4] = "XX"
End If

As a side note, it should be noted that the entire branching logic in the routine was per a single specification, so the coding here is even more insidious, as a single developer coded all of the paths. It would have been better to code in notes (comments), as in the following:

‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = X, then Item4 = XX
‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = Z, then Item4 = XX

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008 
    recordset![Item4] = "UU"
    ‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = Z, then Item4 = UU

Else
    recordset![Item4] = "XX"
End If

Item 2: The person coding does not have the business knowledge to determine the impact of the changes (lack of business knowledge): This is not an excuse in this case, but it could be legit in some instances. Even so, if the paths are obvious, make a comment on the “changes” so someone knows. The routine change is below the next item

Item 3: The person needs to ensure the path is there for possible future changes: This can also be solved, like item 2, with comments. And, no, I will not get into the “comments are bad” argument, pro or con. Here is the solution code for Items 2 and 3, which is the same for Item1, taking in account that the developer was not adding to the code, he was creating the routine.

‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = X, then Item4 = XX
‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = Z, then Item4 = XX

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008 
    recordset![Item4] = "UU"
    ‘ Per specs 10/30/2007, if Item1 = 1 and Item2 = Z, then Item4 = UU

Else
    recordset![Item4] = "XX"
End If

Item 4: The person coding does not FEEL he has the time to refactor. I can sympathize with this thought pattern, as it is often hard to convince management that you need a bit more time to clean up code. After all, the general consensus is “as long as it is working, why should you take any more time developing?” And, if management forces the issue, it is better to have a job than it is to be right, right?

As a personal note, I actually disagree with the “better to have a job” statement, at least in most cases. With the economic downturn, we are at a higher unemployment rate (around 3%, compared to the current 9.35% average across all sectors) and the rates out there are lower, perhaps lower than your current job rate. So, accepting garbage coding might be a bit more acceptable, but realize there are two artifacts that come with coding garbage:

  1. You are developing bad habits: While you may downplay this, the impact of continuing to do bad work does eventually become a habit, if the studies are correct. I have personally witnessed it (anecdotal evidence) with workers in an environment that allows them to be lazy, so I assume it applies to any development/coding habit. If you disagree with me, just comment, and we can talk about it.
  2. You are leaving behind evidence of garbage coding: We already know that the guy who just left normally gets blamed for the problems in the system(s) he was working on. Unless you can’t avoid it, don’t give evidence that you are to blame for the problem.

This gets to another CYA maneuver. Whenever you are forced to leave behind bolted on code, keep an evidence trail that you advised a refactor. You may never need it, but if you do, it is better to have some form of evidence that you were trying to do the right thing and forced to compromise.

SideNote

For the actual code, I left the original code, but commented out the lines that would not run. This was more out of my desire to stop spinning cycles, but leaving things so people in the future could see the logic. It was a bit faster than a rewrite. The code ends up like this when commented out:

‘ Added by XXX per specs 10/30/2008
‘GAB NOTE: This code accomplishes nothing, so it is commented out
‘If recordset![Item1] = "1" And Item2 = "X" And Item3 = "Y" Then
‘        recordset![Item4] = "XX"
‘End If

‘ Added by XXX per specs 10/30/2008
‘GAB NOTE: This code accomplishes nothing, so it is commented out
‘If recordset![Item1] = "1" And Item2 = "Z" And Item3 = "A" Then
‘     recordset![Item4] = "XX"
‘End If

If recordset![Item5] = "4900" Then     ‘ Code added by XXX per specs 10/30/2008

        recordset![Item4] = "UU"

        ‘ Added by XXX per specs 10/30/2008
        ‘GAB NOTE: This code accomplishes nothing, so it is commented out
        ‘If recordset![Item1] = "1" And Item2 = "Z" And Item3 = "A" Then
        ‘    recordset![Item4] = "UU"
        ‘End If

Else
    recordset![Item4] = "XX"
End If

The added benefit of this change is it can easily be reversed if rules change. It is unlikely in this case, but being able to revert back and change the order of code is probably wise in this case. And “politically” it is a better option. 😉

Peace and Grace,
Greg

Twitter: @gbworld