This article started with my need for a good and simple interception mechanism for
some requirements that could be solved using AOP techniques. There are plenty of
interceptors out there but most of them (Castle.net, Spring.net, LinFu, etc..) would
require to emit dynamic child classes through IL code at runtime and thus ends with
almost always the same limitations regarding the classes you can intercept : they
can not be static, must be non-sealed, properties and methods must be virtual, etc...
Other interceptions mechanism would require to change the build process or to buy
a license. I could not afford one or the other...

AOP stands for Aspect Oriented Programming. I guess every reader is familiar with
the OP part of the acronym so we will have to clarify what Aspect means and don’t
worry we’ll come to that later in the article.

I’ll (try to) keep this article at beginner level. Knowledge of Object Oriented
Programming concepts is the only requirement to read further!

In my opinion understanding properly a concept make you a better consumer of its
implementation. But, I do understand that the article is a bit long so if you feel
bored or discouraged I still encourage you to jump to the implementation part. You'll
still be able to come back to theory later.

If you are familiar with AOP then don't leave yet!
Let me already disclose straight away what this article has to offer...

I will introduce an interception technique which allows to intercept:

any class (including sealed, static, value types)

constructors

type initializers

instance methods, properties and eventsand events (even if they
are not marked as virtual)

static methods, properties and events

Without

Weaving your code or your assemblies

emitting IL code

using any dynamic stuff

modifying your target class

forcing the weavers to implement anything (such as MarshalByRef)

Basically we are talking about a pure managed code technique which could run on
.Net 1.1 (actually I use bits of Linq but you can change t that easily) and which
allows you to intercept almost anything you might think of.

Let's be more clear. With the following technique:

you can intercept stuff such as System.DateTime.Now or System.IO.File
operations!
you don't have the usual limitations of the most popular interceptions library.

Some might think they have not made their full journey into Object Oriented Programming
so why would they switch from OOP to AOP and abandoned all the concepts they hardly
have learnt over the years? Answer is simple: there is no switch. There is no:
OOP vs AOP! AOP is one of these concepts which name, in my opinion,
is misleading. Embracing the AOP principles lets you dealing with classes, objects,
interfaces, inheritance, polymorphism, abstraction etc… so there is no way you get
lost as you are still fully immersed in the OOP world.

When applying AOP concepts in your code you are attempting to relax one particular,
and not the least, principle of OOP which is encapsulation to adress cross-cutting
concerns (we'll come back to that later on).

Back in the old days, when internet was only yellow pages, bulleting boards and
usenet, you were better to read books if you wanted to learn anything (comment for
the y generation : a book is a thing with written sheets of paper stuffed in it).
And all these books would approximately remind you this regarding the OOP subject:

Rule #1: you have to encapsulate all you data and code

Rule #2: never ever break Rule #1

Encapsulation has been the ultimate goal for introducing OOP concepts
in 3rd generation languages (3GL).

Wikipedia:Encapsulation is used to refer to one of two related but distinct
notions, and sometimes to their combination:

A language mechanism for restricting access to some of the object’s components.

A language construct that facilitates the bundling of data with the methods
(or other functions) operating on that data.

AOP, in a way, is claiming that it, sometimes, should be possible to use:
a language construct that facilitates the bundling of methods (or other functions)
operating with encapsulated data without the data.

Got that? Then you get all that is to know about the theory. Good job!

You are software developer in a bank. The bank has a pretty working operational
system. The business is running smoothly. Government emits a policy which enforces
banks to commit on some sort of transparency. Whenever money goes in or out of the
bank it should be logged. The government publicly said that this is a first measure
towards transparency but that more is to be expected.

Your web application has been released to test team. All functional tests passed
but the application failed at load testing. A non-functional requirement stated
that no page should take more than 500 ms to process on the server. After analysis
there are dozens of queries made to the database that could be avoided by caching
the results.

You have spent the last 2 years modeling your domain model in a perfect library
consisting of 200+ classes. Lately you’ve been told that a new application front-end
will be written and this guy needs to bind your objects to the UI. But to facilitate
that task all your classes should now implement INotifyPropertyChanged.

These examples are valid in terms of the why and when AOP could come to the rescue.
These scenarii have the following in common:

Some classes (Bank class, Data access services, Domain model classes, etc…) designed
to achieve a given functionality have to be modified to handle a requirement which
is basically “not their own business”.

The Bank class purpose is money exchange. The logging concern is Government’s interest.

The Data Services classes purpose is to retrieve data. The data caching concern
is a non-functional requirement.

The domain model classes purpose is to handle your company’s business. The concern
about notification of property changed is in the UI interest.

It is whenever you have to write some code over different classes to fulfill an
interest external to these classes. In AOP dialect it is whenever you have a
cross-cutting concern.

The notion of cross-cutting concern is centric to AOP. No cross-cutting
concern = no need for AOP!

why should it be possible?

Let’s take a closer look at Scenario C.
Your problem is that you have an average of 5 properties exposed by each class in
your domain model. With 200+ classes you will have to implement (copy/paste) more
than 1,000 times some boiler plate code to transform something which looks like
this:

Uh! And that is for one property only! BTW, did you know the intern left 2 days
ago?

You surely get the why without further explanations

It should be possible "to bundle the methods operating with encapsulated data without
the data" in other words : externalise the implementation of the cross-cutting
INotifyPropertyChanged concern with no or minimum impact on domain
model classes like Customer.

We have a cross-cutting concern which requires some code to be
executed in several classes (targets from now on).
The implementation (the code which implements Logging, or Cache, or whatever) is
simply called concern in the AOP world.

We should then be able to attach (inject, introduce, etc... choose your word) our
concern (I repeat because it is important: the concern
is the implementation for your cross-cutting concern) at any chosen
place of the target.
And we should be able to choose any of the following places of the target
to attach our concern:

Static initializers

Constructors

Static Property getters and setters

Instance Property getters and setters

Static methods

Instance Methods

Destructors

In a perfect AOP world we should be able to attach our concern
at any line of code of the target.

Fine, but if we want to attach a concern we need a hook in the
target, don’t we? Yes captain!
In AOP the notion of that hook (the place where your concern is
going to be attached for execution) has a name: it is a pointcut.
And the place from where you actualy attach the code has also a name : it is a
joinpoint.

Clear enough? Maybe not.... Here is some pseudo-code that hopefully demonstate the
idea:

Before we move on to our actual implementation let's introduce a few more definitions...

What is an Aspect?
It is the association of a concern, a point cut
and a joinpoint.
Think of it for a second and I hope it will be crystal clear: the fact that I have
a Logging mechanism (concern), that I register its log method to
be executed (joinpoint) at a given place of my application code
(pointcut) is one aspect of my application.

But wait a minute... What could/should a concern be allowed to
do once injected?

Concerns are categorized into 2 categories:

Side effects:
A side effect is a concern which is not changing
the behavior of the code at pointcut. A side effect
just introduce an additional action to perform.
A Logging concern is a good example of a side effect:
whenever the runtime execute the targeted method (eg:Bank.Withdraw(int Amount))
the LoggingConcern.LogWithdraw(int Amount) method will be executed
and the Bank.Withdraw(int Amount) method will continue execution.

Advices:
An advice is a concern which might change the
input/output of the method.
A Caching concern is a perfect example: Whenever the runtime execute
the targeted method (eg: CustomerService.GetById(int Id)) the CachingConcern.TryGetCustomerById(int
Id) will be executed and will force the CustomerService.GetById(int Id)
method to return with the value found in cache, if any, otherwise will let the execution
continue.

Advices should be allowed to:

Inspect the input parameters at targeted pointcut and modify them if needed

Cancel the execution of the targeted method and replace it with a different implementation

Inspect the output result od the targeted method and modify or replace it

At that point if you are still reading then congratulations! Bravo! Parce que vous
le valez bien...

We are done with the general concepts and ideas of AOP. Let's move forward and see
how we can get close to that with C#...

There is no easy way to get pointcuts for every single line of
code. But we can get one at each method call and that's fairly easy by using the
System.Reflection.MethodBase class. MSDN is not really verbose
about it: Provides information about methods and constructors.[sic].

Between you and me using MethodBase for getting reference to pointcuts
is the most powerful possibility at your disposition.

You can get reference to pointcuts for Constructors, Methods, Properties and Events
as for .Net almost anything you declare in your code (apart from fields) ends up
being a method...
See yourselves:

... there is just no reason why our registry would be consulted, so there is no
way that our LoggingConcern.DoSomething() method is executed...

Our problem is that .Net does not provide us with a simple way to intercept such
calls out of the box.

As there is no native way then some work around must be implemented. The capabilities
of your work around is going to drive the capabilities of your AOP implementation.
The goal of this aricle is not to discuss all possible interception techniques but
take note that the interception model is the key differentiator
between all AOP implementations.
The SharpCrafters website (owners of PostSharp) is providing some clear information
on the 2 major techniques:

There is not much of a secret if you want to intercept all calls made to a class
you have 3 choices:

Create your own language and compiler to produce .net assemblies: when compiling
you can inject whatever you want everywhere you want.

Implement a solution which modifies the runtime behavior of assemblies

Give a proxy to your consumer and intercept calls using an Interceptor class while
marshaling the real subject (target)

For advanced guys: I voluntarily don't mention Debugger API and Profiler API possibilities
which are not viable for production scenarii.
For very advanced one: An hybrid of solutions 1 and 2 using the Roslyn API should
be feasible and, as far as I know, it is still to be invented. A bon entendeur...

Apart if you need to provide pointcuts at any single line of code
then it seems that the 2 first solutions are a bit of over-engineering.
We'll go for the 3rd solution. Take note that usage of proxying technique comes
with a good and a bad news:

The bad news is that your target object must be swapped at runtime
with a proxy object instance. Implying that if you want to intercept things such
as constructors you'll have to delegate construction of your target
class instances to a factory (that's a cross-cutting concern that
this implementation won't solve. If you already have an instance of the target
class then you will have to explicitely ask for the swap to happen. For
the IOC and Dependency Injection ninjas the delegation of objects creation will
be less than an issue. For others it means they'll have to use a factory if they
want to use our interception technique at its full extent. But don't worry we are
going to implement that factory.

The good news is that we have nothing to do to implement a proxy. The class System.Runtime.Remoting.Proxies.RealProxy
will build it for us in a highly optimized way.

In my opinion the class name does not reflect its use. This class is not a Proxy
it is an Interceptor. But anyway that class will provide us with a Proxy by calling
its method GetTransparentProxy() and that's the only thing we need.

Some explanations are required here as we are now touching the heart of the implementation....

The RealProxy class exists to serve the purpose of intercepting calls
from remote objects and marshal a targeted object. By remote here you must understand
really remote like : objects living in another application, another AppDomain, another
server, etc...). I am not going to go too much in details but there were 2 ways
to marshal objects in the .net Remoting infrastructure : by reference or by value.
Basically it means you can only marshal remote objects if they are inheriting
MarshalByRef or if they implement ISerializable. Our plan
is not to use the remoting capabilities at all but we still need to let the RealProxy
class think our target is acceptable for remoting. That's why we pass typeof(MarshalByRef)
to the RealProxy base constructor.

The RealProxy class is receiving all calls made on the transparent
proxy via the System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage
msg) method. That's where we will implement the details about method
swapping. Read the comments in the code above.

About the implementation of IRemotingTypeInfo: In a true remoting environment
the client side would request an object to the server. The client application runtime
might not know anything about the type of the marshalled remote object. So when
the client app makes a call to the method public object GetTransparentProxy()
the runtime must decide if the returned object (the transparent proxy) is boxable
to the client application expected contract. By implementing IRemotingTypeInfo
you give a hint to the client runtime telling if casting to a specified type is
allowed or not.
And guess what the trick is there, in front of your astonished gaze, right here...

publicbool CanCastTo(Type fromType, object o) { returntrue; }

All our AOP implementation is only possible due to the possibility offered by remoting
to write these 2 words: return true; Passed that point we can cast
the object returned by GetTransparentProxy() to whatever interface
without any runtime check!!!.

The runtime just purely and simply gave us a "yes card" to play with!

We might want to revisit that code to return something more appropriate than true
to any type... But we could also imagine make use of this behaviour to provide a
Missing
Method implementation or a catch all interface... There is a lot of room
fot your creativity to express istself here!

At that point we have a decent interception mechanism for our target instance. We
are still mising interception of constructors and creation of the transparent proxy.
That's a job for a factory...

publicstaticclass Factory
{
publicstaticobject Create<T>(paramsobject[] constructorArgs)
{
T target;
// TODO:
// Base on typeof(T) and the list of constructorArgs (count and their Type)
// we can ask our Registry if it has a constructor method joinpoint and invoke it
// if the Registry has no constructor joinpoint then simply search for the corresponding one
// on typeof(T) and invoke it...
// Assign the result of construction to the "target" variable
// and pass it to the GetProxy method.
return GetProxyFor<T>(target);
}
publicstaticobject GetProxyFor<T>(object target = null)
{
// Here we are asked to intercept calls on an existing object instance (Maybe we constructed it but not necessarily)
// Simply create the interceptor and return the transparent proxy
returnnew Interceptor(target).GetTransparentProxy();
}
}

Note that the Factory class is always returning an object of type
object. We can't return an object of type T because the
transparent proxy is simply not of type T, it is of type System.Runtime.Remoting.Proxies.__TransparentProxy.
But, remember the "Yes card", we can cast the returned object to whatever interface
without any runtime checking!

We will nest the Factory class in the AOP class hoping
to give a neat programming experience to our consumers. But you'll see that in the
Usage section below

If you have read the whole article till that point I must recognize you are almost
a hero! Bravissimo! Kudos!

For the sake of brevity and clarity of this article (damned... why are you smiling?)
I am not going to discuss the boring implementation details of method retrievals
and switching. There is actually not much fun in it. But if you are interested in
that piece then you can download the code and browse it : it is fully functional!.
The classes and methods signature might be a bit different as I am coding while
but no major change is to be expected.

Warning: Before deciding to use this code in your project please
read carefully the
paenultimus section. And if you don't know
the word paenultimus then I guess you have to click the link first!

That's where we benefit from the "Yes card"! Remember? There is no runtime type
checking between the returned proxy and the interface.
Which means we can create any kind of interface... no one as to implement it anyway:
neither the target nor the concern. Basically
we are only using the interface as a contract...

Let's demonstrate that by creating a fake interface to mimic the static File
class

So far we have been able to achieve the primary goal of AOP : implement an aspect
and register it for execution. TinyAOP is born. But your journey in AOP land is not finished yet and you might want to dig further:

Reason #1: Who wants to register Joinpoints the way we are now? Not me, for sure!
With a bit of introspection we can make things much more practical and build something
that look like a real AOP library. AOP is there to facilitate your life not to introduce
more pain.

Reason #2: Matters such as mix-ins and composition are completely uncovered and we can expect tons of goodness there.

Reason #3: We need performance and stability. Now the code is just a proof of concept.
It is far too slow when we can make it very fast. A bit of error checking would
not be bad either.

Reason #4: We are intercepting almost any kind of class but what about interfaces
interception??

Reason #5: Do we really need more reasons ?

Conclusion: We have a nice and tiny prototype which demonstrates the technical feasibility
of doing AOP purely with managed, non-dynamic, code without weaving, etc...

You have learnt AOP : you can start from here and roll your own implementation!

No secret that I am french... Nobody's perfect! While writing this article I was
googling for a place where the expression "A boire, ou je tue le chien!" would be
explained and I found that page called "French expressions you won't learn at school".
I am sure you might find some of these expressions pretty funny so I am sharing
the link : http://www.globule.org/~gpierre/french.php

A website such as Codeproject is only working because some guys are writing and
publishing articles. Whatever the reasons why these guys are doing it, they are!
And that takes a non-negligible amount of work and time.

Please do not neglect that time and work:
If you don't like the article please refrain to give your vote of 1 without further
explanations... I might have wrote a statement which is wrong or false, my english
surely needs rephrasing, maybe you are expecting more or less explanations, I don't
know... It is as simple as that: I don't know if you don't tell!
Your justified bad ratings are welcome I am not gonna hurt (ok, maybe a bit ) and
it will allow me to revise my judgment, make any necessary adjustments or corrections
to the article and also to improve myself for future ones.

Now if you liked the article, or you are using the code or if you have learned something
today then let me know as well : leave a comment, give me your
vote (of 5), drop me an email, connect on LinkedIn... Whatever form of feedback
is much appreciated!!!

I am a little wonder : is there another way to implement without 'RealProxy' ?

May be we could do as this (Just in my brain , for i am not familiar with IL yet):
1 Interface . IActor { string Name{get;set;} }
2 Implemetation . Actor :IActor .
3 Use ILGenerator dynamic generate a type ActorShadow which implemete IActor with an instance of Actor named _actor , and cache it . ActorShadow's implemention of IActor is actually just references of _actor's method .But "onentry" ,"before" ,"after" ,"onexception" ,"onexit" , we inject our own code by 'OprCodes.Call' .
4 _actor depends on which type you want to intcepte , and how to inject the concerns depends on your requires . Encapsulate IL logics in a class Named AOPFactory .