Click here to Skip to main content
Licence LGPL3
First Posted 4 May 2011
Views 2,838
Bookmarked 0 times

Intercepting Console.WriteLine and Other Third-Party Method Calls with LinFu.AOP 2.0

By | 4 May 2011 | Technical Blog
Intercepting Console.WriteLine and Other Third-Party Method Calls with LinFu.AOP 2.0
A Technical Blog article. View original blog here.[^]

ConsoleInterceptor

Worth a Thousand Words

In case you are wondering, yes, that is a screenshot of LinFu.AOP intercepting calls to Console.WriteLine() at runtime.

One of the more useful things that LinFu.AOP can do is intercept calls to third-party assemblies that aren't necessarily under your control. In fact, LinFu makes it so easy that all you have to do to make the interception happen is add the reference to LinFu like the following lines to your CSProj file just like I did with my SampleLibrary.csproj file:

<PropertyGroup>
  <PostWeaveTaskLocation>
    $(MSBuildProjectDirectory)\$(OutputPath)\..\..\..\lib\LinFu.Core.dll
  </PostWeaveTaskLocation>
</PropertyGroup>
<UsingTask TaskName="PostWeaveTask" AssemblyFile="$(PostWeaveTaskLocation)" />
<Target Name="AfterBuild">
  <PostWeaveTask TargetFile="$(MSBuildProjectDirectory)\
	$(OutputPath)$(MSBuildProjectName).dll" 
                 InterceptAllMethodCalls="true" />
</Target>

'Automagically' Delicious

Once you reload and rebuild the solution, LinFu.AOP will automatically modify your code after the build runs so that you can intercept it at runtime. LinFu does this by adding hooks to your code so you can change it as the program is running. In this case, I casted the modified BankAccount class to an IModifiableType instance so that I could add my custom ConsoleInterceptor instance:

// Create the BankAccount class just like normal...
var account = new BankAccount(100);
// Notice how LinFu.AOP automatically implements IModifiableType 
// so you can intercept/replace method calls at runtime
var modifiableType = account as IModifiableType;
if (modifiableType != null)
modifiableType.MethodCallReplacementProvider = new WriteLineMethodReplacementProvider();

account.Deposit(100);

The WriteLineMethodReplacementProvider class, in turn, determines the method calls that should be intercepted at runtime:

public class WriteLineMethodReplacementProvider : IMethodReplacementProvider
{
    public bool CanReplace(object host, IInvocationInfo info)
    {
        var declaringType = info.TargetMethod.DeclaringType;
        if (declaringType != typeof(System.Console))
        return false;

        // We're only interested in replacing Console.WriteLine()
        var targetMethod = info.TargetMethod;
        return targetMethod.Name == "WriteLine";
    }

    public IInterceptor GetMethodReplacement(object host, IInvocationInfo info)
    {
        return new ConsoleInterceptor();
    }
}

Choosing Which Methods to Intercept

As you can see from the example above, this class ensures that only calls to Console.WriteLine() are ever intercepted. The ConsoleInterceptor itself is responsible for replacing and intercepting the Console.WriteLine() method itself:

public class ConsoleInterceptor : IInterceptor
{
    public object Intercept(IInvocationInfo info)
    {
        var targetType = info.TargetMethod.DeclaringType;
        var target = info.Target;
        var targetMethod = info.TargetMethod;
        var arguments = info.Arguments;

        Console.WriteLine("Intercepted method named '{0}'", targetMethod.Name);

        // Call the original WriteLine method
        targetMethod.Invoke(null, arguments);

        // Console.WriteLine doesn't have a return value so it's OK to return null)
        return null;
    }
}

The most interesting part about the code example is how LinFu.AOP adds the method call hooks without touching a single line of the source code. All of the IL rewriting is done behind the scenes so you won't have to worry about the gory details of using an AOP framework in your legacy code. The beauty of this approach is that it allows you to intercept any method call, even if that method call is a part of the .NET base class libraries.

You can find the LinFu.AOP.Examples library here at Github.

Note: Please intercept BCL method calls responsibly.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

About the Author

Philip Laureano

Software Developer (Senior)

United States United States

Member

Follow on Twitter Follow on Twitter


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralSomething is missing? Pinmembercaloggins7:57 9 May '11  
GeneralRe: Something is missing? PinassociatePhilip Laureano14:00 9 May '11  
JokeRe: Something is missing? Pinmembercaloggins0:42 10 May '11  
GeneralGood stuff PinmemberRugbyLeague3:24 4 May '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 4 May 2011
Article Copyright 2011 by Philip Laureano
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid