I've been working on creating my own IoC container for learning purposes. After asking a couple questions about them, I was shown that creating a factory to "resolve" the objects was the best solution (see third solution here). User Krzysztof Koźmic showed that Castle Windsor actually can implement this for you.
I've been reading the source of CW all morning. I know when Resolve is called, it "returns the interface". How does this interface "intercept" calls (since there is no implementation behind) and call it's own methods?
I know there's obviously some reflection trickery going on here and it's quite amazing. I'm just not at all user how the "interception" is done. I tried venturing down the rabbit hole myself on git, but I've gotten lost. If anyone could point me in the right direction it'd be much appreciated.
Also - Wouldn't creating a typed factory have the dependency on the container inside the calling code? In ASP.NET MVC terms, that's what it seems to me.
EDIT: Found Reflection.Emit... could this be what's used?
EDIT2: The more and more I look into this, the more complicated it sounds to automatically create factories. I might end up just sticking with the repetitive code.
Visual Studio 2010 RC + ASP.NET MVC 2 RTM won't re-target from .NET Framework 4 to 3.5
MVC2 and Session Start Event
Test Function in MVC Project
- Dependency injection merely instantiates an existing class that implements the interface.
WebHost4Life host migrated my .NET MVC site and now membership functionality does not work
For example, you might have a MyServices class that implements IMyServices.
SSI-like feature in ASP.NET / ASP.NET MVC
IoC frameworks give you various ways to specify that when you ask for an IMyServices, it will resolve to an instance of MyServices.
how do i load thousands of rows in my asp.net mvc project from database into slickgrid?
There might be some IL Emit magic going on to set up the factory or helper methods, but the actual instances are simply classes you've defined..
HTML.DropDownList values from multiple sources?
- Mocking allows you to instantiate a class that implements an interface, without actually having to code that class.
Authentication for IIS content in virtual directory under ASP.NET MVC website
This does usually make use of Reflection and IL Emit, as you thought.
Typically the emitted IL code is fairly simple, delegating the bulk of the work to methods written in C#.
Most of the complexity of mocking has to do with specifying the behavior of the method itself, as the frameworks often allow you to specify behavior with a fluent syntax.
Some, like Moles, simply let you specify a delegate to implement the method, though Moles can do other, crazier things like redirecting calls to static methods..
Here is some information on what Castle Windsor is doing.. To answer your question, the most helpful place I found to start was the OpCodes class.
This is a good summary of the available functionality in IL and how the OpCodes function.
It's essentially a stack-based assembly language (no registers to worry about), but strongly-typed and with first-class access to object symbols and concepts, like types, fields, and methods.
Here is a good Code Project article introducing the basics of IL.
If you're interested, I can also send you some helper classes I've created over the last few years that I use for my own Emit code..
It generates a type on the fly that implements the interface and forwards all calls to that type, you make via the interface, to the interceptor.. It imposes no dependency in your code.
The interface is created in your assembly, that you control, where you don't reference Windsor.
In other assembly (entry point to the app) you tell Windsor about that interface and tell it to make it a factory and Windsor learns about your interface and does stuff with it.
That's Inversion of Control in its glory.. It's actually not that complicated :).
It allows you to have a dynamic implementation with a static interface.
In fact it even has a baseclass
ImpromptuFactorythat provides the starting point for creating factories with a dynamic implementation based on the interface..