tags:

views:

76

answers:

4

I have a base class DomainObject for all my business objects I am using with NHibernate. It contains the Id property.

public abstract class DomainObject
{
    public virtual int Id { get; private set; }
}

I would like to write an IEqualityComparer to compare my domain objects. If two objects have the same Id and are the same kind of object they should be equal. However when I use GetType() to get the type of the object, it will return the NHibernate proxy type. So this code:

bool IEqualityComparer.Equals(object x, object y)
{
    // null checking code skipped here
    if(x is DomainObject && y is DomainObject)
    {
            return ((DomainObject) x).Id == ((DomainObject) y).Id
                    && x.GetType() == y.GetType();
    }
    return x.Equals(y);
}

Doesn't work correctly, because the type of x is Asset but the type of y is AssetProxy21879bba3e9e47edbbdc2a546445c657.

So, how do I get the entity type on an object that may be a NHibernate proxy object? i.e. in the example above Asset instead of AssetProxy21879bba3e9e47edbbdc2a546445c657?

A: 

You could change your code to do something like this:

bool IEqualityComparer.Equals(object x, object y)
{
    var a = x as DomainObject;
    var b = y as DomainObject;

    if(a != null && b != null)
    {
            return a.Id == b.Id
                    && a.GetType() == b.GetType();
    }
    return x.Equals(y);
}
Pedro
This code is equivalent to my code and wouldn't work either. As I stated, GetType() returns a proxy type and so the two types are not equal.
Jeff Walker Code Ranger
I'm sorry I should've tested it.
Pedro
+2  A: 

To get real object instead of proxy you can use

session.PersistenceContext.Unproxy(proxyObject)

But I think you should look at Sharp architecture implementation for Equals.

Sly
It should be noted that he's probably more interested in the GetTypeUnproxied() method in http://github.com/codai/Sharp-Architecture/blob/master/src/SharpArch/SharpArch.Core/DomainModel/BaseObject.cs - but +1 for a good reference impl.
DanP
In this case I don't actually have the session available to me in this code. Thanks for the reference to Equals in Sharp architecture, it doesn't apply to me becuase I am writing an equals for tests so it doesn't have to handle all the cases, but it was still a good reference. And thanks Dan to the link to the GetTypeUnproxied() code, that is more what I am interested in.
Jeff Walker Code Ranger
A: 

You can implement a backdoor property as described here to get the actual nonproxied instance.

Diego Mijelshon
A: 

You can get the real type of a proxy with:

NHibernateUtil.GetClass(x);

or you can add a method to DomainObject like:

public virtual Type GetTypeUnproxied()
{
    return GetType();
}

Which is really slick and doesn't depend directly on NHibernate.

Alternatively, one can approach the problem by saying you need to get the true object, rather than the proxy, which, if the session is handy, can be done with:

session.PersistenceContext.Unproxy(x);

As mentioned in another answer, if you're trying to implement equals it would be a good idea to check out the Sharp architecture implementation of Equals.

Jeff Walker Code Ranger