About NJect

NJect is an utility class that lets you inject your code into any method of any class. Typically, this is either a class that you don't control (such as a .Net framework or third party class), or a class that you don't want to pollute with the injected code. Possible applications include tracing method calls, breaking into the debugger at certain points, obtaining values of input parameters and return values, replacing target methods with your code, performance tuning, etc.

Getting started

NJect works on top of TypeMock Isolator, so before you run the code, you have to enable it. See instructions on their site.

In order to use it, you should follow these steps:

  1. Create an instance of the NJect.NJector class. You should do it before the target object is created.
  2. Inject code into one or more methods. You can inject your code before, after, or instead of the target method.
  3. Call the code that invokes creation of the target instance (or create it yourself). If you want, say, the third instance created, you can use the SkipInstances method of the NJector class.
  4. Call the code that invokes the target method(s).

Here's a sample. Using Reflector, I discovered that the System.Windows.Forms.Form.GetAutoScaleSize method creates a new instance of System.Drawing.Graphics and calls its MeasureString method. What I want to know is which text is being measured, and the result of the measurement. Here's how I do it:

public void Sample() {
 
    var inject = new NJect.NJector(typeof(System.Drawing.Graphics));
    // In order to make this work, you have to add the following call (see the explanations below):
// inject.SkipInstances(2);
 
    // After each MeasureString call, run the diagnostic code
    inject.After(
        "MeasureString", // method name
        new Type[] { typeof(string), typeof(System.Drawing.Font) }, // types of parameters
        delegate(object target,       
System
.Reflection.MethodBase method,
object
[] parameters, object returnValue) { //inject the code in curly brackets
            string text = parameters[0] as string; //the first argument
            System.Drawing.SizeF result = (System.Drawing.SizeF)returnValue; //the return value
            Console.WriteLine("MeasureString is called for '{0}', the result is {1}", text, result);
        });
 
    //call the actual code
    var x = System.Windows.Forms.Form.GetAutoScaleSize(System.Windows.Forms.Form.DefaultFont);
 
}

If we actually run this code, we don't get any console output. This mystery can be solved with the help of the TypeMock Tracer. Turns out that 3 instances of the Graphics class are created, and only the third one calls MeasureString. So, we add a call to SkipInstances() at the beginning to get straight to the third instance.

Download NJect

You can download the code here.