In my last post I have demonstrated a function generating a proxy object implementing an empty interface and a constructor from a base class. Now I will try to extend it to implement interface methods. First we need to list the interface methods we need to implement. We also have to remember our interface may inherit from other interfaces, so we need to scan it recursively.
To make things simpler and easier to follow, I will split the whole process into many small methods.
As the first step let’s create an entry point implementing an interface:
This method calls ImplementMethods() on our main interface and all parent interfaces.
We need to iterate through all the methods in the interface and implement all of them:
Finally - the main event of the evening - we are ready to generate a single method!
Now the fun part begins… We want our method to call other method(s) from the base class (DynamicProxy) and pass information about the call (name, parameters, return type etc.). There are few steps we need to take to do that:
Prepare a list of method parameters
Define a method with the typebuilder
Use IL Generator to create a method body, which calls the DynamicProxy method
For now I will Ignore the problem of generic parameters and overloading methods with the same names. Let’s leave that for later ;)
I will stop here. I spent two evenings analyzing the code that generates a method proxy:
And all I could do is copy it to my project and try to get it running. I would have to spend much more time on reading and learning IL to understand what is going on here. Let alone writing a blog post about it :). This is not the goal of this project or blog, so I decided to give up and take a different path.
No, no. I am not giving up on the project! I was lucky enough to get some helpful comments with suggestions to a previous post. Some people recommended Castle DynamicProxy - a framework doing just what I tried to solve here. It’s being used in NHibernate and a few mocking libraries. If these guys didn’t bother to do it manually, I think I am well excused from doing the same ;)
Sorry if you were hoping to learn how to grasp IL here. Maybe I will get back to it one day. For now I want to move forward with the project and I think sometimes it’s better to take the safer path than spend two weeks on a problem and end up with code you don’t fully understand. Especially that such code is much more prone to bugs.
I hope I will be able to show you a basic proxy implementation using DynamicProxy in the next post.
Michał Dymel's Picture
About Michał Dymel
Passionate software developer interested in Web Development, .NET, Angular2, Architecture and security. Currently doing remote consulting.