2010-10-25 19 views
4

J'essaye de faire une interception basée sur les attributs en utilisant structuremap, mais j'ai du mal à lier les dernières parties.Faire une interception avec structuremap

J'ai un Registre personnalisé qui scanne mes assemblées et dans ce Registre j'ai défini le ITypeInterceptor suivant qui a pour but de faire correspondre les types décorés avec l'attribut donné et ensuite appliquer l'intercepteur s'il est apparié. La classe est défini comme tel:

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> 
    : TypeInterceptor 
    where TAttribute : Attribute 
    where TInterceptor : IInterceptor 
{ 
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator(); 

    public object Process(object target, IContext context) 
    { 
     return m_proxyGeneration.CreateInterfaceProxyWithTarget(target, ObjectFactory.GetInstance<TInterceptor>()); 
    } 

    public bool MatchesType(Type type) 
    { 
     return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0; 
    } 
} 

//Usage 
[Transactional] 
public class OrderProcessor : IOrderProcessor{ 
} 
... 
public class MyRegistry : Registry{ 
    public MyRegistry() 
    { 
     RegisterInterceptor(
      new AttributeMatchTypeInterceptor<TransactionalAttribute, TransactionInterceptor>()); 
     ... 
    } 
} 

J'utilise DynamicProxy du Castle.Core pour créer les intercepteurs, mais mon problème est que l'objet retourné par la CreateInterfaceProxyWithTarget (...) appel ne implémenter l'interface qui a déclenché la création de l'instance cible dans structuremap (ie IOrderProcessor dans l'exemple ci-dessus). J'espérais que le paramètre IContext révélerait cette interface, mais je ne peux que sembler obtenir le type concret (c'est-à-dire OrderProcessor dans l'exemple ci-dessus). Je cherche des conseils sur la façon de faire fonctionner ce scénario, soit en appelant le ProxyGenerator pour renvoyer une instance qui implémente toutes les interfaces comme instance cible, en obtenant l'interface demandée de structuremap ou par un autre mécanisme.

Répondre

2

J'ai effectivement quelque chose qui fonctionne avec une légère mise en garde donc je vais juste poster ceci comme réponse. L'astuce consistait à obtenir l'interface et à la passer dans le CreateInterfaceProxyWithTarget. Mon seul problème était que je ne pouvais pas trouver un moyen d'interroger le IContext sur l'interface qu'il était en train de résoudre, donc j'ai fini par regarder la première interface sur la cible qui a fonctionné pour moi. Voir ci-dessous le code

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> : 
    TypeInterceptor 
    where TAttribute : Attribute 
    where TInterceptor : IInterceptor 
{ 
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator(); 

    public object Process(object target, IContext context) 
    { 
     //NOTE: can't query IContext for actual interface 
     Type interfaceType = target.GetType().GetInterfaces().First(); 
     return m_proxyGeneration.CreateInterfaceProxyWithTarget(
      interfaceType, 
      target, 
      ObjectFactory.GetInstance<TInterceptor>()); 
    } 

    public bool MatchesType(Type type) 
    { 
     return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0; 
    } 
} 

Hope this helps quelqu'un