37 votes

L'identification de NHibernate des classes proxy

Je ne suis pas un NHibernate utilisateur; j'écris une sérialisation de l'utilitaire de bibliothèque. Un utilisateur a ouvert une fonction de demande que je devrais gérer NHibernate des classes de proxy, de les traiter de la même manière que le type réel. Pour le moment mon code est de les traiter comme héritage inattendu, et de lancer une exception.

Le code ne sais pas à l'avance sur NHibernate (y compris l'absence de référence, mais je ne suis pas aftaid de réflexion ;-p)

Est-il robuste / moyen fiable de détecter ces types de proxy? Apparemment DataContractSerializer le gère bien, donc je suis en espérant qu'il y est quelque chose d'assez simple. Peut-être que certains d'interface ou d' [attribute] décoration.

Aussi, lors de la désérialisation; pour le moment, je serais de créer le type d'original (pas le NHibernate type). Est-ce d'amende pour la persistance des fins? Ou est le type de proxy nécessaire? Si ce dernier; ce qui est nécessaire pour créer une instance du type de proxy?

49voto

Diego Mijelshon Points 40314

Vous pouvez détecter si une classe est un NHibernate proxy par moulage (sans surprise) INHibernateProxy.

Si vous avez besoin pour obtenir le sous-jacent "réel" d'un objet, utilisez:

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

Vous n'avez pas besoin de test pour les proxys d'appel Unproxy; elle renvoie le paramètre d'origine si ce n'est pas un proxy.

Edit: je vais maintenant utiliser une approche différente pour obtenir l'objet sous-jacent, la plupart pour travailler autour de chargement paresseux et à l'héritage: http://sessionfactory.blogspot.com/2010/08/hacking-lazy-loaded-inheritance.html

16voto

Vijay Patel Points 5696

Je devine que vous n'avez pas vraiment envie d'accéder à la véritable Nhibernate session. Ce code peut mieux l'adapter à vos besoins:

/// <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();
    }
}

Espérons que cela aide.

8voto

Sam9291 Points 382

Il est un outil de NHibernate où vous donnez un type (proxy ou pas) et il renvoie le type réel. (Je suis à l'aide de NHibernate 3)

C'est la façon dont vous l'utiliser:

var realType = NHibernate.NHibernateUtil.GetClass(proxyInstance);

Espérons que cela aide :D

1voto

s1mm0t Points 2957

NHibernate crée (proxy) des sous-classes d'entités lors de l'exécution pour être en mesure de faire le chargement paresseux. Il est seulement capable de faire cela parce que vous êtes obligés de marquer toutes les propriétés que "virtuel". Je ne peux pas penser à comment vous pourriez détecter qu'un objet est un proxy, par opposition à tout autre type de sous-classement - certainement pas de manière générique. Je ne peux que présumer que votre code est en train de lancer une exception dans ce cas parce que la classe réelle qui est en cours de (dé-)sérialisé n'est pas marqué comme étant serializable. Je pense que la seule chose que vous pouvez faire est de desserrer jusqu'à votre validation ou de permettre la sérialisation d'une sous-classe si elle remplace toutes les propriétés de sa classe de base.

La désérialisation pour le type d'original sera parfait.

1voto

Jamie Ide Points 28680

NHibernate 2.1+ permet la dynamique de fournisseur de proxy dans la configuration. Les implémentations que je suis conscient de Château (valeur par défaut), LinFu, et le Printemps. NHibernate n'a pas besoin d'une interface ou d'un attribut. Je pense que cela rend assez impossible à détecter de manière fiable si un objet est un proxy.

Comme s1mm0t répondu, en créant le type réel sur la désérialisation est très bien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X