2008-10-30 13 views
12

Je sais qu'il est possible (en théorie) de créer un nouveau type à l'exécution, mais est-il possible de modifier un corps de méthode d'un type existant à l'exécution? Mon plan (si je peux obtenir cela pour travailler) est de marquer des méthodes avec un attribut personnalisé, puis à la recherche d'exécution pour les méthodes avec l'attribut, et insérer une partie de mon propre code dans le corps de la méthode.Est-il possible de modifier un corps de méthode lors de l'exécution dans .NET?

Des suggestions? Je suppose que si je n'arrive pas à faire fonctionner cette approche, je pourrais toujours utiliser une méthode virtuelle dans une classe de base (avec les attributs), combinée à une usine statique pour cracher un type dynamique dérivé avec mon exécution méthode générée à l'heure dans la classe enfant. Ce ne serait pas aussi propre à utiliser.

Répondre

9

PostSharp qui est un aftercompiler, fait quelque chose de semblable à ce que vous décrivez, en utilisant des attributs pour marquer des points d'injection dans le code , seule différence est qu'il le fait à la compilation.

Mais vous pouvez également le faire au moment de l'exécution, non en changeant les corps des méthodes, mais en utilisant des classes dérivées de ContextBoundObject qui est une classe .Net qui vous permet d'intercepter tous les appels effectués contre elle. Voici un MSDN Magazine article décrivant comment faire AOP en utilisant ContextBoundObject. (Vérifiez les aspects en .Net partie de l'article)

Et comme une troisième option, vous pouvez utiliser la génération de code dynamique (Reflection.Emit ou CodeDom) en combinaison avec des attributs et des méthodes virtuelles pour générer dynamiquement des classes dérivées où vous peut insérer votre code, mais c'est la façon la plus douloureuse de le faire.

Edit:

Il y a une option fournir pour utiliser .Net unmanaged profiling API pour intercepter méthode JIT-tion et de remplacer les organes de la méthode avant JIT-ing. Cette technique est utilisée avec succès par JustMock (Telerik) pour simuler des méthodes statiques, des méthodes non virtuelles et même des classes scellées.

0

Avez-vous l'intention de le faire pour des types arbitraires? Je suppose que pas donné que vous allez décorer les méthodes avec un attribut. Compte tenu de cela, je pense que la meilleure approche serait de définir des méthodes abstraites dans une super classe pour vos types. Une méthode sur la super classe peut héberger le code de la méthode de plaque de chaudière et déléguer aux implémentations concrètes via les méthodes abstraites pour le comportement du type individuel de cette méthode. En règle générale cependant, à moins de créer des fichiers de code et de compiler des assemblages dynamiques lors de l'exécution, ce que vous cherchez à faire ne peut pas être fait. Il y a probablement beaucoup plus de principes OO et de modèles pratiques que vous pouvez utiliser pour atteindre le même résultat.

3

Vous ne pouvez pas modifier une méthode existante au moment de l'exécution, mais vous pouvez en créer une avec le code DOM à la volée et l'exécuter. Vous pouvez également concaténer des chaînes de code, les compiler en mémoire et les exécuter.

J'ai fait ce dernier moi-même (une application que j'avais autorisée code C# personnalisé qui a été compilé et exécuté en mémoire, runtime).

1

Un somewhat similar question a été demandé plus tôt (d'accord, donc ma solution était quelque peu similaire).PostSharp a déjà été mentionné mais il y a aussi cette très applicable que j'ai trouvé intéressante en recherchant le problème.