Among my many shortcomings is this: I am old and learned to program in the procedural days. Worse, I learned to program for the web with PHP 3.0, long before anyone had devised any structure or protocol for how the web should work. Consequently, I am a johnny-come-lately to most of the cool stuff that has been figured out about making websites (and most other kinds of modern software).
In recent years, I have adopted some object-oriented techniques and read a lot. I pretty much understand the modern world. However, as much as I know about the trees, I really cannot very easily see the forest. I can play my recital piece, but it's not great music.
So, I have endeavoured to change that. Even before this .NET experience, I spent several months writing an object-oriented, MVC framework for my personal projects. It's very nice in a lot of ways (I have gone for simplicity and it's good) but, it has not turned me into an OO maven.
C# is changing that. Not only is it a very OO kind of language, but it's also freed me to think OO thoughts from the beginning of the project. It is also serving as a source of examples and giving me the opportunity to really think through a lot of things.
To wit...
Last night I got stuck on something (can't remember what) and, as always, googled it. I came up with a page entitled, "Three Ways to Bind a DropDownList with LINQ and C# ASP.NET".
It starts with the obvious way, natural to .NET. It creates both a display object and a database access object in the .aspx file. The guy explains that this is the equivalent of an MVC view file (I paraphrase very broadly here) and that makes for a nasty confusion of architecture and deeply limits the potential for code-reuse and, for that matter, opportunities for more refined data presentation.
So, he suggests a somewhat better way. He extracts the data access code and puts it into the controller. This is passed (in that annoying, automatic .NET kind of way) to the view file where the display control has been told what fields to extract. He notes that this is better, but if the names of the fields in the database ever change, every page that has this dropdown will have to be revised. It also makes for cumbersome, un-reusable code. He's also unhappy because it uses a database object, not a business object, and that it violates the ideal separation of code functions (those field names in the view are plenty of evidence for this).
Which brings him to his "enterprise" quality answer, which I love and studied and learned immensely from.
What he did, is to make it so that display object only knows what sort of objects it wants to represent. The control basically says, "I am ListNumberOne and I am a drop-down list displaying GoodObjects." When his controller loads the page, it has a line of code that says, in effect, "PopulateList(ListNumberOne)".
PopulateList examines the list object passed to it (reflection is my next major topic) and finds out that it is supposed to display GoodObjects. It asks GoodObjects for a list suitable to be applied to a display object and applies it.
So far, neither of these things knows any more than it needs to. The display object knows what sort of things it wants to show, but nothing about how to get them. The controller only knows that it has to populate ListNumberOne, but nothing about how it's done.
The next part is where he provides the so-called "business object" that will make him happier about how things work. This business object does know 1) how to get the data (from a LINQ object defined in Visual Studio) and 2) what information is needed to populate the display object (provided by a simple class whose only business is to represent an appropriate data type).
Probably it's main coolness is that it does some cool stuff to grab the type of GoodObject so that it can be instantiated and asked for the appropriate data type.
This article uses a tone of esoteric (at least to me) C# constructs and thus provided me a comprehensible context to learn about them:
1) Attributes, ie, code constructs that look like [attributeName]. These are things that add behavior to whatever you put them next to. I'm not entirely clear about the internals, but the basic premise is that you write a class that does something you like, mention it as an attribute adjacent to the class you want that behavior added to, and Voila!, you've got some new behavior. I'm not certain, but I think this may be their way of doing composition in the class definition code. It also seems to offer a whiff of Aspect Oriented Programming. You can added crosscutting behaviors to almost anything. (I first saw, and was unable to understand, attributes when I ran into Postsharp which implements a sort of AOP this way.)
2) Generic classes, eg, Systems.Collections.Generic.List<T>. Turns out that this is the equivalent of a utility library for C#.
3) Specifying types for generics, eg, List<NameValueType> (the "appropriate data type" mentioned above). Turns out that lots of things have generic types and that you can specify what they are supposed to be this way. I have to say, though, that I'm still a little unclear about the benefits of strong typing.
4) That you can have several methods of the same name for a class that are, apparently, distinguished by their parameters, ie, if you pass it one type, it will select the item of that name with that as a specified parameter; pass it a different type and it will choose the other one. Maybe this is why strong typing is good. Not really feeling it yet.
5) The [serializable] attribute. This allows you to pass the object to a variety of serializers (binary, xml, etc) that store objects in serialized form.
6) A practical and believable example of why it's good to have an interface class. In this case, it allows future programmers to be confident that their "lightweight business object" will have the ability to generate the "appropriate data type" for populating drop down lists (and many other things).
Phew!!
And it's only early afternoon.