我正在尝试从一个抽象基类中移除一个服务定位器,但我不确定要用什么来替换它。以下是我所拥有的伪代码示例:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
问题在于,派生类的实例化程序不知道内核必须具有哪些绑定才能使MySpecialResolver
不抛出异常。
这可能是本质上棘手的,因为我不知道我将要解析哪些类型。派生类负责创建types
参数,但它们没有硬编码在任何地方。(这些类型基于派生类组合层次结构中深处的属性的存在。)
我一直在尝试使用延迟加载委托来解决这个问题,但到目前为止,我还没有想出一个干净的解决方案。
更新
这里实际上有两个问题,一个是IoC容器被传递给控制器,充当服务定位器。这很容易解决--您可以使用各种技术将位置上移或下移调用堆栈。
第二个问题是困难的,如何确保控制器在需要服务时具有必要的服务,而这些需求直到运行时才暴露出来。从一开始就应该很明显:你不能!你总是依赖于服务定位器的状态或集合的内容。在这种特殊情况下,无论怎样摆弄,都无法解决这篇文章中描述的静态类型依赖关系所描述的问题。我认为我最终要做的是将Lazy数组传递到控制器构造函数中,并在缺少必需的依赖项时抛出异常。