About 5 years ago I decided that I had enough of building my own PCs. It stopped being fun for me and became a chore. So at that time I came up with an experimental PC purchasing plan. I would spend $2k-$3k on a PC that will then last 3 years and then upgrade.
The plan worked great. So great in fact that my last PC lasted 5 years. :D
Its still a great PC. At the time I mostly gamed. Sure I was coding at work, but when I got home, I was gaming. Therefore, the specifications for the computer were gaming related. In end the PC’s specs were roughly : 3 Ghz intel p4; 3 gigs of ram; 512mb PCI-E x16 Nvidia
Still a great machine for gaming.
But now I spend near 100% of my time coding. When I do game, my friends and I all have xboxs. Its cheaper and easier to hook up online and play than a PC. At least I think so.
Now when I code, I have multiple Visual Studio sessions open, maybe streaming a video, maybe downloading files, etc. My poor single processor PC was under a very demanding load.
But riding in to save the day is my new PC I bought from Dell.
Its specs:
XPS 730X, Intel Core3 I7-950 (3.06GHz, 8MB cache)
6GB Multi-Channel DDR3 at 1066MHZ (3x2GB DIMM)
SLi, Dual nVidia GeForce 9800G512MB
300GB Western Digital Velociraptor - SATA-II, 3GB/S 10000RPM, 16MB Cache
Niiiiice. :) The thing is freaking enormous.
This is my first PC with a multiple core and with a 64 bit processor (and OS).
So far tonight I’ve done nothing but install Win 7 and an assortment of applications. Its amazing how many little addons and applications you forget you use on a daily basis.
I am not an OS guy. I don’t really care for command lines nor all the super duper features. I just like things to work. I am one of the few out in there that liked Vista and didn’t find anything wrong with it.
But Win 7 is supposedly da bomb so why not upgrade? The most I’ve noticed about Windows 7 is the new taskbar (which I like). I think the main trend I’ve noticed going from Vista to Win 7 is that the most common tasks I do are closer… if that makes sense. So things that were 2 clicks away are now 1 click away.
I’m going to get back to playing with my new toy. I look forward to the many years of development I will get out of this machine.
When I was first exposed to the idea of fluent interfaces my response was… big flipping deal.
It wasn’t until I actively started using fluent interfaces in my code did I begin to see their power and elegance.
What is a fluent interface? Here is the obligatory link to wikipedia ;)
In simple terms, its returning a type instead of void in order to achieve method chaining.
The end goal of the method chaining is to provide a more readable interface and code.
First, does it break the Law of Demeter?
Law of Demeter doesn’t equal the number of periods. I am of the opinion fluent interfaces do not violate the Law of Demeter.
What is LoD? Another link to wiki and here is a link to a stack overflow on this very subject! :)
To me, Law of Demeter is about restricting communication between objects.
A common violation of LoD (imho) is the exposure of a list property on an object. I believe this serves as a good example of LoD as well as being an example on how to make a fluent interface. :)
A Person object has a name and a list of friends.
12345678910
publicclassPerson
{
publicstringName{get;set;}
publicList<Person>Friends{get;set;}
publicPerson()
{
Friends=newList<Person>();
}
}
I could then add friends by…
1234
varroger=newPerson{Name="Roger"};
roger.Friends.Add(newPerson{Name="Eddie"});
roger.Friends.Add(newPerson{Name="Freddie"});
roger.Friends.Add(newPerson{Name="Gordie"});
Now this is pretty typical, so what’s the problem?
Well my code knows WAY too much about Person. I know it has a list of friends and if they change that list to say a dictionary, I am hosed.
Not only that, but poor Person class… people can add friends to his collection without him every knowing. What if some additional logic needs to be done when adding a friend?
What if the person wants to record the birth date of every friend so they can send out birthday cards? Person is SOL.
As for Law of Demeter, my code is using the Person object to communicate through to the List. I am exposing my code to changes in Person.
Let’s change Person to eliminate this problem.
123456789101112131415
publicclassPerson2
{
publicstringName{get;set;}
privatereadonlyList<Person2>_friends;
publicPerson2()
{
_friends=newList<Person2>();
}
publicvoidAddFriend(Person2friend)
{
_friends.Add(friend);
}
}
Now the only way to add a friend is through Person. Yippie!
1234
varroger2=newPerson2{Name="Roger"};
roger2.AddFriend(newPerson2{Name="Eddie"});
roger2.AddFriend(newPerson2{Name="Freddie"});
roger2.AddFriend(newPerson2{Name="Gordie"});
If I wanted to make this a fluent interface all I would need to do is instead of returning void, return the Person class.
12345678910111213141516
publicclassPerson3
{
publicstringName{get;set;}
privatereadonlyList<Person3>_friends;
publicPerson3()
{
_friends=newList<Person3>();
}
publicPerson3AddFriend(Person3friend)
{
_friends.Add(friend);
returnthis;
}
}
Now I can do the same logic like…
1234
varroger3=newPerson3{Name="Roger"}
.AddFriend(newPerson3{Name="Eddie"})
.AddFriend(newPerson3{Name="Freddie"})
.AddFriend(newPerson3{Name="Gordie"});
That is pretty cool, but fluent interfaces really shine with the builder pattern.
This time around I want to force construction of a person through a builder and have the builder use a fluent interface. Notice my Person’s constructor and fields are private. I embed the builder class within the Person class so the builder has access to the constructor and fields. In this manner only my builder class has access to constructing a person. My builder can now act as an anti-corruption layer for Person.
It’s a simple example but maybe it sparked some ideas on how to use fluent interfaces to chain methods and make your code more approachable to people without Computer Science degrees. :D
But I couldn’t just leave it at that. I wanted to show a different approach to solving the same problem. * A later tweet explained his problem was more a datacontext issue, which the snippet I provided should fix. This post does take a different look at how to approach handling read only controls.
How can we make a control ‘read only’ through binding?
As you can see I use the IsReadOnly property on the base view model as a data trigger and then completely swap out the control template for the text box. This allows for complete customization of the read only look. It also pushes this functionality out into a style to be reused through the entire application.
Other things to note with the project (for those unfamiliar with the following practices):
So whenever WPF tries to resolve the PersonViewModel in a container, it will use this DataTemplate since I did not provide a key but only a DataType.
So in Window1 I can do…
123
<ContentControl>
<PersonView:PersonViewModel/>
</ContentControl>
Again this is a very simple scenario so I am ignoring any presentation patterns on how the ViewModel is placed or ‘shown’. Also ignoring how dependencies can be resolved, etc.
And even though this is a content control, this works for items controls as well. So consider a stack of ‘views’. You could be accomplish this simply by placing a collection of ViewModels in an ItemsControl.
But really… that’s for another post.
2. Expression for INotifyPropertyChanged
I am also using a LambdaExpression to implement INotifyPropertyChanged. Essentially achieving safe notification and eliminating those nasty magic strings.
123456789
publicstringFirstName
{
get{return_firstName;}
set
{
_firstName=value;
OnPropertyChanged(this,m=>m.FirstName);
}
}
Anyway.. that was a quick project I threw together. I hope it was helpful.
So Ryan, the apostle of everything on the web, has been spreading the gospel of Open Rasta for months. Tonight I decided that finally, I should download and give this fantastical framework a shot.
For an explanation on what OpenRasta is and is not, I shall direct you to their sites:
I am a person that likes to learn by trying so I immediately jumped to the ‘creating your first OpenRasta website’ (here). I have looked at some of Ryan’s code and have survived several conversations with Ryan over the framework. ;) I believe that is enough preparation for at least a simple tutorial.
Well I go to the modifying the web.config section and was left with a broken solution. Apparently from the time the tutorial was written and the time I downloaded the version 2.0.2039.312, the handlers and modules all moved to another assembly. I had a gut feeling it moved and when I talked to Ryan, he confirmed my suspicions. Supposedly he is going to try and update the tutorial.
In the meantime, just change ….”OpenRasta.Web.OpenRastaHandler, OpenRasta”
So change the assembly reference from the OpenRasta.dll to the OpenRasta.Hosting.AspNet.dll
I assume if you are reading this you have the skill set to modify said correction for the other references.
After that I breezed through the creation of the ‘Home’ resource and the ‘Home’ handler. No duh? Any programmer can make a couple of classes. :)
I’m at the configuration section and I have to say, I love the fluent interface. Anyone who has talked to me in the past 6 months knows I love the pattern. It instantly makes any framework extremely approachable.
The tutorial has you making a manual configuration. I tried to find an auto configuration just using some intellisense with no luck. I will investigate this further. If I was going to use OpenRasta I would definitely want a convention based solution. Even with a nice fluent interface, I really don’t want to manually create all my mappings by hand.
But there is something to be said for simply creating a mapping like :
1234
ResourceSpace.Has
.ResourcesOfType<Home>()
.AtUri("/home")
.HandledBy<HomeHandler>();
I ran the app expecting the 405 method error as the tutorial predicts.. and got an empty page. I was using FireFox, so I jumped over to IE and was then greeted by the 405 error. I assume FireFox is either handling the problem gracefully or I don’t have some settings setup to display these errors. /shrug
So then I created my ‘Get’ method on my HomeHandler. One of the things that did attract me to OpenRasta was the POCO handlers. I’ve grown to appreciate very clean code with some acceptable conventions. Just makes life easier. I can focus on the domain problem and not the intricacies of any given framework.
Most of this seemingly new re-invention of HTTP as ESB, REST, Atom.. etc is interesting in that its a reexamining of a technology we use all the time. I haven’t done web development in roughly 3 years. The majority of my experience is in smart client apps. That is just the way my career and projects played out for me. The websites I created were always very basic and probably crap if judged by web developer gurus.
Anyway.
We click links and magically we get a web page. We don’t really think much about it. Sort of like turning on a light switch or starting your car. We just expect things to work and don’t really worry about it. How many drivers can actually explain a combustion engine?
There is a lot going on in the background to make the web work. This new (new to me at least) area of development is leveraging the tech the way it was supposed to be used (if I am to believe the pioneers in this arena). A lot of this is a change of perspective. And with any change of perspective it can take awhile to make the transition.
After that side trip down my ramblings, we come back to me having a handler with a Get method. Now I have graduated to a 406 error (as expected by the tutorial).
I then created my view as the tutorial suggested. Now upon trying to fluently configure.. I ran into a snag. Again the tutorial is out dated (which is fine for an open source and still growing framework).
I had to add the “OpenRasta.Codecs.WebForms.dll” to the solution.
Also the fluent configuration suggested is…
1234
ResourceSpace.Has.ResourcesOfType<Home>()
.AtUri("/home")
.HandledBy<HomeHandler>()
.AndRendededByAspx("~/Views/HomeView.aspx");
But since the AndRendededByAspx is obselete, the code should now be:
1234
ResourceSpace.Has.ResourcesOfType<Home>()
.AtUri("/home")
.HandledBy<HomeHandler>()
.RenderedByAspx("~/Views/HomeView.aspx");
I then continued the tutorial until I had my Home View that displayed my lovely welcome message.
Yay! I got my first Open Rasta page to work. :)
Feel free to investigate my project at my Git Hub repository: