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!

Friday, October 26, 2007

Ouch! From the ALTNET Mailing List

Someone suggested to use DotNetNuke for the community site for ALT.NET and I heard this reply:

I'd rather chew glass.

Ouch!

DotNetNuke does have a lot of flexibility and generally buys you a lot, but I don’t find it a joy to work with at all.  Especially the OOB experience is just nasty.

 

Tags:

The MSFT Open Source Conspiracy Continues

The latest news just broke in the previously noted Microsoft Conspiracy to Consume good open source project leaders.  I'm sure you've heard it 10 times before me, but what the hell, what's 1 more?

Rob Conery, creator of SubSonic is joining Microsoft full time to work on SubSonic!  I think this is great news.  First, it reaffirms my belief that Microsoft has their eye dead on the community.  Things are changing, and for the better, mark my words (muahahah).

I can't wait to see how this will affect the project, because I know that Rob has passion, and now that he doesn't have to worry about other projects, clients, or deadlines... he can focus and make SubSonic even better!

Who will be next?  Speculate in the comments...



Thinking of an NHibernate Mapping DSL

Something about Ayende inspires me to build something.  I got to thinking today about how I could create a DSL for NHibernate mapping files.  What's wrong with XML, you say?  Well...

  • It's verbose - XML is known for it's ability to easily validate based on a schema, not for readability.  In other words, XML was designed for computers, not humans.  Since I am a human (are you?) I would prefer something a bit more friendly.
  • Schema Validation takes time - Usually you don't notice, but some recent metrics show that it can account for more than 1/2 of the startup time for NHibernate when there are many mapping files.  If you have an appliaction with 1000 entities, arguably you have bigger problems than XML's readability and schema validation performance, but it IS noticable so hey....
  • Generates runtimes errors for semantic structure - Sure, the syntax is validated, but there are so many things that can go wrong with runtime compilation (that's a weird term) of mappings.
So I got to thinking how we could do better.  Here's what I came up with (with some additions from Ayende) -- it's in Boo:

import flux88.NHibernate.Mapping

mapping Test.Project, Test.Project.Entities

entity Customer,
table: Customers
default_access: "nosetter.camelcase-underscore"entity Customer,
     
        identity "Id",
generator: "native"
       
        property Name,         
column:   "CustomerName",
type:     "String(12)",          
nullable: false

property DateJoined,

property Address,
type: "String(200)"

set _orders,
access: "field",
manyToMany Order,
table: Orders,
pk_column: "customer_id",
fk_column: "order_id",
inverse: true

entity Order,
table: Orders

Note that there isn't a ton of extra fluff, it's meant to be light-weight and easy to write.  Additionally you could set defaults at the top (like default_access) so that you can avoid typing it all over your mappings.

Ayende added the notion of doing this:

for type in assembly.GetTypes():
continue if type.Namespace != "My.Model"
entity type.Name, type.Namespace:
idenity "id"

for prop in type.GetProperties():
property prop.Name

You get the idea.

There could be a number of benefits of doing it like this.  First, you can compile it, so you can get syntax errors notified.  If you use the BooExplorer I'm pretty sure you'd get intellisense for this.  I could also see plugging this into a model validator that would reflect over the model and make sure that all of the properties and access strategies will work with the mapping as defined.

Anyway, I have some reading up on DSL's to do... Ayende, that means I need you to write that book on DSLs with Boo :)  Can I have it next week?

Thoughts?  Suggestions?

Wednesday, October 17, 2007

Bandaids, Coke, QTips, Kleenex, and Ajax

 I’m sure you’ve noticed these…

  • Bandaid - Adhesive Bandage
  • Coke - Soda (at least here in the crazy south)
  • QTip - Cotton Swab
  • Kleenex - Tissue

The world doesn’t need another one:

  • Ajax - Microsoft ASP.NET AJAX

For the 100th time… AJAX does not mean Microsoft ASP.NET AJAX!

Need I say more?

Tags:
Monday, October 15, 2007

MVC versus MonoRail and the Corporate Giant

A lot of buzz is going around about the MVC framework coming out of Microsoft.  I posted about how cool it was and got a couple of comments that basically said: 

They just copied MonoRail.

Well, yes.  In a sense they did.  And Rails.  And Django.  And another one that The Gu mentioned that I hadn’t heard of.  Is that a bad thing?  If you’re using MonoRail today, then you should continue to use it.  Unless you like some of the different syntax or ability to mock the core ASP.NET Runtime objects.

The reason I think that ASP.NET MVC is so exciting and important is because I often come to clients that refuse to (or make it very difficult) to use non-MSFT produced thingies.  Can I use Resharper?  No, we gave you Visual Studio.  Can I use NHibernate?  No we use Enterprise Library.  Can I use NAnt, StructureMap, MonoRail, SubSonic?  Often times the answer is no.  Recently I’ve had experience where our team dumped eWorldUI in favor of ASP.NET Ajax Control Toolkit.  The reason?  Easier to get approved since it has Microsoft’s name attached to it.  It doesn’t matter that eWorldUI is free and easy to implement.  It matters because somebody sees eworldui.dll in a bin folder somewhere and everyone wants to know where it came from.

When you work in an organization with 10,000 employees that has widely adopted Microsoft as a technology platform, trying to get something approved like MonoRail is like trying to convince a Catholic priest that he’s really a MormonOk so that doesn’t really make much sense, but what I’m getting across is that it’s hard.

Some of my readers have already gone down this route, and succeeded.  And I commend you.  But I have yet to get corporate adoption of something like that.  Maybe it’s my inability to convince people of the benefits, or sway their concerns about supportability and such.  Or maybe I just work with very beligerant clients. 

Some of my colleagues probably read this blog, so just so you know I’m not talking about you… I’m talking about the other guy. .

Back to my original argument.  Since this is a new framework coming out of Microsoft, I will not have to fight to get it adopted.  I can go in and say “this is how it’s done for real applications” and have Microsoft guidance to back me up.  Hell, some clients might even ask me for it!  That’ll be interesting.  I can’t imagine what it would be like for a client to come up to me and say “hey I was thinking, maybe we should use NHibernate for this…”

Thinking about that makes me kind of sad that it hasn’t happened before.  Am I just unlucky?  Am I just not skilled at convincing?  Or is this commonplace in the industry?

System.Web.MVC will reach an audience that MonoRail doesn’t:  The corporate giant who already swallowed the pill and will do anything that Microsoft pushes, good or bad.  And a lot of consultants work firmly in this space.

Tuesday, October 09, 2007

ASP.NET MVC or Scott Guthrie is My Hero

The collective jaws were dropped at ALT.NET.  Just about everyone attended this talk by Scott Guthrie.  If you’d like to watch this, Scott Hanselman has recorded the video and posted on his blog.

ScottGu-MVC

Rather than regurgitate it all here, I’ll quickly summarize what it’s like.

Remember HTML?  Yeah, that.  We are going back to our roots and back to the model that the web really lives in, not a psuedo, event-driven state-based model that is ASP.NET Web Forms.

Why don’t we like ASP.NET Web Forms?  I do like it, but it does have it’s problems.  The benefits of ASP.NET often cause other concerns to rise up.  Tired up re-populating data on the form?  Here’s some Viewstate for you.  Of course Viewstate causes page sizes to explode because most people just leave it on, even for read-only pages with no post-backs.  Think of a grid that you place on a page.  If you don’t have to postback to the same page again (like with a command field or something) then you can turn viewstate off and have a savings of almost 2X!  I for one think that ViewState can be awesome, but it is more likely abused than leveraged.  This is a pain point for many people.

The entire postback model, combined with the event-driven model is something that I have had to learn in-depth the hard way.  I really don’t think any of that knowledge is really helpful at all outside of ASP.NET.  I spent a crapload of time trying to get server controls to work in the complicated ASP.NET lifecycle, and does that knowledge transfer?  Probably not.

Lastly I think that ASP.NET’s templated control syntax often requires an equal or even more lines of code than the actual HTML would take in the first place!  Take the GridView for example.  Sure it’s great and it lets you bind data and get columns autogenerated for you, but take a look of that list of properties.  There is so much there that you almost need a degree in GridViews to be effective with it.

Microsoft has been paying attention to the community.  We’ve been readily ditching ASP.NET Web Forms in favor or Ruby on Rails or MonoRail.

ScottGu presented the new MVC framework (codenamed Scalene) to a huge audience.  There was a lot of trash talking (in a good way) between ScottGu and Scott Bellware.  It’s not easy to take blundt criticism from people like ScottB, but The Gu took it incredibly well and even dished it out a bit.

What I really liked about ASP.NET MVC is that there isn’t that much to it.  Here’s what you’d need to do to start using it on your project (exisitng or new):

  • Add the System.Web.MVC.dll (or however it will be packaged — no installer exists yet)
  • Add 1 HttpHandler to handle a new extension
  • Add 1 HttpModule, which provides all of the routing and black magic of MVC

Create a controller class, like this:

//This example is for you, Jacob Lewallen :)

public class ClownsController : Controller

{

    [ControllerAction(DefaultAction = true)]

    public void List()

    {

        ViewData = Clown.FindAll();  //you write this method or use Castle ActiveRecord for example

        RenderView("List");

    }

 

    public void SomethingSecret()

    {

        //this cannot be accessed by a url 
        //because it doesn't have the attribute

    }

}

Next you’ll need a view.  You can use aspx, Brail, or NVelocity as your templating language.  That’s freaking great that you can choose.

Here’s a quick example of an aspx view:

<h1>Clowns</h1>

<table>

   <tr>

    <th>Name</th>

    <th>Number of Balloons</th>

    <th>Likes Kids?</th>

   </tr>

 

   <% for(var c in ViewData) { %>

 

   <tr>

    <td><%=c.Name%></td>

    <td><%=c.Balloons.Count.ToString() %></td>

    <td><%=c.LikesKids? "yes" : "no" %></td>

   </tr>

 

   <% } %>

</table>

Notice how I get to use standard HTML constructs, use code blocks to provide view functionality & data, and I don’t have to mess with postback or viewstate at all because I don’t need it. 

Wait, you mean we have to learn HTML again?  D.H.H. often reminds us that the HTML is provides beautiful constraints that he is happy to work inside of.  We don’t have any naming containers here.  In fact, we don’t have any unnecessary id elements at all!  If we did, they would be exactly what we typed here, making javascript integration a lot easier.

To wrap this all up, a customizable route in the Global.asax will map the following url to render this page:

http://your_url/clowns/list    <—  look how clean!

The framework knows how that the format is http://your_url/[controller]/[action] and so it instantiates your ClownsController and looks for an action called List().

So much more to talk about, but I’ll be posting more details once I get my hands on it.

ALT.NET Goodness

Wow.  What an awesome event.

I’ll skip the play-by-play, because that has been covered to death.  Instead I’ll focus on my notes.  There are definitely some “meaty” posts in my mind that are still storming, so expect good things to come.  There are some good points here, but it’s a long post so I’ll be surprised if I get any comments .

Being a Catalyst for Change

I first attended a session on “Fostering Passion” and “Being a catalyst for change” which were grouped together.  A lot of people showed up and J.P. Boodhoo led us off.  He talked about the importance of a good, healthy work attitude, and if you aren’t getting what you need from your current employer then you should really seek out something better. 

  • You need to show pain before you can start evangelizing new stuff.  Ask people the question “How is that working for you?”  or “What would you want to improve first…. why?”  This gives you the context and the opening for suggesting new ideas.
  • Talk about problems in context with the 4 variables, this helps lead to whether something is “working” or not
    • Time
    • Scope
    • Quality
    • Budget
  • Hosting brown-bag sessions is a great way to get people excited.  Scott Hanselman pointed out that he found it valuable to create a “shadow government” of peers who you can individually get excited about different topics.  Ask them to give a lunch & learn and spread the word that way.  Somebody called them “Hanselminions”  —  epic.
  • JP Boodhoo stressed that we build relationships before we offer to “fix up their processes.”  If you come in wanting to change everything you’ll just alienate your team and ruin your credibility.
  • Another thing that we discussed is that newcomer’s to our community are going to be very overwhelmed…  currently there isn’t much direction.  We don’t want to be prescriptive, but a general “go in that direction” will definitely be helpful.

Advanced NHibernate

The next session I attended was Advanced NHibernate Techniques, facilitated by Jeffrey Palermo.  I found this to be awesome, because usually when I get to talk (or listen) to NHibernate at a user group or code camp, it’s focused on the beginner side of it.  Everyone in the room had been using it for a while, and had some really good suggestions and valid problems with it.

  • ActiveRecord vs. Persistant Ignorant?
    • I suggested that for dead-simple models, or a team that doesn’t know DDD, that AR was a much easier path with less friction, however you do quickly hit a limit here when you want to start using more Domain Driven Design such as the Aggregate root/aggregate relationship, repository pattern…  or if you need these to be remote… they can’t be used on the client side.  Somebody pointed out that it is very difficult to switch from one to the other, and this makes the initial decision very hard.
    • Howard Dierking pointed out that “No Simple CRUD app stays that way”
  • Database, Mapping, Code -> which first?
    • This was basically a poll question.  Almost everybody here started with code, then database, then mapping.  Very few people used hbm2ddl (like I do) to generate the database.  We all agreed that generating the database needs to be abandoned once you start doing tuning and specific tweaks.  The Eleutian guys (who have names, by the way… Aaron and Jacob) have a pretty hefty process that all starts with a modeling tool.  It kind of scares me, but they seem to have it working so that they don’t have to re-work anything.  To be truly DRY you definitely need another abstraction, however I’m not convinced that UML is it.   What if we had a Boo DSL that represented the mapping, and we could specify advanced DDD concepts there, and have it generate the code, hbm, and Database…?
  • Issues?
    • Aaron and Jacob have been stressing about Adaptive Queries and Read-only queries, and I need to make an effort to understand their problem.  Originally I dismissed this as a non-issue, but that’s a cop-out.  I want to understand what they are wanting that they aren’t getting with NHibernate.
    • We all seemed to agree that it’s painful that if you have a single error in your mapping file, the session factory throws an exception and just about every test in your application will fail.  This SUCKS for pinpointing the error.  I heard Howard mention something about jitting the mapping assemblies (I guess while writing?) — I definitely need to continue this discussion with him.
    • Partials mappings would be pretty cool, so you could generate the mappings based on default conventions, then you could override when necessary.

ASP.NET MVC Framework presented by Scott Guthrie

  • This flippin’ rocks.  A detailed post to follow.

Domain Driven Design – Facilitated by Dave Laribee and Scott Bellware (with a cameo from yours truly!)

  • This was pretty much review for me, but it’s always good to get refreshed.
  • Opening your mouth is a good way to get people to ask you another question (provided you didn’t say something completely stupid) — I kept getting asked to explain more topics here, which was flattering.
  • At one point I said “If you haven’t read Evans yet, go TODAY and buy his book.  Then read it 8 times.”  — This led people to believe that I had read it a few times.  Nope!  I still have 7 more to go .
  • A lot of discussion went around the different between responsibilities of the entities, and the responsibilities of domain services (not to be confused with application services or <gasp> SOA).

User Stories (facilitated by Scott Bellware & Raymond Lewallen)

  • The more I dig into this stuff the more I like it
  • Epics– 30,000 ft view (almost impossible to estimate) (if you have to, also provide a low confidence value)
  • Theme – closer, but not enough to estimate.  Gives more detail.  Many themes per epic
  • Story – small enough to provide estimate & acceptance criteria.
  • Ray said “I can give you a gantt chart & have it say whatever you want on it.”  — this is funny, but SO true
  • Estimation accuracy and Trust are increased as time goes on… providing you aren’t making empty promises early on
  • Don’t estimate a user story until you have acceptance criteria
  • Acceptance Criteria (AC) can be technical
  • AC helps define “done”
  • Early stories will add a LOT of new concepts
    • new models
      • tables, entities, whatever
    • some UI req’s
  • Estimating epics helps w/ product planning  (“How much can we put in by next year?”)
  • Release planning should NOT include epics.  Break them down.
  • AC transitions, which leads is implemented in TDD/BDD style
  • Test names should describe the behavior, not impl.  I’ve got to follow this rule more often.  A lot of tests I write are explicit in that I know what happened if it failed, but the actual story that I’m working on is missing.  The failing test has no context, and thus no value associated with it.
  • BDD classes are named after the state or original behavior.  The setups for this class put the object in that state.
  • Method names are named like the AC
    • public class When_a_case_is_opened
      • public void Its_status_is_changed_to_open

Are Executable Requirements Possible?

  • Jeremy Miller started off by stating the value of Fit vs. FitNesse and a lot of people showed pain with FitNesse. 
  • Fit/FitNesse works great when dealing with state-based testing
  • Behavior based testing is where it breaks down and becomes really cumbersome
  • He invited Joe Ocampo (from Los Techies) to talk about NBehave
  • NBehave solves their problem of providing change tracking and traceability into their organization because they have a strict environment that requires it.
  • They have a fluent language that looks like theUserStory.AsA(“Premier Member”).IWantTo(“get a discount on future purchases”).SoThat(“I can save money”)
  • I joked that they could also have another fluent interface that looked like SystemShall.(“Have a textbox”).ThatShallContain(“the user’s name”) 
  • This helps solve the issue where refactoring is difficult.  Since the strings above are keys for delegate hashes, you’ll get an exception if someone changes the text of a story.  This will spark a much needed conversation with the developers.

I’m still trying to bask in the awesomeness that came from this event.  All you naysayers out there are just upset that you missed out .

Loan - Mortgage Calculator - Homeowner Loans - Bad Credit Loans