I just started using the Policy Injection Application Block from Microsoft’s Enterprise library. At first, I thought it was worthless and overly complex. I was wrong. It is a very powerful programming tool that allows me to develop a lot faster and cleaner.
Policy Injection is similar to aspect-oriented programming in that it helps to break away cross-cutting concerns (authorization, logging) from the actual business logic. And yes, I basically copied that from the documentation.
Here is what policy injection means for me. I can build business logic, which performs only what I want it to. So I can have a function called AddUser and all that is done is the actual operation of adding that user. I can then attach policies to that function, which specify how to authorize and log it. This has a couple effects. One, it reduces the amount of code which in turn cleans up the code. Second, it allows me to customize cross-cutting concerns for different projects. If I have an administrative application, I need to authorize differently than a user application. Policy injection makes this possible without dirtying up the code.
After the initial few hours of getting used to using it, I am a huge proponent. I definitely recommend checking it out.
As most of you know, the data access layer is my favorite application layer to work with. For a while, I worked on my own active record implementation in PHP. After switching to .NET, my outlook has strayed away from the active record pattern though. I like using business entity objects that have no coupling to a database. Instead, I use an object/relational mapper to translate from business entity to persisted database object.
At first, I started working on my own implementation again, which provided a simple, in code, mapping technique. I quickly realized that mapping business entity relationships wasn’t easy though. After a couple hours of staring at my monitor hoping I could come up with an elegant solution, I decided to look at some 3rd party mappers. I had heard about NHibernate before and decided to give it a shot.
I spent about two days prototyping part of my database in NHibernate and my first impression is wow. Everything I could think of adding in an o/r mapper exists in NHibernate. Lazy loading, relationships, inheritance, component mapping, and so much more is possible. Over the past few weeks, my entire data access layer has been converted to NHibernate with overwhelming success. Like any library, it has its own quarks, but for the most part it speeds up development time while adding lots of power to my applications. I would recommend it to anyone.
NHibernate uses XML documents or .NET attributes to map an entity class to a database. I never thought I would use XML again after painful VB6 experiences, but I decided to give it another shot. To my surprise, I loved it. It allows for really clean separation of the database and code, which basically means cleaner code and a happier Brian. The only really annoying part of NHibernate is session management, but I’ll save that for part 2.
I recently started a new project here at Webmail.us which will be a .NET based web application. One of the core pieces of .NET web apps is, not surprisingly, ADO.NET. It is Microsoft’s upgrade from ADO, but it is more of a rewrite. Almost everything has been refactored, with many new abstractions and paradigms for how to access data. When I first read about ADO.NET, I was very skeptical. I didn’t understand the need for these complex, hard to understand abstractions like DataTable’s and DataRelation’s and DataSet’s. It all seemed foreign to me for a multitude of reasons. Unfortunately, Microsoft seems to be pushing DataSet’s so loudly, its hard to see what else is out there.
After a few days of digging though, I found a few great articles (Choosing Data Containers for .NET, On the Way to Mastering ASP.NET: Introducing Custom Entity Classes) on why not to use DataSets, as well as why you should. DataSets were designed for rapid application development, and seems to be Microsoft’s answer to the Rails ActiveRecord pattern. It is a quick and dirty way to build the data access layer for web applications. To be more specific, by quick I mean it allows version 1.0 of a product to be released quickly, because a data abstraction already exists. By dirty, I mean it isn’t an abstraction created for your application, it is a data abstraction created for any application.
Pro’s of ADO.net
- Fast development time
- In place architecture.
Developing custom data access solutions can be very powerful, and very risky. A bad design can lead to bad performance and is inherently error prone
- Feature rich
- Disconnected data
- Concurrency
- Many more…
- Easily serializable
Con’s of DataSets
- Large memory footprint
- Not object oriented.
DataSet’s represent relation data, just like a database. But I don’t want an in-memory representation of the Employee table, I want Employee objects. Scott Hanselman sums it up pretty nicely:
A DataSet is an object, right? But it’s not a Domain Object, it’s not an “Apple” or “Orange” - it’s an object of type “DataSet.” A DataSet is a bowl (one that knows about the backing Data Store). A DataSet is an object that knows how to HOLD Rows and Columns. It’s an object that knows a LOT about the Database. But I don’t want to return bowls. I want to return Domain Objects, like “Apples.”
- Not abstracted.
Directly connected with database data and structure. So, any change to the database schema, could trickle down to the presentation layer.
Conclusion
ADO.NET is a huge improvement from old ADO, but don’t buy into the entire framework. Microsoft is trying to push DataSets but they might not always be the best solution. For enterprise applications, I don’t think DataSet’s are the answer. On the other hand, for smaller web application, it might be a perfect fit.
A while back, I posted a review of some existing Active Record implementations. One of those happened to be the Zend frameworks DB portion. I believe that was about the time of version 0.7, and I recently looked on their website and discovered 1.0 had been released.
I initially had low expectations, expecting 1.0 to just clean up 0.7 code, with minimal feature additions. After I downloaded it, I found out how wrong I was. The 1.0 release fixed every negative comment I had about 0.7. Although it’s not perfect, it’s a lot better than it used to be.
The Good..
- Variables for defining which row and rowset classes to use in Zend_Db_Table. This enables custom row and rowset classes which I believe is a must-have.
- Support for compound primary keys
- Ability to cache the table meta data and prevent unnecessary database access
The Bad…
- Application level support for foreign keys, namely cascading deletes. This feature is awesome since a lot of the tables I work with are myisam and don’t support cascading deletes. Too bad it doesn’t truly cascade. If you delete a single record, it will cascade that delete to all related tables, but no cascading after that. Basically, a worthless feature that causes more confusion than it helps. Just use MySQL’s Innodb storage engine and clean up the code
- Complexity. Lots of classes and lots going on.
It has been a while since I have written about, or coded, my Active Record implementation. Basically, I have had too many other things to work on to enhance the functionality of an already working, albeit very beta, design. But, that doesn’t mean I haven’t been thinking of all the features I want to add to it.
For many applications, the date created and date modified information for data is very useful, but annoying to set. Since Active Record abstracts all access to a database, these fields can be set easily and transparently. Many other implementations of the Active Record object already support this, so its not a new feature, but definitely a needed feature. The main issue is what timezone the server is in since NOW() doesn’t return GMT. It’s obvious that GMT is the preferred storage format of this data, so maybe passing a GMT date string from GMT is best.
Another feature that I just thought of is soft deletes. Basically a soft delete is where the data isn’t actually deleted, but a flag is set to show that it is deleted. This is very useful if you need to keep old data around for restores, or if you just want to have a record of everything. One of our new hires MikeT brought it up to me since his project has a soft delete requirement.
Hopefully I can get these added into my implementation fairly quickly since they are so simple. Even though features like this are just the tip of the iceberg, they are crucial for creating a viable Active Record design.