2009-02-24 4 views
4

J'utilise Unity pour résoudre des types dynamiquement pour une architecture enfichable. J'utilise également l'interception pour appliquer la validation des règles métier via AOP (en utilisant ValidationAspects). Enfin, j'utilise NHibernate comme ORM pour conserver les objets de domaine.Obtention d'une instance réelle à partir d'un proxy sous Unity Interception avec NHibernate

Pour que l'AOP fonctionne, nous utilisons le VirtualMethodInterceptor, car l'interception d'interface ne fonctionne pas avec NHibernate. J'ai une façade sur ISession qui gère la conversion entre l'interface et les types réels pour les opérations de dépôt.

Pour vous assurer que tous les objets du graphique tiré par les cheveux via NHibernate sont correctement AOP pour serveur mandataire, je fait une mise en œuvre NH IInterceptor et l'emportaient sur la méthode Instantiate(), pour que je puisse fournir NH avec des objets créés plutôt que l'avoir appeler new(). J'utilise ensuite Container.Resolve() pour récupérer les objets mandatés avec la validation injectée, et je la retourne à NH pour la remplir. Cela fonctionne bien.

Le problème survient lorsque le vidage de session se produit. NHibernate se fâche parce que les objets qu'il voit dans le graphique sont du type proxy plutôt que du type réel. La façon dont nous mappons (tous via la propriété, tous virtuels) NH devrait être en mesure d'obtenir toutes les valeurs dont il a besoin via le proxy, si je pouvais passer outre la vérification de type. Ce que je dois savoir est: étant donné un objet transparent proxié créé par Unity avec interception activé, est-il un moyen d'obtenir une référence directe à l'instance 'réelle' il est mandaté, ou b) pour remplacer NH et Dites-lui de traiter les objets d'un type de proxy comme s'il s'agissait d'un type mappé connu, de manière dynamique lors de l'exécution?

+0

Pouvez-vous construire un cas-test de base de cette situation? Avez-vous envisagé d'utiliser NHibernate.Validator à la place? (http://nhforge.org/wikis/validator10/nhibernate-validator-1-0-0-documentation.aspx) –

+0

Je ne l'avais pas, bien que je puisse le regarder un peu plus puisque vous le mentionnez. Nous aimons ValidationAspects spécifiquement à cause de la capacité AOP - vous pouvez effectuer une validation au niveau de la méthode ou du paramètre sans avoir besoin d'appeler aucune méthode d'assistance. –

+0

Même un simple test-case risque de fonctionner avec beaucoup de LOC. Je sais ce qu'est le «problème» - c'est un conflit entre la vision NH du monde et la vue Unity Interceptor. En théorie, Castle Windsor + PostSharp fonctionnerait, mais j'aime l'unité et j'aimerais l'essayer. Peut-être pirater source :-( –

Répondre

0

Nous utilisons l'interception pour la mise en cache. Donc, dans notre classe, qui implémente ICallHandler nous avons le code comme ceci:

public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     //... 
     var nextHandler = getNext(); 

     var realReturn = nextHandler(input, getNext); 

     var cacheRefreshingItemParameters = new CacheRefreshingItemParameters 
     { 
      InterfaceMethod = input.MethodBase, 
      InterfaceType = input.MethodBase.DeclaringType, 
      TargetType = input.Target.GetType() //remember original type 
     }; 
     _cacheProvider.Add(cacheKey, realReturn.ReturnValue, cacheRefreshingItemParameters); 

     //... 
     return (cachedReturn); 
    } 

Nous mettons cacheRefreshingItemParameters dans le cache UpdateCallback et résoudre le service d'origine:

var service = _unityContainer.Resolve(parameters.TargetType); 
Questions connexes