I almost feel bad about a comment I left on Rober McLaw's blog reads as 3rd-party spam. There is so much being said about ObjectSpaces being delayed that I won't bother linking to any other specific posts because in order to be fair, I would have to link to way too many blogs. Every developer seems to have an opinion on this issue and I am no exception. My opinion? "Cool". Why? Because of LLBLGen Pro. My comment on Robert's blog:
I don't think LLBLGen Pro could be much more intuitive and easy to
use out of the box without the user losing too much control. From the
documentation to the code generation GUI to the easily understood (and
remembered) class names in both the generated code and in the SD.LLBLGen.Pro
namespace to the actual usage of the generated classes, I think Frans has hit
the "sweet spot" between power, ease, and extensibility.
LLBLGen Pro has a very short learning curve, allowing you to almost immediately start using classes generated from your database. Literally within minutes of installing the product (assuming your database is already created), you can use the generated entity and collection classes with a few lines of code and "the power of the dot". A very simplistic example would be binding a datagrid to a collection of orders a user has placed. The code would something like this:
private void BindUserOrderGrid(int UserID)
{
UserEntity user = new UserEntity(UserID);
DataGrid1.DataSource = user.Order;
DataGrid1.DataBind();
}
This example is simplified only in that you may not want to do it that simply. If you want to make it that easy, you can. That is why everyone wants ObjectSpaces so badly, because data access like this makes development so much easier. The trade-off for power is control, though. Frans has made sure that you maintain control by allowing (recommending, actually) you to extend the generated code to build your validation into the classes. You can either edit the generated code directly or build classes that use the generated code (depending on the complexity of your project and whether or not you will be re-generating the code after making database changes). You can also edit the code templates and extend LLBLGen Pro much further than I plan to.
The main arguments people have for not using O/R mappers and code generators are the same arguments that I had: "NIH (Not Invented Here)", "but when I change the database, I'll have to regenerate the code", and "I don't like the archetecture/generated code". The first issue, NIH, only holds up if you don't mind reinventing the wheel every time you want to drive to the store or if you plan to set aside the time to really do the job correctly (like many have: Frans, Paul Wilson, Thomas Tomiczek, Gavin Joyce and countless others have written tools that have saved them (and others) time and energy, but sometimes it is better to allow their work make our work easier. "Standing on the shoulders of giants", to so speak. I also think that "NIH" and "I write all my own code, thank you" are bs in light of the fact that ASP.NET, VS.NET, and the .NET framework itself are code generators. How could I say I won't use a code generator on principle and then let the .NET framework pump out html and postback JavaScript for me?
The second issue seemed like a problem until I actually thought about it for a moment. If I use a code generator that generates code based on my database and then make changes to my database, I'll have to regnerate the code. That sounds like a PITA. But then I realized that if I hand-coded all of my data access code and made changes to the database, I would still have to change all of the data access code, except I would have to do it by hand. I think somewhat highly of myself but I don't think for a second that I can refactor that code by hand more accurately than a code generator can. I'm not saying that I can't write the code better than a program can, I'm saying that "find and replace" isn't a technique that compares with regenerating the code. If you write classes that derive from or use the generated classes, then regenerating the code will be mostly painless. LLBLGen Pro will generated the code in a "Two Class Scenario": In my lame example above, I am using a theoretical generated UserEntity class. This class is the one that you would alter and extend as needed. The other generated class would be a UserEntityBase class. LLBLGen Pro will regenerate the base classes only, if you want, so that your altered code in the Entity class would not be overwritten. It would be nice if no database changes were made and this issue would never arise, but that isn't a reality that I can count on. LLBLGen Pro makes the process as painless as possible. To be completely safe, you shouldn't alter the generated code at all, of course. So... my main fear was quickly disolved when I realized that regenerating the code after a database change was going to be much easier than doing it by hand. But that leaves the showstopper:
If an O/R mapper or code generator doesn't produce code that you can live with, it isn't good enough. It doesn't matter if Bill Gates wrote the code by hand on a napkin for you at TechEd, if it doesn't fit into your project in a way that you can be satisifed with, you will have to get rid of it. Code Generators like CodeSmith allow you to have complete control over the code. This slides the "control:ease" slider too far to the "control" side for me personally. If you slide the slider too far to the "ease" side, you end up locked in to someone else's idea of how your code should work. I don't know where ObjectSpaces would go on my "control:ease" sliding scale, but LLBLGen Pro hits the sweet spot. I can change the code I don't like but I don't have to in order to make it work and, luckily, I agree with the basic premise of the generated code. If I looked at it and hated it or thought "wtf is he thinking!?" then I would ditch LLBLGen Pro and continue looking for a tool that fit my needs. Some people will say that, I am sure. Some people might not even look at the code (let's face it, some people don't wanna know) and they really don't have to but that isn't something I would recommend. LLBLGen Pro produces validator classes for a reason. use them. So... the code meets my lofty standards and works along the same lines as what I would have written myself by hand (in many more hours), but the one thing that bothered me was that it doesn't base all database interaction on stored procedures. This is okay and acceptable because I was going to have to use raw SQL for some of the complex sorting and filtering queries. I know I can do this inside a stored procedure but I really don't like that method. LLBLGen Pro doesn't stop you from doing that or using procs in your usual method. Retrieval procedures produce DataTables in a single line of code which is pretty nice, even if I don't use that functionality very often.
My reasons for not wanting to use a code generator or O/R mapper were quickly shot down once I started playing with CodeSmith and LLBLGen. Once I knew I wanted one, I tried a few more to see how they compared and which was best for me. LLBLGen Pro won out because of the quality and extensibility of the code, the low price (not free but more than fair), and the ease of use. The demo only works with Northwind but Northwind isn't a bad example. I was able to see how the code would work for 1:m, m:n, and other relations and how that would fit into my method of coding. The documentation is incredible. It explains the theory, the technology and the process in a way that few developer's documentation even attempts.
Besides the Entity classes, Collection classes, and stored procedure calls, you can also create Typed Views based on views in your database, Typed Lists that are similar to views but exist only in your code, not in the database (not a great explanation, but this is getting long and I am getting lazy). I use Typed Lists when I need data from a few related tables but not every field from those tables.
I am a bit relieved that ObjectSpaces is delayed, honestly. I means I may not have to replace LLBLGen Pro as my O/R mapper as soon as expected (assuming Frans will be porting this to .NET 2.0). There are many similar products that you should try if you aren't currently using any code gen or O/R mapping tools, I highly recommend LLBLGen Pro. Now that ObjectSpaces is delayed, you should stop waiting if you have been.
Other tools that bring some of the promised Whidbey functionality to .NET 1.1: Steve Sharrock's ASP+FTP (ASP.NET Deployment with FTP), Paul Wilson's improved version of Master Pages, and Rob Howard's articles on the provider model design pattern.