Bookmark and Share

Embrace the Dark Side

I’m trying to win the grand prize for June on Community Credit, and I get 5000 points for linking to there. Here’s what I’m trying to win!

DarthVaderUSB

Embrace the Dark Side
Embrace the dark side every day with this animated Darth Vader USB hub. His eyes light up red as he moves his head from side to side and performs his trademark heavy breathing. Push button activation or select random intervals throughout the day. Plug a peripheral in and Vader activates to the sound of a light saber

Remember, if you’re writing blog posts, presenting, or volunteering for the community in any form; you too can win stupid prizes for smart people!

Bookmark and Share

One Public Type Per File

I remember when I started working on this particular project a few months ago. When I looked over the code for the first time, I noticed something funny about the cs files. Each cs file contained multiple public types. In the extreme cases, there were dozens of public classes in one file.

I brought it up with my new teammates, and one person claimed that he liked to keep related classes in a single file. I mentioned that I find it more difficult to find what I’m looking for in the solution tree, but he shrugged it off by suggesting I use the search feature.

Having never seen this type of code structure before, and with the knowledge that you group related classes by namespace, I decided to research why I felt so strongly that public types deserve their own file. I referred to the Framework Design Guidelines book by Krysztof Kwalina and Brad Abrahams (which is a great reference, btw). The first rule under A.4 File Organization is “DO NOT have more than one public type in a source file.” It then lists a few exceptions (number of generic parameters, nested, etc.).

Today I received yet another reminder of why this type of file structure is bad. I pulled down the latest code, then I retrieved a shelveset I was working on last week. I knew I might have to merge a few files, but I didn’t expect this.

DefinedMoreThanOnce

Ignoring the misspelled class name, someone had moved the type from a file I was working on to another. This kind of silliness wouldn’t happen if the class had its own file. I wasn’t even working on that particular class. As it turned out, the class in question was used by a few xaml pages, and a developer thought it fit better with a different xaml page than its original home.

My rule is one public type per file, using namespaces and project folders to group related types. This reduces the amount of potential editing conflicts and makes it easier to find the type in the Solution Explorer. If you have types with the same name but a different number of generic parameters, name the file by the class name with `(# generic parameters) at the end. For example, List<T> would be List`1.cs.

Bookmark and Share

Prevent Crawlers On Your Data Service

At ConvergeSC 2009, an attendee asked me to describe how to prevent crawlers from trolling your ADO.NET Data Service. I explained as best as I could, but I felt like a blog post might make it more clear.

To a bot, your data service looks like any other site on the web. Sure, it’s reading either Atom, POX, JSON, or some other bizarre format you’ve concocted, but it’s still data coming down through http and discoverable via links. There are ways to prevent a bot from crawling, but information available on the web that doesn’t require authentication can be crawled.

The first way to prevent your service from being crawled by a legitimate bot is to put a Robots.txt in the root of the site. Inside the file, put the following lines:

User-agent: *
Disallow: /

This locks down the entire site from being crawled by the bot. If your service coexists with a site you want to be crawled, you can change the Disallow option to /MyService.svc/. be sure to include the closing slash so other pages aren’t accidentally matched.

The conference attendee seemed to be concerned specifically about anchor tags and AJAX. If you’re using the OnClick event of the anchor tag, most spiders will not follow it. However, if the uri is in an href, a crawler will pick it up. Bing and Google will honor a rel attribute with the “nofollow” value to prevent indexing the page. However, Yahoo and Ask will still follow and index a link with that attribute.

If your service is publicly available, using the robots.txt is the way to go. If it’s not publicly available, the service should already be locked down through authentication techniques.

Bookmark and Share

The Lounge

I am honored to have joined the Lounge Advertising Network!

Now, I know you’re thinking, “Why would someone be honored to join an ad network?” I would answer that with “look who else is in this network.” The Lounge picks only the top Microsoft technology blogs… blogs by influencers both online and off. To be counted among them is indeed a cool thing.

Bookmark and Share

Tracking Items in Solution Explorer

Have you ever debugged a large project you didn’t create? If so, you’ve probably gotten lost in the vast jungle of code that was once some poor programmer’s paradise. This vast jungle is full of cannibalistic tribes and wild animals waiting to tear you to pieces. Your only hope for survival is your ability to navigate the solution tree, relying on your wits to circumvent the illogical paths of code that “Go To Definiton” has guided you down.

Luckily, Visual Studio 2008 will provide you a guide if you ask for it. Open Tools | Options… | Projects and Solutions | General. Then, check the box for “Track Active Item in Solution Explorer.”

TrackActiveItem

After you have pressed okay in this dialog, when you have a file opened in the editor, the Solution Tracker will automatically select it. The one catch I’ve found is that if the project is contained within a solution folder, the folder must be open.

Bookmark and Share

KiGG View Detailed Story

I recently deployed a KiGG site, but I wanted it to act more like DZone than DotNetShoutOut. On DotNetShoutOut, if you click the link from any of non-detailed page views, it takes you to the site. DZone will take you to the detailed view of the story, and if you click the link from there it will take you story’s site. The reason for this change is that I want my site to foster the community: more comments and viewing promoters. Eventually, I would like to code up a friend system for KiGG similar to DotNetKicks friend system, and I feel that seeing who promoted a story will grow more connections between those in the community.

Here’s how you can implement viewing the detailed story. In your KiGG 2.2 release codebase, open up Kigg.Web\Views\Story\Story.ascx. On line 132, you will find the declaration for detailUrl.

<% string detailUrl = Url.RouteUrl("Detail", new { name = story.UniqueName }); %>

Cut this and paste it immediately after the table tag on line 99. Then, replace the first td’s content with the following snippet of code.

<% if (Model.DetailMode) %>
<% { %>
<h2><a class="entry-title taggedlink" rel="bookmark external" 
        href="<%= Html.AttributeEncode(story.Url) %>" target="_blank" 
        onclick="javascript:Story.click('<%= attributedEncodedStoryId %>')">
        <%= Html.Encode(story.Title)%></a></h2>
<% } %>
<% else %>
<% { %>
<h2><a class="entry-title taggedlink" 
        href="<%= Html.AttributeEncode(detailUrl) %>">
        <%= Html.Encode(story.Title)%></a></h2>
<% } %>

That’s it: simple change! I think it would be better to make this configurable and submit it to the project. I may do that when I have more time to sift through the codebase.

Bookmark and Share

Ease The Pain of Office Interop

If you’re a C# developer who has tried to do Microsoft Office programming, you know how much of a pain it can be. Most of the methods require tons of parameters, and you end up needing to pass tons of Missing.Value argument around.

If you haven’t done this before, it’s easy to get started writing Office programs. First, make sure you have Office installed. Second, add a reference in your project to the Office application you want to automate.

AddReference

Now, add the appropriate using clause (using Microsoft.Office.Interop.Excel;) to your C# code. If you use multiple Office applications, you may wish to alias the namespace to prevent naming conflicts. Most of the Office interops use the same class: Application. Now, create your Excel application object for automation.

var excel = new Microsoft.Office.Interop.Excel.Application();

That was easy enough. Here’s the part where it gets nasty… nearly every method you call requires optional parameters and casting.

Worksheet sheet = (Worksheet)book.Sheets.Add(Missing.Value, 
    Missing.Value, Missing.Value, Missing.Value);

Sheets.Add isn’t so bad, but some methods have dozens of parameters. These only exist to junk up your code. Wouldn’t you much prefer to write the following instead?

Worksheet sheet = book.Sheets.Add();

So would I. In C# 4.0, we get optional parameters and the interop code returns dynamic types, so this is exactly how your code will look next year. But that doesn’t really help us today. Luckily, there is a C# 3.0 feature that will allow you to write readable interop code: extension methods.

public static Worksheet Add(this Sheets sheets)
{
    return (Worksheet)sheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}

Just place that method in a static class and you’re good to go. Then, add methods as you need them. Since you can overload extension methods, you still have the flexibility of optional parameters. Here’s the full class I needed for the piece of Office automation I was working on.

internal static class ExcelExtensions
{
    public static void Close(this Workbook workbook)
    {
        workbook.Close(null, null, null);
    }

    public static void SaveAs(this Workbook workbook, string fileName)
    {
        workbook.SaveAs(fileName, Missing.Value, Missing.Value, Missing.Value, 
            Missing.Value, Missing.Value, XlSaveAsAccessMode.xlShared, Missing.Value, 
            Missing.Value, Missing.Value, Missing.Value, Missing.Value);
    }

    public static Workbook Add(this Workbooks workbooks)
    {
        return workbooks.Add(Missing.Value);
    }

    public static Workbook Open(this Workbooks workbooks, string fileName)
    {
        return workbooks.Open(fileName, Missing.Value, Missing.Value, Missing.Value, 
            Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, 
            Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, 
            Missing.Value);
    }

    public static Worksheet Add(this Sheets sheets)
    {
        return (Worksheet)sheets.Add(Missing.Value, Missing.Value, Missing.Value, 
            Missing.Value);
    }
}
Bookmark and Share

SQL Server 2008 Installation Fail

I was setting up a SQL Server instance on my co-located server, but a series of events led me to uninstall it and reinstall it a few times. The final time through, it detected the original reporting services database, so I cancelled the installation and deleted the SQL Server folders. At that point I spent the next hour or so trying to make SQL Server get past the setup bootstrap installation.

The setup program told me everything was okay before it began the installation. The problem was, the installer just disappeared in the middle (after entering the key, before requesting usernames/passwords): it threw no error, the installation logs said everything was okay, there was nothing in the event logs.

I tried rebooting, but that didn’t work. I tried deleting the registry entries, but that didn’t work either. I checked everywhere I could think of for remnants of SQL Server. I then thought that maybe I dirtied my key with all my install attempts, so I tried to install the developer edition: same problem.

Then it occurred to me to check Programs and Features.

sqlserversetup

Sure enough, the setup program was installed, and it was causing the installer to fail. Uninstalling this fixes the problem.

Bookmark and Share

Refactor ForEach to AddRange

Here’s a refactoring I used to do some minor cleanup today. The programmer was iterating through a dictionary to add values to a list. No logic was contained within the iterator.

public void AddCodes(Dictionary<int, string> indexedCodes)
{
    foreach (var code in indexedCodes.Values)
    {
        Codes.Add(code);
    }
}

This can be simplified by using the list’s AddRange method.

public void AddCodes(Dictionary<int, string> indexedCodes)
{
    Codes.AddRange(indexedCodes.Values);
}

If you’re reassigning, this is even more unnecessary; just use the ToList method provided by LINQ.

public void AssignCodes(Dictionary<int, string> indexedCodes)
{
    Codes = indexedCodes.Values.ToList();
}

This isn’t much of a change, but it did simplify things. The real world example was surrounded by other blocks of code that made it difficult to read. This one, small change helped improve the readability of the method.

Bookmark and Share

SmallBasic 0.5

I happened to notice the SmallBasic 0.5 release announcement and decided to take a look at it. The question going through my mind was, “why do we need yet another Basic programming language?”

You can download SmallBasic 0.5 via the Microsoft Download Center. Here’s the overview.

Microsoft Small Basic is a project that is aimed at making computer programming accessible to beginners. The project comprises a simple programming language that gathers inspiration from the original BASIC programming language; a modern and attractive programming environment; and rich, extensible libraries. Together they make programming fun for kids and adults alike.

After installing it, I was struck by the coolness IDE.

sbide

It’s not nearly as powerful (or even powerful looking) as Visual Studio, but it felt like I had a toy to play with. Not knowing a thing about the language, I started tying and discovered that it has a really cool intellisense dialog.

sbintellisense

Not only is the intellisense window cool, check out that class: Flickr! It has built-in classes for popular services! I am a little disheartened to see a certain evil word, Goto, in that list.

When I started looking at this, I was wondering why we need yet another flavor of Basic. I’ve only played with the IDE and skimmed the documentation, but it did answer my question. I believe SmallBasic is more palatable to beginners and will open the doors for more people to discover the awesomeness of software development.

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
Telerik Developer Evangelist, C# MVP

JustCode

Telerik .NET Ninja

 

INETA Community Speakers Program

 

MVP - Visual C#

 

Friend of RedGate

World Map

Tag cloud

Month List

Disclaimer

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

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