lundi 11 septembre 2017

Method Interception using Reflection in C#

I wrote an abstract class that uses reflection to find fields marked with an Attribute in the constructor, like this:

[AttributeUsage(AttributeTargets.Field)]
public class TrackedField : Attribute {}

public class ATrackedObject {
    public ATrackedObject() {
        Type objType = this.GetType();
        foreach(FieldInfo f in objType.GetFields()) {
            if(f.IsDefined(typeof(TrackedField)), false)) {
                //Add field to list to keep tabs on periodically
            }
        }
    }
}

What I would like to do, is:

  1. Create another attribute, TrackedMethod
  2. In the constructor, in the same fashion as with the TrackedFields, find all methods tagged with TrackedMethod
  3. Change the method so that when it gets called, a method inside ATrackedObject gets called first or instead, either by replacing the method entirely or by injecting code into it, but without breaking the ability to at least see what the original method call was, including parameters
  4. No third-party libaries, and should be .NET 3.5 compatible

I have seen a number of SE threads discussing how to do this, and all of the answers relied on being able to use a third party library - however, none of the questions seemed to match my use case exactly - I can ensure 100% that every object that needs to have methods tracked will inherit from the class that does the tracking.

I don't know for sure this is possible, but I am wondering since IoC/AOP libraries like PostSharp and others exist, surely they must operate by some kind of mechanism - I assume Reflection.Emit plays a part - but what, and how?

Here are some similar questions, which did not have what seemed to me to be answers to my specific scenario, or relied on third party libraries:

custom-attribute-to-process-info-before-a-method-is-called

how-do-i-intercept-a-method-call-in-c (this was helpful, but missing the crucial component of how to actually inject code

intercept-method-calls

Is there a way to make this technique (Attribute -> Base Class Constructor -> Reflection -> Method Interception) viable?





Aucun commentaire:

Enregistrer un commentaire