So, I'm trying to solve a problem that I'm sure someone else has already encountered. Basically, I want the call to my IoC container to recursively resolve the dependencies, but also potentially execute some custom code to alter the outcome based on a set of predefined criteria. That's vague, so let me give an example:
Say I have a controller like so:
public class SampleController : Controller
{
protected SampleType _sampleType = null;
public SampleController(SampleType sampleType)
{
_sampleType = sampleType;
}
}
I've also got some test versions of this controller (say I refactored it and I want to make sure it doesnt break horribly in prod by AB testing it's exposure):
public class SampleController_V2 : SampleController
{
protected SampleType _sampleType = null;
protected AnotherType _anotherType = null;
public SampleController_V2(SampleType sampleType, AnotherType anotherType)
{
_sampleType = sampleType;
_anotherType = anotherType;
}
}
I've extended the DefaultControllerFactory
to use Unity when creating the controllers. This is all working fine. Now, what I want to do, it provide the ability to AB test any particular type in the hierarchy if things to resolve. This works well for the top level, but not for child elements as it recurses through the object graph.
Right now, it will choose the appropriate controller to resolve and give it its dependencies. However, I cant seem to intercept the individual calls to dependencies to also AB test those. I can define a test through database configuration, and then have the IOC container resolve it based on the criteria. Example:
SessionIds that start with the letter 'a': SampleController_V2
Everyone Else : SampleController
UserIds ending in 9 : SampleType_V2
Everyone Else : SampleType
This all works for the top level item. However, the call to _unityContainer.Resolve(type)
doesnt seem to be a recursive call; I'd like to be able to inject that code into any point when it tries to resolve a type:
-> Attempt to Resolve SampleController
-> Test Code Tells Us to use _V2 if possible.
-> Attempt to Resolve SampleType
-> Test Code tells us to use the _V1 if possible.
-> Resolves SampleType_V1
-> Attempt to Resolve AnotherType
-> No Test Defined, Use the Default
-> Resolves AnotherType
-> Resolves SampleController_V2 (passing SampleType_V1 as the dependency and then AnotherType as the other dependency)
Looking through some online articles, it sounds like I need to use some kind of Unity interceptor, but it's almost like I'm writing my own IoC container at this point with some kind of testing architecture built in.
Hopefully someone has a good idea on how to do this before I go down to pain of finding the constructor and then resolving each type recursively.
EDIT: So It actually hasnt turned out to be that horrible to create my own injection by inspecting the constructor parameters of each dependency recursively, but I think the boss people might get a bit perturbed if I throw out Unity for my own custom solution.