I am trying to create a proxy class dynamically. I know there are some very good frameworks out there to do this but this is purely a pet project as a learning exercise so would like to do it myself.
If, for example, I have the following class implementing an interface:
interface IMyInterface
{
void MyProcedure();
}
class MyClass : IMyInterface
{
void MyProcedure()
{
Console.WriteLine("Hello World");
}
}
To intercept methods to this class in order to log them, I am creating another class (my version of a proxy class) which implements the same interface but contains a reference to the 'real' class. This class performs an action (e.g. logging) and then calls the same method on the real class.
For example:
class ProxyClass : IMyInterface
{
private IMyInterface RealClass { get; set; }
void MyProcedure()
{
// Log the call
Console.WriteLine("Logging..");
// Call the 'real' method
RealClass.MyProcedure();
}
}
The caller then calls all methods on the proxy class instead (I am using a basic home-brew IoC container to inject the proxy class in place of the real class). I am using this method because I would like to be able to swap out RealClass
at run time to another class implementing the same interface.
Is there a way to create ProxyClass
at run time and populate its RealClass
property so it can be used as a proxy for the real class? Is there a simple way to do this or do I need to use something like Reflection.Emit
and generate the MSIL?
I wouldn't recommend doing this. Usually you use some well-known libraries such as Castle or EntLib. For some complicated classes it could be quite a challenge to dynamically generate a proxy. Here is an example of doing that using "Is" polymorphism. For this you have to declare all your methods in base as virtual. The way you were trying to do this ("Has") also possible, but for me looks more complicated.
Have a look at System.Runtime.Remoting.Proxies.RealProxy. You can use this to create an instance that appears to be the target type from the perspective of the caller. RealProxy.Invoke provides a point from which you can simply invoke the target method on the underlying type or perform additional processing before/after the call (logging, for example).
Here's an example of a proxy that logs to the console before/after each method invocation:
Here is how you would use it:
The output to console would then be:
Before invoke: MyProcedure
Hello World
After invoke: MyProcedure
You can use dynamic objects as described in this question, but for a dynamically-generated, strongly-typed object you'll have to use
Reflection.Emit
, as you suspected. This blog has example code showing the dynamic creation and instantiation of a Type.I have read that Roslyn has features which make creation of dynamic proxies easier, so maybe take a look there, too.
Maybe I have misunderstood the question, how about a constructor?