Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identifying NHibernate proxy classes

I'm not an NHibernate user; I write a serialization utility library. A user has logged a feature-request that I should handle NHibernate proxy classes, treating them the same as the actual type. At the moment my code is treating them as unexpected inheritance, and throwing an exception.

The code won't know in advance about NHibernate (including no reference, but I'm not aftaid of reflection ;-p)

Is there a robust / guaranteed way of detecting such proxy types? Apparently DataContractSerializer handles this fine, so I'm hoping it is something pretty simple. Perhaps some interface or [attribute] decoration.

Also, during deserialization; at the moment I would be creating the original type (not the NHibernate type). Is this fine for persistence purposes? Or is the proxy type required? If the latter; what is required to create an instance of the proxy type?

like image 542
Marc Gravell Avatar asked Apr 18 '10 22:04

Marc Gravell


2 Answers

You can detect if a class is a NHibernate proxy by casting it to (unsurprisingly) INHibernateProxy.

If you need to get the underlying "real" object, use:

Session.GetSessionImplementation().PersistenceContext.Unproxy(proxiedObject)

You don't need to test for proxies to call Unproxy; it returns the original parameter if it's not a proxy.

Edit: I now use a different approach to get the underlying object, mostly to work around lazy loading and inheritance: http://sessionfactory.blogspot.com/2010/08/hacking-lazy-loaded-inheritance.html

like image 149
Diego Mijelshon Avatar answered Sep 28 '22 03:09

Diego Mijelshon


I'm guessing that you don't really want to access the actual Nhibernate session. This code might better fit your needs:

/// <summary>
/// Returns the real type of the given proxy. If the object is not a proxy, it's normal type is returned.
/// </summary>
internal static Type GetRealType(this object proxy)
{
    if (proxy is INHibernateProxy)
    {
        var lazyInitialiser = ((INHibernateProxy)proxy).HibernateLazyInitializer;
        return lazyInitialiser.PersistentClass;
    }
    else
    {
        return proxy.GetType();
    }
}

Hope that helps.

like image 22
Vijay Patel Avatar answered Sep 28 '22 04:09

Vijay Patel