Ayende @ Rahien

Unnatural acts on source code

How NHibernate forced me to OO design

At some point of my code, I had this method.

image

Remember, this is spike code, so I didn't care for breaking things like encapsulation or getting ugly code. In essence, the code above is breaking encapsulation and stomps all over DRY and Liskov substitution principle.

It worked for a while, then it stopped. The reason that it stopped is that I started passing it lazy instances. And a lazy instance is a proxy, which is neither an ImageItem or HtmlItem. So now ContentItem has the following:

image

As an aside, notice the RecordApperances method. That is the absolute top of Ask, don't tell.

Comments

Victor Kornov
11/12/2008 06:48 PM by
Victor Kornov

Heh, that should read "Tell, don't ask" :)

I wonder, what DisplayInformation looks like. Do you use it like:

if(info.IsImage) {

...

} else {

...

}

atx
11/21/2008 03:50 PM by
atx

I have a similar problem with base classes and proxies, but mine also involves sublassing with discriminators.

The setup is following:

  • base class A, has Lazy=true, subclasses A1, A2 & A3 (table-per-class pattern - one table with columns for all class tree), discriminator field named e.g. "ASubClass"

  • class B has some property of type A (e.g. "myA")

Now, I am trying to do the following:

B myB = B.FindOne(.....);

A myA = B.myA;

if (myA.ASubClass == "1") //1 is discriminator value in subclass A1

{

//discriminator says it is an A1!

A1 myA1 = (A1)myA;  //Error!

}

Now, the line marked as Error, yields an "cannot cast NhibernateProxy to A1" exception - similarly to what you wrote in this post, the actual "myA" is an NHibernateProxy subclassing class A. However, it should rather be an proxy subclass of A1... Frankly speaking, I don't know how to go around this... How to cast the lazy initialized object to its subclass? I do not fully understand the solution that you gave here, Ayende :(

Comments have been closed on this topic.