2010-12-23 1 views
7

Est-il possible de créer une fonction personnalisée qui capture les exceptions effectuées dans une méthode définies par un attribut personnalisé?Utilisation des attributs personnalisés C# pour la journalisation des traces d'audit et des exceptions

planification im faire quelque chose comme ceci:

[Logging(FeatureEnum.SomeFeature, IntentEnum.SomeIntent, "some comment")] 
public void SomeMethodThatDoesATask() 
{ 
    try 
    { 
     var doSomeAction = new LazyProcess(); 
     doSomeAction.WhoDunnit(); 
    } 
    catch(Exception ex) 
    { 
     StaticMethodThatDoesLogging.CatchError(ex); 
    } 
} 

La question est: Comment capturer le nom de la méthode où cet attribut a été placé et quel événement a été jeté? Il peut capturer une exception ou simplement enregistrer automatiquement que cette méthode a été appelée.

+0

Connaissez-vous la bibliothèque PostSharp? http://www.sharpcrafters.com/postsharp (pas plus gratuit). –

+1

bonjour Uwe, la raison pour laquelle je fais le mien. –

+0

Juste mon avis, mais l'édition de la communauté (qui est libre, sortof) a plus que suffisamment de capacités pour la plupart des utilisations. J'ai lu qu'il y a de la sorcellerie sérieuse qui fait travailler PostSharp et je préfère les laisser faire. Sinon, bonne chance! –

Répondre

5

Cela ne peut pas être facilement réalisé. Par exemple TypeMock utilise l'API du profileur de structure .NET pour surveiller l'exécution d'une application. Il vous permet de vous inscrire à différents événements et d'être averti quand une méthode est appelée, une exception se produit, ... mais cela ne va pas être une tâche facile. D'autre part, vous pouvez utiliser AOP mais vous devez modifier votre code pour que l'appelant utilise un proxy généré au lieu de la classe réelle. Spring.NET a quelques fonctionnalités intéressantes à ce sujet. Donc, fondamentalement, sans utiliser l'API Profiler .NET framework ou sans écrire du code personnalisé qui lit les attributs d'une classe donnée en utilisant la réflexion, vous ne pouvez pas le faire. Les attributs sont juste des métadonnées de classe et sans quelque chose qui leur donnerait un sens, ils ne font rien.

+0

Je suis d'accord - il est préférable d'utiliser la bibliothèque plutôt que de déployer sa propre implémentation. – VinayC

1

Les attributs ne sont que des métadonnées. Vous auriez besoin de faire du tissage de code, d'utiliser quelque chose comme PostSharp, ou d'utiliser une bibliothèque d'interception d'exécution telle que Castle.DynamicProxy. Par eux-mêmes, les attributs ne contiennent aucune fonctionnalité réelle à l'application, sauf par la réflexion.

Si vous avez une ligne de code dans la méthode qui effectue la journalisation, vous pouvez obtenir la structure de la méthode appelante, utiliser la réflexion pour vérifier l'attribut et partir de là. Je suppose que c'est ce que vous vouliez faire avec StaticMethodThatDoesLogging.

public void CatchError(Exception ex) 
{ 
    StackFrame parentFrame = new StackFrame(1); 
    MethodBase mi = parentFrame.GetMethod(); 
    LoggingAttribute attr = mi.GetCustomAttributes(typeof(LoggingAttribute), true).FirstOrDefault() as LoggingAttribute; 

    if (attr != null) 
    { 
     // do your logging. 
    } 
} 
+0

Espérons que cela compile. Je n'ai pas Visual Studio à portée de main pour l'essayer moi-même. J'ai fait beaucoup de cela récemment, donc je travaille de mémoire. – Amy

Questions connexes