Fabien Bézagu

Visibilité interne et NHibernate

Récemment, nous avons fait une petite découverte intéressante concernant NHibernate. Oh, ce n'est qu'une petite chose sans grande importance mais je trouve regrettable que NHibernate ne détecte pas le problème "à la source".

Problème

Parfois, nous voulons réduire la portée d'un constructeur, d'une méthode ou d'une propriété au modèle du domaine en utilisant le mot clef C# internal. Lorsque nous souhaitons rendre persistante la classe contenant ce membre interne, NHibernate offre par défaut son mécanisme de proxy. Nous avons tous eu cette erreur de mapping à la création de la SessionFactory qui dit à peu près : Method should be virtual. Seulement, cet avertissement n'est levé uniquement lorsque la visibilité est publique. Dans le cas d'une méthode interne, NHibernate ne "voit" pas la méthode. Or, cette méthode peut être invoquée depuis l'extérieur de la classe. Deux cas de figures peuvent se présenter.

Réhydratation par NHibernate

NHibernate tente d'utiliser le constructeur interne : dans ce cas, une erreur de type Constructeur non trouvé est lancée. Sans avoir vérifié, je pense que s'il essaye d'accéder à une propriété interne, le même type d'erreur surviendra.

Invocation depuis le même assemblage

Ce cas est beaucoup plus vicieux à détecter et il s'agit de ma réelle motivation pour écrire ce billet. Lorsque la méthode interne est invoquée (donc nécessairement depuis le même assemblage), elle peut accéder à des champs privés. Or ces champs, si la classe est "proxifiée", ne contiennent pas les valeurs réelles. Ces valeurs sont dans le proxy qui intercepte normalement tous les appels par polymorphisme et accède à un tableau contenant tous les champs privés. La méthode interne n'aura donc jamais connaissance des bonnes valeurs des champs privés.

Solution

La solution, afin que NHibernate puisse voir les membre internes des classes qu'il proxifie est donc double :

  • Prendre l'initiative de marquer ces membres comme virtuels : ainsi, le polymorphisme pourra fonctionner,
  • Ajouter la visibilité protégée aux membres : de cette façon, les proxy, qui ne sont pas dans le même assemblage, pourront y accéder. (pour rappel, la visibilité internal protected rend les membres visibles depuis l'assemblage et en plus depuis les héritiers).

Mon réflexe désormais seront donc certainement d'éviter les membres internes purs et d'y adjoindre quasi systématiquement la visibilité protégée.

MetaBuilders

Je n'ai pas pris l'habitude de signaler mes découvertes mais je trouve que celle-ci mérite le détour. Il s'agit d'une librairie de contrôles Web pour ASP.NET qui s'appelle MetaBuilders. Elle est Open Source et bien que je ne l'ai pas encore exploré à fond, elle me semble très utile.

Le spam, fléau des temps modernes

Comme vous l'avez peut-être remarqué, mon blog n'était pas disponible ces trois derniers jours avec un joli message de Free indiquant que "Non, n'insistez pas, nous ne satisferons pas votre demande !". Tout cela à cause du spam. Quand un site web a la chance de recueillir autant de gentils commentaires, il a en plus le plaisir de se faire couper du monde et, cerise sur le gâteau, de se faire amputer de la jambe droite, à savoir la table MySql souffrant de boulimie.

Une pointe d'agacement et d'impuissance m'envahit sachant qu'il s'agit de mon deuxième avertissement. Au troisième, tchao le beau blog. Fort de ma première expérience, je m'étais armé de sauvegardes mais, malheureusement, la dernière n'était pas assez récente : j'ai perdu les commentaires sur le billet concernant la Nested Factory. J'en suis navré et prie mes chers lecteurs de bien vouloir m'excuser pour la gêne occasionnée.

Je parlais d'impuissance car je me suis tout de même doublement équipé : j'ai mis en place des captchas et un filtre anti-spam. Le captcha ne semble pas assez puissant et laisse passer beaucoup trop de commentaires indésirables. Comme je n'ai pas activé la suppression automatique dans mon filtre anti-spam, la table grossit et si je ne veille pas au grain, Free le fait pour moi.

Aujourd'hui j'ai deux options :

  1. Activer la suppression automatique des messages que mon filtre considère comme sale et laisser les commentaires ouverts sur tous les billets. Le risque est de voir certains messages désirés détruits sans autre forme de procès.
  2. Désactiver les commentaires sur mes plus vieux et plus contaminés billets.

N'hésitez pas à me dire ce que vous en pensez. En attendant, j'opte pour la première option.