Thursday, November 29, 2007

System.Web.MVC on the Horizon

Looks like we can expect the ASP.NET MVC CTP to be released in about a week.

Great stuff!  Check out some of the other major things that are coming out of Microsoft in the coming months at ScottGu’s blog.

Tuesday, November 20, 2007

Book Review - ASP.NET 2.0 Anthology

A few weeks ago, Jeff Atwood sent me a free review copy of his new book, The ASP.NET 2.0 Anthology.  He co-authored the book with K. Scott Allen (from OdeToCode), Wyatt Barnett, Jon Galloway, and Phil Haack.

Normally I wouldn't get excited about a book like this, but looking at that list of authors I was more than intrigued to give it a try.  Granted, the book is targeted for the beginner to intermediate ASP.NET developer, so a lot of it was not very helpful to me, but I did find quite a few good nuggets that I will take away and utilize in the future.

The first few chapters give a general overview of the newer features of .NET 2.0 and some other basic concepts.  I think that this would be helpful to someone just coming to ASP.NET (maybe from another language) and want to get started. 

The book was published by SitePoint, under their "Anthology" style.  This means the book is organized into 101 different "tips" phrased as questions that someone might ask on a forum or similar.  Some examples from Chapter 1 are "How do I use source control?" and "How do I go about using open source code?" -- I was pleased to see these sections in the book.  You normally wouldn't expect this and I think it helped make the book more well-rounded.

The middle chapters were a bit more targeted to the intermediate ASP.NET level, which made it more interesting for me.  They covered things like custom configuration sections, custom validation, how to maintain control state when viewstate is turned off.  All throughout I think the authors gave solid advice on all these features.  There was a good section on Membership and Access Control, which is sure to be helpful to intermediate ASP.NET developers.

The last few chapters were the most interesting to me, which is funny because most of them weren't specific to ASP.NET.  A section on troubleshooting bothersome SQL queries is sure to help people out.  There were a good number of general web developer tips, such as considering SEO and clean HTML for good search engine rankings.  I appreciated the tip on how to utilize URL rewriting at the IIS level, and how to serve-up custom images to evil hotlinkers on myspace (thanks Jeff Jon!).  These types of things are great to know when pursuing a career as a web developer.  The last chapter introduced SubSonic, which I think was awesome.  Not many developers that I meet have heard of SubSonic and I find it to be a pretty useful tool with a low barrier of entry.  It definitely warranted some attention in this book.

While a lot of the content was your typical ASP.NET 2.0 fodder that I avoid (like SqlDataSource), I thought that the authors did a good job of noting when things were applicable, for example when to use the Web Site model vs. Web Application Projects.  The book didn't have enough beginner content and explanation of ASP.NET to be a beginner book (which is a good thing), but it did have quite a lot of excellent tips that makes this book a great companion to any intermediate developer.

Thursday, November 15, 2007

NHibernate Screencast - Persisting the Address Book

A few weeks ago, Evan Hoff posted a screencast on building up a domain model in a test-first manner.   We talked about it and thought it might be interesting to show how to apply persistence to this already functioning and tested domain model.

So take a look and tell me what you think!  It weighs in at 40 minutes (I tried to keep it under 30 but hey).

Wednesday, November 14, 2007

Zune Gets Long Awaited Sofwtare Update

I was one of the early adopters for the Zune.  My biggest attraction to it was the nice screen, which is great for watching movies on the busride to work.



Well now that the new Zune 2.0's are out, Microsoft released a much needed software update, both on the PC software side and the Zune firmware.  If you have a 1st generation Zune, then go to http://www.zune.net and grab the latest software update!  It's worth it!

Some new features:
  • wireless sync
  • support for podcasts (finally)  -- both in the PC software and the Zune itself
  • updated UI


Friday, November 09, 2007

On Fluent Interfaces and Friction

So I decided to start that NHibernate Mapping DSL project and open-source it.  Right now it doesn't do anything, but you're free to take a look at http://www.assembla.com/space/nhibernate-mapping

I wrote all of this code test-first, and it allowed me to tackle the interface and flow the way I thought might be useful.  I ended up with something that was mildly usable like this:

IMapping mapping = Mapping.For<Product>()
.Identity("Id")
.Property("Name")
.Property("Price")
.Map();

So this allows me to quickly accept the defaults of the mappings, so NHibernate will assume that I have ...
  • the column names are the same as the property names
  • the type of the column matches the type of the property and it can be picked up via reflection
  • the identity generator of the primary key is Identity
  • the identity/properties have setters
  • the "Name" and "Price" columns are nullable
This isn't always true of course, so we need to be able to specify where we deviate from the defaults.  So how can we accomplish this using a fluent interface?  We could resort to adding more overloads to the Identity() method, so you might have....

IMapping mapping = Mapping.For<Product>()
.Identity("Id", "product_id", Access.NoSetterCamelcaseUnderscore, Generator.Native)
.Property("Name", "product_name", false)
.Property("Price", false)
.Map();
But we don't know how many settings the user might want to specify.  If we have 4 simple, independent settings, then we'd have to support 4! method overload options!  Yuck!

public IPropertySpecificationPredicate Property(string name);
public IPropertySpecificationPredicate Property(string name, string columnName);
public IPropertySpecificationPredicate Property(string name, string columnName, DbType type);
public IPropertySpecificationPredicate Property(string name, string columnName, DbType type, int length);
public IPropertySpecificationPredicate Property(string name, string columnName, bool nullable);
...
This is just the beginning.  What if you wanted to only specify the property name and the nullability?  We quickly end up in an anti-pattern I like to call overload explosion

We can do a bit better, right?  I started to gather my thoughts and came up with this syntax:

IMapping mapping = Mapping.For<Product>()
.Identity("Id")
.Column("product_id")
.Generator(Generator.Native)
.Map();
So now the Identity() method takes a single parameter, the name of the property.  Anything else is optional.  The return type is now something like an IIdentityBuilder interface, which accepts methods on altering the identity object that its building.  Here you can see that we only specified the settings that we wanted, nothing else.  We still had to have a way to "pop" the current object (and thus the entire mapping) so that we can indicate to the builder that we are done building the property and you can return the IMapping object next.  This feels awkward for now, but for now it's ok.

Let's extend this pattern.  Once I'm working with the IMappingBuilder interface, I can now see methods called Generator(), Access(), Column(), etc.  There's nothing there to prevent me from calling .Column("...").Column("...").Column("...").Column("...") which I guess isn't such a big deal.  All it's doing is setting the column property of this object we're building.

Now I'm noticing that there has to be a spot where the user gets finished with the mapping identity and now has some choices.  The obvious next operation would be to create a property, but how do I pop the current context and start working on a new one?

Maybe something like this?

IMapping mapping = Mapping.For<Product>()
      .Identity("Id")
      .Column("product_id")
      .Generator(Generator.Native)
      .AndProperty("Name")
      .Nullable(false)
      .Map();

I'm already started to notice that my identity and property elements are getting lost in the noise.  If I keep up this pattern not only do I have TONS of ISomethingPredicateBuilder objects, I also remember that it's not only properties that I can add at any time.  I could add a Bag, a Set, a List, or any number of other mapping elements.

Another route I might take is using anonymous to provide me with the flexibility of code within the interface.  Take a look:

IMapping mapping = Mapping.For<Product>()
      .Identity("Id", delegate(Identity i) {
                         i.column = "product_id";
                         i.generator = Generator.Native;
                      })      
      .AndProperty("Name", delegate(Property p) {
                         p.column = "product_name";
                         p.nullable = false;
                      })
      .Map();
Here I have a lot more flexibility over the different ways that I define various mapping elements.  The only part of this that is really cumbersome is the delegate syntax itself.

This is probably where Boo or Ruby would come in and save the day because of it's super-dynamicness-flexibility-extraordinaire, but I'd like to see how far I can push C# for now.  At least until C# 3.0 comes out, where I'll get object initializers, lamba expressions, and a few other neat tricks that really make this stuff more fun to sculpt.

What about you?  What types of syntax do you find most readable, usable?
Tuesday, November 06, 2007

Prototype & Scriptaculous - Protips #1

I often talk to people who haven't worked with one of the cool javascript frameworks out there.  I am partial to prototype and scripaculous, but I also really like MochiKit.

If you aren't taking advantage of one of these, then perhaps this post is for you... I give you the ultra quickstart to diving into prototype and scriptaculous!

Things you shouldn't ever program javascript without

The best thing ever invented since rubber tires: a replacement for document.getElementById('control_id');

You know you're not supposed to use document.all or document.ctrl_id, right?  Well at least now you do. document.getElementById() is the cross-browser safe way of getting an element off of the page. The prototype equivalent is $('control_id'). This will automatically extend the element returned with some helpful utility methods (like extension methods in C# 3.0). -- more on this later.

Along the same lines is a useful method for selecting elements using CSS selectors. If you're a CSS junkie (like me!) you'll appreciate this.    

$$("div span.info");
This will return all of the DOM elements that would be matched by that CSS Selector. (for those who don't know, this would get all span tags with a class of "info" that are directly nested underneath a div.

Want to show or hide an element? Use Element.hide(ctrl), Element.show(ctrl), or Element.toggle(ctrl). You can attach these methods onto the element itself by saying Element.extend(ctrl). If you retrieved it via the $() method, then your object already has these methods.

Let's say you want to grab all of the span tags from a parent div tag.  Typically you'd do this:

var spans = parentDiv.getElementsByTagName("span");

but what is spans?  If you thought it was an array, you'd be wrong.  It's a NodeList, which is not nearly as powerful as a javascript array.  (With javascript arrays you can push(), pop(), shift(), and other cool things that you can't do with a NodeList.  Anyway, back to the spans collection, we can elevate this to an array by using the $A( spans ) method.  Now we can use all of the nice array goodness for that list.

Effects for that extra polish

How about fading an element?

new Effect.fade(elem);
This also takes options so you can control how fast it fades, for example. Check the excellent docs for all the gory details.

Want to make a slide out box?

new Effect.toggle(elem, "slide");
This will toggle the element using slide up and slide down. ("fade" and "appear" also work here for toggling).

How about some ajax?

Forget UpdatePanels. Most of the time we just need to fire off a request and get a list of values back from the server. Prototype has you covered there:

new Ajax.Request( "/path_to_server/ajax/AjaxHandler.ashx?op=getUsername&value=bob",
{
method: "get",
onSuccesss: function(result) {
if(result.responseText) alert('available!); else alert('taken');
},
onFailure: function(e) { alert('something went wrong ' + e); }
}

I don't know about you, but that's pretty painless to me.

Want something a bit richer?  How about an autocomplete textbox? I wrote this one to auto-complete cities as you type.

var url = '~/AjaxHandler.ashx?op=get_cities';

ac = new Ajax.Autocompleter(city_textbox_id, results_id, url,
{
paramName: 'filter',
frequency: 0.2,
minChars: 1,
indicator: indicator_id,
callback : function(element, filter) {
var state = $(state_dropdown_id);
var state_code = state.options[state.selectedIndex].value;

return filter + '&state=' + state_code;
}
});

That's it. I'm not kidding. I handed it a textbox, a div to display the results, and a url to get the data. It takes care of all of the ajax requests, the frequency limiter to prevent us from firing a request with every single keystroke, and returning the results into a list. It even has full keyboard support. The url looks like ~/AjaxHandler.ashx?op=get_citiees&state=TX&filter=Hou and it will return the matches that it finds (based on an HttpHandler I wrote).

What are your favorite prototype / scriptaculous protiops?

Friday, November 02, 2007

Why No Ribbon in Visual Studio 2008?

Yesterday I was getting frustrated with the completely user-unfriendly massive toolbar that Visual Studio boasts, and noted that Visual Studio 2008 *should* have gotten the ribbon toolbar that shipped with Office 2007.  My cube-mate Peter said,
"They'd probably get sued by the Office Team."

Well said, my friend.  They probably would.  For "Toolbar Infringement." 

Wednesday, October 31, 2007

Fluent Interfaces Allow a Higher Level of Abstraction

Jeff Atwood takes a stand against using embedded languages to express intent. I concur with Ayende's response for most of his points, however I wanted to chime in on the discussion.

Later on, Jeff argues that a better way (or as he puts it, the "ultimate solution") is to include the underlying features of other languages to leverage them natively. He specifically mentions LINQ. Take a look at this sample LINQ syntax:

var priorityCustomers = from customer in Customers
where customer.Status = 'Gold'
select customer;

This syntax is great, and I welcome it for VS 2008. But this is almost the same thing as the Criteria API in NHibernate, or the Querying API in SubSonic. The only difference is that we're not using parentheses and dots all over the place, but the end result is the same.

Having this code directly in our language also makes it more difficult to construct dynamic queries. By dynamic I don't mean make the 'Gold' text a parameter, I'm talking about building the where clause dynamically based on run-time decisions. Using a query builder API such as SubSonic's allows you to do this.

Another point that Atwood makes is that creating fluent interfaces over things like regexes and SQL allows you to NOT learn the underlying concepts, which is unacceptable for professional developers. I agree with him, but LINQ is also one of those! The syntax we wrote above will get translated into a real T-SQL query for us. We should still be cognizant of the SQL that is generated and make adjustments where necessary, but does that mean we always have to program at the lowest common denominator? As professional developers we have to be aware of many technical concepts that are being abstracted from us. A lot of us program in .NET, and most of us probably have a background in C++. I'm glad I learned C++ so that I understand what's going on "behind the curtain," but I'm programming at a higher level of abstraction now. Remember having to always null-terminate your strings (I mean char arrays)?. I'm glad I don't have to do that anymore. Working at a higher level of abstraction allows me to be more productive.

The languages that we see in the coming years will almost certainly bost higher layers of abstraction and specialty, so that we can more easily build data-driven business applications, or 3D-modeled geology simulations, or whatever your domain is. AT&T has just created a programming language called Hancock, specifically geared for mass surveylance. ERLang is designed specifically for mission-critical, always-on systems.  There are many that exist today and even more that we haven't seen yet.  Don't fear the abstractions!

Remortgages - Cheap Car Insurance - Wills - Credit Card Consolidation