Mike Nichols - Son of Nun Technology

January 2007 Entries

Why Dad Should Never Have Let Me Play In The Garage

A personal WTF that makes me chuckle (now)...
I've been finally learning how to utilize NAnt to automate all the stuff that has to go on.
Still, it's a bit like giving  a chainsaw to a 1-year old...
So found myself run this snippet in one of my targets:
<delete dir=${root.dir} />

Eh...what I meant to say was
<delete dir=${build.root.dir} />

Subversion saved my buttocks tho :)

Review: Apex SQLDiff

I am learning about dealing with migrating database changes within a test environment and need some good tools to help me. Earlier I had looked at SQL Delta and was somewhat impressed. It got some data synchronized pretty easy and the price is good.

However, I may have been missing something but dependencies weren't detected very well in the table structure so I looked around some more. I found a tool by Apex called SQLDiff which is a bit more money but the interface is far easier to work with and manages the dependencies in the db for me. Overall, I simply didn't have to think alot and if I wasn't intimately acquainted with the table structure I'd still be able to perform actions on my db with this tool.

The UI is very easy to navigate around and I found things like editing and creating projects to be a breeze. I am new to these things so that is a big plus in my book. Since this provides both data comparison and schema comparison, i think the prices is right.

Check em out at http://www.apexsql.com/.

 

MIKE

MicroRant

<rant>

Few things drive me more crazy than going onto a forum of an open-source product and seeing some user complaining about something that they don't understand. It's one thing to be frustrated but don't treat the OSS developers as if they work for you.
Documentation is the big gripe against OSS and sometimes I can understand, but if you have the source code AND IT IS FREE ... wouldn't you choose to investigate the code and not only answer your question but learn some stuff at the same time?
The OSS I use is developed by folks who are spending lots of energy on their software and I really appreciate their sharing.
If that doesn't work for you, perhaps you should buy an equivalent commercial product.

</rant>

Five

Alrighty...so I got tagged by JP Boodhoo so here's my 5 things you probably don't (want to) know about me :)

1. I have my master's in music on percussion and played professionally up until about 6 years ago (I'm 36). From age 16 I was playing jazz gigs in DC up until I toured for a couple of years, played tons of stuff locally, a fair amount of studio stuff and taught at James Madison University (in Virginia) and Arizona State University. Drumset and concert marimba are my specialty, though I started and continue on piano.

2. Jesus gave me my wife Natasha, a lovely study in humility raised in Brasil (though she is American) and we got to fly 300 miles into the heart of the Amazon in North Brasil to see where she grew up about 3 years ago. Since then, we have had two amazing children, Chaya Faye and Joshua Avidor.

3. I'm green at development (you've noticed :) ) and have been thankful to have discovered so many gracious developers who share their wisdom via this medium. I never had school for development stuff and really don't have many (I can think of one) local folks to share or work with or mentor me (I'd like to change that this year)...but I have discovered the mindset akin to music arrangement and composition.

4. I live in Phoenix, Arizona and love this state since we go backpacking/hiking/camping as much as possible with two children. Before kids my wife and I were avid hikers and I have hiked every trail in the Western Superstition Mountains and have been stuck in sand in my truck in some of the loneliest places in the country.

5. I have another blog for our family set up at http://blogs.chayachronicles.com/nichols (shameless plug) where we log current happenings with our family and especially things I am being taught in the Bible.

Okey doke...so it seems like tagging has made its rounds...so I want to pass it on to Bill PierceBilly McCaffertyFredrik Gheysels, and Martin Fowler (that last one was a joke...wouldn't it be funny if he read my blog though????!)

One last thing...has anyone thought of how we can play 'kick the can' over the internet?

Ok...you can wake up now

MIKE

Messages From Domain Layer Up To Presentation Layer - Notification Patterns and Exceptions

One of the frustrating things with Domain Driven Design principles (for me) is some of the unanswered questions and lack of good .NET examples implementing solutions to real-world problems. A few days ago I posted a proposition that (kind of) attempts to propose a way of dealing with all the little messages we want to send up the pipeline but without throwing exceptions all over the place. I really wanted to keep from including every call to my Service layer from my Presentation layer in a try...catch block. I realize that it is common to do this when crossing boundaries but I wanted to have a consistent way of dealing with all the messages. More on that later. First, some elementary foundational stuff...At first it might seem like I am reinventing wheels, but hopefully after I am completely done it will make sense.

On one hand, we are told exceptions  are expensive and should not be used for program flow purposes, but on the other hand the fact remains that you only get to return one result from a method (out and ref notwithstanding). Now, some think events such as bad data being passed from the user is a reason to throw an exception, but I just don't think that is exceptional...that is something I EXPECTED. Hmmm...are we getting our "cepts" crossed with our "pects" ? :)

DDD has lots to say about how to create a rich domain but very little in regard to how this works in relation to all the other application stuff like infrastructure or presentation. We are told to protect the Domain Layer at all costs, but then I find myself dying on the hill of complexity to do so. Sending messages from the Domain layer up to the presentation is one of these I think. So over the next few posts I am implementing how I am solving this problem in my project, ending up wiht the final Notifier implementation I blogged about a couple of weeks ago and has since evolved into something I really like.

First, let's give ourselves some flexibility. As I see it an exception is something you didn't see coming or perhaps something that is unusual in an application and should interrupt application flow. In some ways, though, an exception is just a message and can be used like a Notification pattern. So to get some consistency, I implemented an INotification interface: 

    public interface INotification

    {

        IList<INotificationItem> Items { get;}

        bool HasItems { get;}

        bool HasErrors { get;}

        void AddItem(INotificationItem item);

        void Clear();

        IEnumerable<INotificationItem> GetBySeverity(params NotificationSeverity[] severity);

 

    }

The INotificationItem this INotification contains are this:

    public interface INotificationItem

    {

        string Message { get;}

        NotificationSeverity Severity { get;}

 

    }

Now, I'll create an application exception to be used across my app :

    [Serializable]

    public class AppException : ApplicationException, INotificationItem,INotification

    {

        private int _errorCode;

        private NotificationSeverity _severity;

        private string _message;

 

        private INotification _innerNotification= new Notification();

Notice I am implementing both the INotification and INotificationItem interfaces on this. I realize Exception has InnerException for doing this same thing but I wanted to give some more information about the exceptions including error codes.  This gives me some flexibility to have nested Items as things go up the pipe to the Presentation layer. All of these sit in an assembly such as a Common library that is visible to my Domain, Services, Presentation, and Web assemblies.

Let's assume that I have a Service layer which is actually consuming my Domain Entities.

public class DomainService

{

    public void AddPhoneToContact()

    {

        try

        {

            Contact c = PersonFactory.GetPerson("Mike", "", "Nichols", Gender.MALE);

            c.AddPhone(555, "5551212", "", "Home");

        }

        catch(AppException ex)

        {

            //Do something with the INotification implementation...stay tuned

        }

    }

}

Ok...so now I can throw exceptions in my Domain entity if something is wrong. Big deal, right? Well, that is the foundation...What is important here is that I have a consistent contract (INotification and INotificationItem) to work with...I could even inject a Strategy into my Service to determine whether to rethrow the exceptions or do whatever I want with them. Of course, you could do that with the standard exceptions too right? In my next few posts I'll show how we'll create a consistent way of handling these events in the application and ultimately help us consistently notify the user and (perhaps) logging or other listeners about these things that happened in our Domain.

NHibernate ISession Playing Friendly with ASP.NET Session (Or Some Other Kind of Cache)

I had a pretty typical situation where you'd store an object in a cache like ASP.NET Session to work with it until it comes time to save the data to the database. Poking around the forums I found a post and also some other blogs that stated that you can call SaveOrUpdate to reattach an entity to the current NHibernate ISession. I kept getting a NonUniqueObjectException though which is just saying that the entity has already been loaded into the current NHibernate Session and cannot be Saved. Here's the flow and how NHibernate works with it:

1. Load Object from database and store into ASP.NET to work with the object.

2. So some real exciting stuff in the web page to manipulate data in store object.

3. Time to persist the object to the database, so let's reattach the object to the current NHibernate ISession using SaveOrUpdate

4. FAILS and throw NonUniqueObjectException for an entity that is a CHILD of my object...

Now at this point I was wondering if perhaps the calls weren't traversing my object graph (into my child objects). Looking thru the StackTrace it turns out a call to DoUpdateMutable in SessionImpl is checking for uniqueness AFTER it has already saved the entity which of course would fail (Updating the object reattaches the entity to the ISession).

But when I looked at the explicit Update() call, it looked like it might work. BLAM! No problems and the object was reattached and saved just like it should be. SUCCESS! Incidentally, a call to Lock() would have worked too but there might be problems with this...here are some rules I discovered while researching this:

1. A call to Lock() will lose your changes on an Intransient Instance (one that was in the DB at some point).  Reserve Lock(Object, LockMode.NONE) for attaching INtransient (new) instances to the current ISession. This is rare. If you choose to use Lock() be sure to make all changes to your entity AFTER the Lock() call or else you'll lose them during persistence.

2. NHibernate WILL traverse your object graph for Lock() and Evict() if you set your cascade to 'all' or 'all-delete-orphan'. So if you need to pull the entity out it shoudl be fine for the child objects if use these cascade strategies...otherwise any associations to your target entity will need to be explicitly Evict()ed or Lock()ed.

It would be nice if there was an explicit Reattach() call in the ISession interface but it works.

This failure to reattach by SaveOrUpdate may be a bug...I'll repost if I hear anything in the forum.

Web Application Project Funniness

Interesting...my web app wouldn't build and was griping about my .designer.cs file beneath a Master PAge. Everything looked fine and should work. I had run ReSharper optimize usings command and it optimized...but the page wanted the fully qualified name on the field (control) entry...strange that it would require that. Oh well.
[UPDATE]: using the optimize usings command in Resharper on the WebPages screws everything up for me...note to self: DON'T DO THAT.

Converting To Generic Type Parameters From GetType

I have come across this before and wonder if anyone else has a slick way to handle my dilemma.

While playing with the Enterprise Library Validation Block, they ONLY provide static methods to receive an IValidator through methods that force a generic parameter:

protected IValidator<T> _validator  =ValidationFactory.CreateValidator<T>();

A nongeneric IValidator is also provided which would be great to have in my layer superclass without me having to pass generic parameters into the superclass everytime...but they don't let you pass the Type into the validation factory so it could look like this:

protected IValidator _validator  =ValidationFactory.CreateValidator(myType);

Looking at the code, it doesn't require this strongtyping (they cast it to typeof(T) in the methods)...so this appears to be a incomplete API.

How would you get around this?

Growing Pains In OR/M - Part 3

I've been trying to log some things I had to overcome in learning how to leverage an Object-Relational Mapper (OR/M) for my applications' data access. In my first post I discussed the philosophical leap from Data Centric to Object-Centric application development. I realize this is not a constraint imposed by all OR/M tools but when applying my favorite, NHIbernate, it really leans you toward Object-Centric application development. There are some OR/M tools developed by folks who have a more datacentric view of software development and believe that the table schema dictates your domain model. I don't follow that school but that discussion is beyond this little series' scope.

In my second post I discussed the hurdle of how an OR/M tool deals with Inheritance. Since inheritance is an object-oriented decision and has no relational (read: Database schema) equivalent, we are forced to deal with the impedance mismatch between object- and relational- thinking.

In this part, I'd like to discuss ways to USE an OR/M and how an OR/M fits into the overall architecture of an application. This kind of thing tends to creep outside of OR/M specifics into broader architectural considerations and I will try to narrow my view, but one thing should become obvious when deciding to leverage an OR/M for data access in an application...IT IS VERY IMPORTANT AND ITS ARM OF INFLUENCE IN AN APPLICATION IS SWEEPING.

WHAT HAPPENED TO MY DATA ACCESS LAYER (DAL)?

If you have been slurping off of Microsoft's nipple of architectural guidance you will no doubt have become drunk with their 'n-tier' or '3-tier' suggestions, the majority consisting of a picture that has these little boxes and circles with pretty colors like these:

Next the tutorials will go on to teach you how to write lots of ADO.NET Database Access code and then return a DataSet either directly to your 'code-behind' pages (in ASP.NET tutorials) or even get a little wild and have you do some bizarre functions like validation within your mysterious 'Business Logic Layer' (BLL). Since a dataset isn't actually the object it represents were are then encourage to write a number of static helper methods to perform operations upon the DataSet to scrub the data before it appears into the (now bloated) Presentation layer.

What was confusing to me about all of this was the idea that this was somehow 'object-oriented' development, but then I found myself writing the same data access code over and over or having to make changes all over the place whenver something like a field definition or rule changed. I thought OOP (Object-Oriented Principles) were supposed to take away all of this duplication of effort? I find myself slipping into the infamous 'DataSets vs. POCO' argument that I think has been better elaborated upon by better developers than me. Read this Hanselman post for a good (and fun) detail of the problem with using DataSets as Domain Entities.

One nice thing about the ADO.NET way of doing things was it was pretty cut and dry...you have to hand-code all the data access code to hydrate your domain objects and also to persist changes to your database when you need to. Since you wrote all this stuff, or maybe went a little crazy and used the Data Access Application Block (DAAB) to help you, you know exaclty how data gets into and out of your classes. As an aside,I won't even get into Unit of Work or other things we need to consider to avoid muddying the water.

But now you decided to use this library (dll) that is supposed to do most of this stuff for you (CRUD functions and so on). Sounds great and my tendonitis just got a little easier to bear with, but now how do I get the data into my objects or save them to the database when I'm all done?

One thing you must remember is that the library you have decided to use (NHibernate.dll for example) is your DAL. When you need to load an object from a database, instead of opening a connection and writing all the mapping code to squirt into your object's properties you now have permission to do this: 

private object myObject = Session.Get(myObjectId);

Huh? That's it? Yes. That's all.

But it now becomes obvious that these kinds of operations (Get, Save, Update, etc) can now be splattered all over my application and that I have simultaneously become 'married' to an external library (in this case, NHibernate.dll). I'll elaborate on the first point in a moment, but regarding the 'marriage' to an external tool like NHIbernate a few things I will say and elaborate upon in a future post. There is a disease calledl 'Not Invented Here'  syndrome which stalks developers (especially .NET developers) and which at first seems like a wise condition to be predisposed to, but in the end can drain the life out of a project's momentum. Realize that this disease is a leading cause of Death By Future-Proofing and that we code not only against an API's specific objects (such as the 'ISession' interface in NHibernate) but also philosophically against a tool's (whether homegrown or not) way of operating. What I mean is that code changes will be required anyways even if we built an elaborate way of protecting ourselves from the very tool we choose to implement. But more on all that later on.

It is true that the manner of calling the various CRUD operations on an OR/M will potentially be divers in an application and could possibly undermine a large benefit of having and OR/M (besides no more ADO.NET code writing)...code reuse. This is where Design Patterns step in to help us establish a consistent and robust way to employ our OR/M. The Domain Driven Design (DDD) camp has given us a pattern called a Repository pattern . I am no DDD expert (you may have noticed) but I believe strictly speaking you'd incorporate a Repository only for your Aggregates in your Domain providing functions like Get(), Save(), Update() and PersistAll(). This smells alot like the Data Access Object (DAO) and in fact you'll find folks intermingling the terms. There is plenty of discussion of this on the forum for domaindrivendesign.org.  The only difference I can find is that a Repository is more strictly ONLY applied to 'Aggregate roots', or those objects within a domain that establish a logical boundary, while a DAO may be freely used for any object in the Domain. The semantics of this aren't important here, but rather the simple fact that a single, reusable object is used to employ the OR/M to access the Database.

Oren's blog at www.ayende.com is a great resource for an implementation of the IRepository<T> object and Billy McCafferty wrote an article on using NHibernate using a DaoFactory. What is important to note is that this object (whether you call it Repository or DAO) hides the internals of dealing with NHibernate (especially with getting the current ISession ) and exposes very simple, but rich, methods needed by your Domain to perform persistence operations. But as I mentioned before, unless you really have a requirement that forces you to have your entire application tool-agnostic, resist the temptation to build an elaborate API that hides your tool's rich resources (such as the ICriteria implementations or HQL in NHibernate and so on).

Where you place this object in your application's project structure is largely personal. I don't want any objects in my Presentation layer to perform data operations (such as a call to Repository<T>.Save(object)) and instead have the Presenters always fetch/save from some kind of Service layer,  so it might make sense to place this interface in an assembly that isn't referenced by the Presentation project.  I have found it easier, though, to simply place this Repository/DAO in my assembly that provides common functions throughout the entire application.

How you retrieve this IRepository/IDao is an important conversation, but one that will be pushed off to a future post I'm afraid. Inversion of Control, Dependency Injection...I just don't have the energy to go into it right now :).

Hopefully, you'll see that your 'DAL' while employing your OR/M has become split across your application. No longer is it found in one assembly but has its low-level details zipped up in your ORM tool's assembly, while you provide the higher-level code to utilize it. How you do this is up to you, but the driving forces are code-reuse (you shouldn't have to write a Repository for every object in your Domain) and richness (you should be able to easily extend the Repository and leverage the rich API your OR/M tool provides such as querying or caching). The beauty is that you are spending time on DOMAIN concerns and not on mundane data access code...