April 2005 - Posts

FeedDemon with Newsgator Synchronization the perfect combo?

Over the past few months I've been using Newsgator online to read blogs.  I love the fact that it allows me to read my feeds from whatever machine I happen to be using, whether it's my Mac, my desktop PC, my laptop, or my work computer.  I can get close to that with RssBandit and it's synchronization feature, however, it still doesn't do it automatically which I need it to because I'm not smart enough to always synchronize my feeds when I open and close it.  In addition I'm out of luck if I want to check my feeds when I'm on my Mac or on the road on a "guest computer.

Having FeedDemon sync with Newsgator might be just the combo I've been looking for.  Not only does it allow me to continue to use Newsgator Online when I'm not at a computer with FeedDemon installed (such as when using my Mac) but it also allows me to have feeds at different locations that are only relevant to that particular location, such as having a Community Server feed for our local tech blogs at work.

I've really been wanting to try Omea as well but the lack of synchronization is a deal breaker for me.  If it don't sync it ain't for me. :-)

Is anyone else using FeedDemon with the Newsgator/Bloglines sync?  How's it working out?

Closures / Anonymous Delegates as DDD Specifications

There’s been an interesting discussion going on in the Domain Driven Design yahoo group recently that started as a result of my “Predicates, Actions, and Comparison’s” post.  I’ve really enjoyed the discussion since its confirmed many of my thoughts on the validity of using anonymous delegates as “Specifications” in the DDD world.

The start of the thread can be found here:  Is this a Specification?

What are closures?

In my previous post I pointed to some information from Mr. Fowler on closures as well as a link to a page that compares closures in Ruby with what we now have in C# 2.0.

This post is an attempt to write down my understanding of closures as to make it stick a little bit better then it did when I just read a couple overviews.

If we hop in the “way back machine” we can find closure support in languages that have been around for a long time, such as smalltalk.  Those in the smalltalk world have been working with closures, which apparently are called blocks, for a long time.  One of the more popular languages at the present time that supports closures is Ruby.  I’m pretty sure most dynamic languages support closures in some form or another but I could definitely be making that up. 

Anyway back to the task at hand, what is this closure thing we’re speaking of and why should anyone care?  Basically a closure is a block of code that you can pass as an argument to a method.  Different languages support the passing of parameters to the “block” of code in different ways.  In Ruby their passed in between vertical bars like |so|.  In C# 2.0 they’re just declared as arguments when we define an anonymous delegate.

As Martin Fowler points out closures sound an awful lot like function pointers.  Although they’re similar there are a couple differences.  The first main difference is that closures can refer to the variables that are in scope at the time the closure if called.  This means that our closures can reference variables declared outside of the closure.  Try that with function pointers or anonymous inner classes, I dare you!?!  Ok, not really.  Moving on…

Ok, so that might not be that big of a deal, so let’s move onto the bigger differences.  So the “first crucial point about closures is that they are a block of code plus the bindings to the environment that they came from.” (Fowler).  Ok, so they’re not just out in space with no connection back to their home.  They actually have a connection back (binding) to the environment that they came from.

The things that I found interesting about closures is how it lets you express things in code.  Although the syntax takes a little getting used to using closures to perform filtering, sorting, converting, and all that other fun seems like it could reduce the amount of code it takes to do such things by a pretty good bit.

The important thing will be to ensure you don’t start using closures all over the place.  The simplicity could lead to closures scattered all over the place which could get ugly fast.  Just like anything else it’s probably a good idea to encapsulate the closures within you’re business objects.  Or not :-)

Looking for more?  Check out http://blogs.msdn.com/kcwalina/archive/2004/06/22/162533.aspx for more API’s that support closures (aka anonymous delegates).

Closures in C# 2.0

I came across a good post comparing the closure support in C# 2.0 with it’s Ruby counterpart.  For a brief introduction to closures check out Martin Fowler’s description.  After reading that check out Joe Walnes “The power of closures in C# 2.0” that shows the equivalent of the Ruby code Martin shared in C# 2.0.  Cool stuff!

Converter and ConvertAll()

Ok, So Mitch’s blog is definitely getting added to my blog roll.  Building on my previous example let’s assume we want to get a list of all the ages of our customers and work with them as a list of int’s rather then dealing with them as a property of the customer, enter Converter<T>.

List<int> allAges = customers.ConvertAll<int>(delegate(Customer customer)
{
   return customer.Age;
}
);

Assert.AreEqual(customers.Count, allAges.Count);
allAges.ForEach(delegate(int i)
{
   Console.WriteLine(i);
}
);

This allows us to convert all objects in one list to another list. Cool!

Predicates, Actions, and Comparison's oh my...

Tonight I was playing with some code trying to wrap my head around the usefulness of anonymous methods.  I started looking at some sample code in various places that all failed to “click”.  I eventually stumbled upon a couple posts by Mitch Danny's blog that helped me see the light.  The generic collection classes have a number of different methods for working with items within the collection such as Find, FindAll, and ForEach. 

The Find, and FindAll methods have a single Predicate<T> parameter.  Using FindAll along with the generic Predicate<T> delegate can help you to filter a list of objects very easily.  Let’s start with a little boiler plate code.  First I defined a Customer class with a single Age field:

public class Customer {
   public Customer() { }
   public Customer(int age) {
     this.Age = age;
   }
   public int Age = 10;
}

Let’s now assume that we want to get all customers that have an age greater then 20.  We’ll start with a generic list class containing a couple sample customers:

List<Customer> customers = new List<Customer>();
customers.Add(new Customer(19));
customers.Add(new Customer(21));
customers.Add(new Customer(20));
customers.Add(new Customer(40));
Assert.AreEqual(4, customers.Count);

In order to begin filtering our list of customers we can use the FindAll(Predicate<T> method on the generic list class along with an anonymous method (since that’s what we started off trying to learn about).  The logic within the anonymous method will get called for each customer in our list.  If the anonymous method returns true (if the customer’s age is greater then 20) then the customer will get added to the list of customers that will be returned from the FindAll method.

List<Customer> customersOver20 = customers.FindAll(delegate(Customer customer)  {
      return customer.Age > 20;
   }
);
Assert.AreEqual(2, customersOver20.Count);

To make this a little more clear the code can be broken out into this:

Predicate

<Customer> customersOver20Predicate = delegate(Customer customer)  {
   return customer.Age > 20;
};

List<Customer> customersOver20 = customers.FindAll(customersOver20Predicate);
Assert.AreEqual(2, customersOver20.Count);

First we declare our predicate delegate, and then we pass the predicate to the FindAll method on our generic list.  Pretty sweet if you ask me.  I’m only beginning to think about all the different ways this could be used but it seems pretty exciting.

We’re not done yet.  We can also take advantage of the Comparison<T> delegate as well as the Action<T> delegate.  The Comparison<T> delegate allows us to implement sorting within customer collections like so:

customers.Sort(delegate(Customer c1, Customer c2) {
  return c1.Age.CompareTo(c2.Age);
}
);

The Sort method takes a Comparison<T> delegate, which we use to implement sorting by age.  The final thing that we’ll use is the Action<T> delegate to list out the items in our list via the generic lists ForEach method.

customers.ForEach(delegate(Customer c)  {
      Console.WriteLine(c.Age);
   }
);

Although I didn’t really find out that much about anonymous delegates I did discover a whole bunch of cool shit that’s within the generic collection classes (Find, FindAll, etc.) as well as a bunch of interested predefined delegates that work with generic types Predicate<T>, Comparison<T>, and Action<T>.  A big shout out goes to Mitch Denny for his list of articles that introduced me to such a wonderful little nicety within .NET 2.0.

I want my double click in server explorer to open a table not the schema

One of the things I always liked about VS.NET is that it “knew” that when I double clicked on a table I wanted to view the data within that table.  Enterprise manager isn’t “in the know” and always shows me the layout for my table.  Unfortunetly VS.NET 2005 has gone back to a double click opening up into design mode for the table rather then opening up the table and displaying the current data within it. :-(

What’s your preference?

ASP.NET Internals

I came across a good article on MSDN detailing some of the internal changes in ASP.NET 2.0.  Although its fun to hear about all the new features, controls, and other snazzy things that we get with .NET 2.0, one of the most important things to note are the changes to the internals.  Without a full understanding of the internals its difficult to master the newfound beauty of .NET 2.0.  Check it out.

Why must 3rd party software always be so painful to work with?

The project that I'm currently working on is using a 3rd party content management system. It provides all the features you'd expect in a CMS and all the marketing material provided makes everything seem easy enough.  As we get deeper into the implementation more and more of the warts of the CMS are presenting themselves.  The system seems very capable for managing basic websites, however, is lacking in several areas when it comes to managing a large website such as the one we're using it on.

It seems like everytime we use a 3rd party component or software packages to help speed up our development efforts it winds up making everything more painful.  An exorbitant amount of time is spent hacking away with the software trying to get it to work the way we need.  It provides some basic features that are useful, however, is lacking in many very important areas which brings the development to a grinding halt as workarounds, hacks, and pure nastiness is considered so that the solution can be delivered.

These experiences always bring me back to one question.  Is using 3rd party software really worth it?  In the amount of time it takes to learn, customize, and hack away at the 3rd party software we could have built a custom solution to do exactly what we needed.  It would have provided us with all the functionality we needed, would have allowed us to add new features and functionality as needed, and made the experience of working on the project much more pleasant.

Do I just have bad luck with 3rd party software or is this something others are seeing and feeling as well?

My Dreams of a Free Mac Mini are fading

It doesn't appear too many people are up for helping a brotha get a free Mac Mini.  A decent number of people have registered but none have actually completed an offer.  This will be my last attempt at getting people to help, as the "help me get free stuff" to "useful information" ratio on this blog is dipping below acceptable levels.

Go get your FREE MINI MAC

RE: Can I still use base page classes in Whidbey?

I've exchanged a couple emails with some Microsofties relating to the issue I posted a couple days ago regarding using base page classes in Whidbey.  It turns out that the "new model" of compiling the aspx pages prevents the base page setup that I have used on a couple different applications from working.  There are a number of workarounds to the problem but they all involve updating code in one way or another.

Option 1
In InitializeComponent (or OnInit) in the base page use FindControl to set the reference to the control.

            saveButton = (Button) this.FindControl("saveButton");  // MyBasePage

Option 2
Update each page to set the button instance in the base class to the version in the code behind class.

            base.saveButton = this.saveButton  // Default.aspx.cs

Option 3
Use reflection to automatically hook up the controls.  This causes a performance impact so isn't a good idea in most situations.

I wish this would "just work" (tm) however after a couple conversations with the peeps over at MS I think I understand the basics of why it's an issue.  I think the problem will somewhat go away as I migrate to v2 and begin to take advantage of all the new "super fun cool stuff" that it provides.

I do want to give a quick shout out to Scott Guthrie and his team for following up on the issue pretty much immediately after I posted.  Within a couple hours I had exchanged several email's with his team (I'm assuming) and at least had an understanding of what the issue was.  It's nice to see such responsiveness from the powers that be over in the "big house".

 

Object Caching with AOP

I found this article pretty interesting.  It talks about implementing object caching with Aspects.  While I haven't done anything using real aspects I have implemented a "CachedEntityProvider" that can be configured to cache the results of queries to the data store.  I've only started playing with more advanced configuration such as setting the cache duration on a query by query basis, as well as providing more advanced options on how the query results (objects) are cached (duration vs. sliding expiration).

The implementation was a pre .net 2.0 implementation so it's not using the official "Provider" model but I'll certainly be looking into the potential for migrating it as I begin to dive deeper into the depths of beta 2.  The only concern at this point is that the out of the box provider "goo" we get doesn't provide enough flexibility in the configuration.  Last I looked it was passing configuration data via a Name/Value pair which would prevent more advanced configuration for per object / per query caching.

ConfigurationSettings becomes ConfigurationManager

In v1.1 we used the ConfigurationSettings class to read values from our configuration files (web/app.config), in .NET 2.0 we now have the ConfigurationManager class.

ConfigurationSettings.AppSettings[”MySetting”];

becomes

ConfigurationManager.AppSettings[”MySetting”];

 

Can I still use base page classes in Whidbey?

Tonight as I was experimenting with Beta 2 I ran into some troubles with my pages that inherit from a base page class.  All the controls that we’re being setup in the base page class were throwing NullReference exceptions.

MyPage.aspx  inherits MyPage inherits MyBasePage

MyPage.aspx and MyPage.aspx.cs don’t need controls defined since they are partial classes and have the magic that goes along with being setup as such.  The MyBasePage class however isn’t a partial class since it lives in a completely different location (different assembly).  In that base page class I have protected Button saveButton defined, but it’s always null.  What’s the magic step that’s necessary to be able to get a reference to the saveButton from within my base page class?

UPDATE: Well I was able to retrieve a reference to the controls by doing a this.FindControl within the Init of the page.  This isn’t a terrible change, but, I am wondering if it’s the answer to how to support this.  To provide a little more context.

In 1.1 I had a base page EditPage.cs with the following declaration:

protected System.Web.UI.WebControls.Button saveButton;

protected virtual void InitializeComponent() {
   this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
}

When I run this in .NET 2.0 I get a NullReferenceException, unless I do something like:

protected System.Web.UI.WebControls.Button saveButton;

protected virtual void InitializeComponent() {
   this.saveButton = (Button) this.FindControl(“saveButton”);
   this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
}

So what’s the scoop, is this the only way to support this or am I missing some super duper special keyword, attribute, or magic wave of the hand to get this to work?

UPDATE #2:

Source from my test is available here.  I get a warning when I compile (below) and when the MyBasePage tries to setup the Click event handler a NullReferenceException is thrown.

“Warning 1 '_Default.myButton' hides inherited member 'MyBasePage.myButton'. Use the new keyword if hiding was intended. C:\Inetpub\wwwroot\AspNetv2\Default.aspx 1 1 C:\...\AspNetv2\”


Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
<title>Untitled Page</title>
</
head>
<
body>
<form id="form1" runat="server">
<div>
<asp:Button ID="myButton" runat="server" Text="My Button"/>
</div>
</form>
</
body>
</
html>


Default.aspx.cs
public partial class _Default : MyBasePage {
   protected void Page_Load(object sender, EventArgs e) {
   }
}

MyBasePage.cs
public class MyBasePage : System.Web.UI.Page {
   public System.Web.UI.WebControls.Button myButton;
  
   protected override void OnInit(EventArgs e) {
      myButton.Click += new EventHandler(myButton_Click);
      base.OnInit(e);
   }

   void myButton_Click(object sender, EventArgs e) {
      Response.Write("Button Clicked");
   }
}


 

System.Web.SmtpMail becomes System.Net.Mail.SmtpClient

// set smtp server

SmtpMail.SmtpServer = System.Configuration.ConfigurationManager.AppSettings["SMTPServer"].ToString();

// send mail
SmtpMail.Send(from, to, subject, body);

Now becomes:

SmtpClient mail = new SmtpClient();
mail.Host = System.Configuration.
ConfigurationManager.AppSettings["SMTPServer"]
mail.Send(from, to, subject, body);

10 Things you shouldn't do with SQL Server

Doug Seven has a good article over on sqljunkies.com that talks about the 10 things that you shouldn't do with SQL Server.

 10. Add a Low Privelage Account to the Admin Role

 9. @@IDENTITY vs. SCOPE_IDENTITY

 8. Fetch Semi-static Data on Each Request of a Resource

 7. Include SQL Data Manipulation Language in Application Code

 6. Abuse SELECT *

 5. Create Stored Procedures without Exception Handling

 4. Prefix Stored Procedures with "sp_"

 3. You Don't Protect the Database Connection String

 2. Accept All Input

 1. Access the Database from the Application with the "sa" Account

Geeks Rule and MBA's rule

Well, I think I’m a little biased too but I agree with Eric and Joel that:

 If you ask me, and I'm biased, no software company can succeed unless there is a programmer at the helm.

Check our Eric Sinks latest Business of Software column, “Geeks Rule and MBA’s Drool”, within it he’s likely to offend many non-geeks and help boost the ego of developers everywhere to all new heights.

Books for the programmer beginner

Does anyone have any recommendations on books for "beginner" programmers?  Although these aren't necessarily for the beginner the below list of books are the ones that came to mind when I started thinking about what I would recommend people read.

Bayesian Filtering for Blog Posts?

I recently was cruising around the Fog Creek Software website checking out the latest version of FogBugz as well as CityDesk and came across a very interesting feature that was part of the recent FogBugz release.  FogBugz 4.0 uses Bayesian Filtering to help filter incoming email into appropriate folders (read more) which sounds like a very nice feature. 

What would be cool is if this could be built into some sort of blogging engine, or content management system.  I always forget to set the categories when I’m posting my entries and going back and updating the assigned categories is something that simply doesn’t happen.  If my blog engine could do this for me automatically it would be super sweet!

Introducing Agile to a legacy project

Brian Marick recently posted his “talking points” for how to introduce Agile to a legacy project.  I think this is something that is often overlooked in the agile community.  There is oodles and oodles of documentation about how to run an agile project when you’re starting fresh, but I haven’t seen very much on how to introduce agile into an existing “legacy” project.  Usually the team is deciding to give agile a try because of disappointments on previous projects, which are usually still around.  This poses some difficult problems since the legacy code usually doesn’t have very many (if any) tests, is likely highly coupled, and possibly a complete mess.  Brian’s post provides some good guidance on how to get started when you’re in such an environment.  The most important thing to note is that it should be gradual process, you can’t make a project agile in a day or week, but you can begin to see immediate benefits from moving in an agile direction.

Finding a good company name

One of the things that I always think is interesting is the names people choose for their companies.  What’s the story behind “Fog Creek”?  Where’s the “fog” and who’s “creek” was it?  I often find that the most random names are the ones I find interesting.  Shouldn’t the names that describe the company be the ones I remember? 

What do you think makes a good company name?  What are the brands that you remember, what is it about them that makes them “memorable”? 

Another problem that should be fixed in the software development industry...

Last week Darrell posted an entry on “How to fix the software development industry”.  I think Darrell hit the nail right on the head with his post.  If you still haven’t read his post, go read it now…..ok, all done?  Good.

Now, moving on.  One of the problems that I see with the software development industry revolves around how the best of the best are treated within software and/or consulting shops.  As we go through our career we’re continually learning new skills that can help us “code better.”  When I started out programming I thought I was the shit, but, much to my dismay I wasn’t.  Years later I’m still learning new and better ways to develop software.  As we all know the deeper you get into this industry the more you realize there is to learn.  The best programmers typically are the the ones that are doing everything they can to get better at what they do.  They read books, study design patterns, learn the tricks of refactoring, and deepen their technical skills to help them get better at writing code.

As they learn and grow people begin to take notice.  Their managers begin to look for ways to reward them for their hard work.  They begin to be placed into leadership roles that allow them to mentor and guide other resources. Slowly they begin to be placed in bigger and better positions, leading and guiding bigger and better projects.  They get a chance to manage a team, tell people what to work on, get to do some initial designs for the system, and then manage the team throughout the build of the project.  The process continues until eventually that all star coder is doing everything except writing code. 

As more and more of the all star’s are placed into managerial positions the team’s strength begins to weaken as other “less skilled” resources are brought in to fill their shoes.  After all it’s just a programmer, any old person can come in and fill that position.  As the value of the programmer is devalued those in the industry that may have otherwise considered a long career as a software developer begin to look at other “more respected” positions such as Project Manager.  After all who wants to be one of those grunts that sits at a keyboard all day hitting keys to make turn the c