Monday, July 11, 2011

NHibernate cascading styles + ConfOrm = Iguazu Falls!

Alright! So let's get down and dirty with my first "real" blog post, shall we?

For those who don't know about ConfOrm, let me say that he is the smartest guy in town when mapping domain entities is all about (besides Fabio Maulo, of course, who is responsible for it as well as being NHibernate's project leader :-) ).

you can read all about it here:

http://fabiomaulo.blogspot.com/search/label/ConfORM

If there is an ideology hidden in this post, that would be to prove yet again that you can use ConfOrm to "auto-map" almost any mapping scenario you can think of, no matter how complex your scenario is.

I have this domain that has lots and lots and lots of entities that map to a single one. Even this entity maps to itself.

Most of the associations are the same: many-to-one. But as well this domain makes use of a many-to-many, and a peculiar many-to-any association (more on this domain in the following posts).

Irrespective of the association used, all of them share one thing in common: the association's target entity. And even if you don't know the actual mapping, you can guess that if everything points to a single thing, then that thing sort of defines the rules of the game.

Now, while ConfOrm provides many "patterns" to set cascadings based on the association type of a mapping, it does not provide a way to set cascading styles based on given types, more specifically, the target of the association.

That being said, what ConfOrm DOES provide is a way to define your own patterns, and that is what makes it so useful: you define your conventions (plus all the gems in ConfOrm.Shop) and this guy takes care of the rest! You do have to hand-code the "exceptions" to the rules yourself, but that's what they are, exceptions.

So you get the usual "mapping-by-code" benefits that you get with tools like Fluent NHibernate, and your mapping code reduces a lot. But more important than that is that you can make your domain grow without having to revisit over and over again your mappings.

Ok, I just realised that I wrote too much already and didn't show anything to prove what I'm saying! So here you go:


   1:      /// <summary>
   2:      /// Pattern to create a general cascading rule where the target of the
   3:      /// association is of type T.
   4:      /// </summary>
   5:      /// <typeparam name="TMatch">A type to use as a target match.</typeparam>
   6:      public class DefaultCascadingForTargetPattern<TMatch> :
   7:      IPatternValueGetter<Relation, Cascade?>
   8:      {
   9:   
  10:          private readonly Cascade _cascade;
  11:   
  12:          public DefaultCascadingForTargetPattern(Cascade cascade)
  13:          {
  14:   
  15:              _cascade = cascade;
  16:   
  17:          }
  18:   
  19:          /// <summary>
  20:          /// Determines if the target type of a relation (subject.To) matches the
  21:          /// type TMatch.
  22:          /// </summary>
  23:          public bool Match(Relation subject)
  24:          {
  25:   
  26:              return ReferenceEquals(subject.To, typeof(TMatch));
  27:   
  28:          }
  29:   
  30:          /// <summary>
  31:          /// Returns the cascading style to be used.
  32:          /// </summary>
  33:          public Cascade? Get(Relation subject)
  34:          {
  35:   
  36:              return _cascade;
  37:   
  38:          }
  39:   
  40:      }

And you can use this pattern like this:

var orm = new ObjectRelationalMapper(); 
 
orm.Patterns.Cascades.Add(
new DefaultCascadingForTargetPattern<YourEntityHere>(Cascade.Persist)
);

Simple, huh!

Do let me know what you think!

Hello, World!

Hi out there, wherever you might be.

I'm a man of many words... But only when I speak.

For a long time I considered the idea of starting a blog about coding, but given the previous statement, I held that idea back. That is until today.

If you see this, you will realise that I just needed a push, since a single reply to a comment cannot be the sole cause of taking the time and effort of doing this, can it? Let us hope for the sake of this blog update rate that it is not.

That being said, do not expect to find here long essays explaining the meaning of life using programming patterns, but rather some small snippets and random thoughts that help me get there, or at least make it through the day.

So with no other further delays, let me introduce myself.

My name is Nicolas, I was born and raised in Buenos Aires, Argentina. I'm a programmer who studied philosophy (yes, philosophy, and I dropped out) and even hid my keyboard for almost 4 years while I worked as a cabin crew for an airline company.

I hope my introduction serves as a warning for you to keep in mind, for I may have some ideas that, well... They might seem a bit odd, to say the least. Besides, remember that this statement could produce a false value.


bool programmer = (latinAmerican == exPhilosophyStudent == exCabinCrew == canDoAnyCode);


But hey! This is just a blog! It is not the Bible, nor Karl Marx's or Agile's manifesto. So I hope you just relax, enjoy and maybe find my writing to be useful to you some day from now.

I'll be back in a few...