所以,我正在尝试解决一个我确定其他人已经遇到过的问题。基本上,我希望调用我的 IoC 容器以递归方式解决依赖关系,但也可能执行一些自定义代码以根据一组预定义的标准改变结果。这很模糊,所以让我举个例子:
假设我有一个这样的控制器:
public class SampleController : Controller
{
protected SampleType _sampleType = null;
public SampleController(SampleType sampleType)
{
_sampleType = sampleType;
}
}
我也有这个控制器的一些测试版本(比如说我重构了它,我想通过 AB 测试它的曝光确保它不会在 prod 中严重损坏):
public class SampleController_V2 : SampleController
{
protected SampleType _sampleType = null;
protected AnotherType _anotherType = null;
public SampleController_V2(SampleType sampleType, AnotherType anotherType)
{
_sampleType = sampleType;
_anotherType = anotherType;
}
}
在创建控制器时,我已经扩展了DefaultControllerFactory
使用 Unity。这一切都很好。现在,我想做的是,如果要解决问题,它提供了对层次结构中的任何特定类型进行 AB 测试的能力。这适用于顶层,但不适用于子元素,因为它在对象图中递归。
现在,它将选择合适的控制器来解析并为其提供依赖关系。但是,我似乎无法拦截对依赖项的各个调用以也 AB 测试这些。我可以通过数据库配置定义一个测试,然后让 IOC 容器根据标准来解决它。例子:
SessionIds that start with the letter 'a': SampleController_V2
Everyone Else : SampleController
UserIds ending in 9 : SampleType_V2
Everyone Else : SampleType
这一切都适用于顶级项目。但是,调用_unityContainer.Resolve(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.