处理Caliburn Micro的静态IoC

本文关键字:静态 IoC Micro Caliburn 处理 | 更新日期: 2023-09-27 18:30:53

我需要在基于 Prism 的容器中托管多个模块(全部使用 Caliburn Micro 完成)。在容器中,可以从同一模块创建多个视图(例如:可以从计算器模块创建科学和财务计算器)。

我正在使用 Unity 进行 DI,因此在所有模块中覆盖了 Caliburn Micro 的引导程序以从 Unity 容器进行解析。

由于 CM 的 IoC 类是一个静态类,因此注册其依赖项的最后一个模块将覆盖(前一个) - 请参阅行 IoC.GetInstance = GetInstance。

我非常喜欢 Sniffer 建议的想法,但每个模块都会创建自己的子容器,因此它不适用于我的场景。

处理Caliburn Micro的静态IoC

我会提出一个我认为可行的解决方案。默认情况下,CM 在BootstrapperBase中分配IoC.GetInstance()和所有其他Func<>委托,如下所示:

IoC.GetInstance = this.GetInstance

其中this.GetInstance只是BootstrapperBase中虚拟和空的方法,因此您可以在自己的派生引导程序中覆盖它。

我尝试的解决方案:存储对已向IoC.GetInstance注册的内容的引用,并在新的GetInstance覆盖中调用它,并对IoC的其他两个静态Func<>执行此操作。

在引导程序的构造函数或Configure()方法中,为IoC中相互包装的静态Func<>委托提供钩子,如下所示:

public class CalculatorBootstrapper : BootstrapperBase {
    private Func<Type, string, object> _previousGet;     
    public override void Configure() {
        _previousGet = IoC.GetInstance; // store reference to whatever was stored previously
        IoC.GetInstance = this.GetInstance;
    }
    public override Object GetInstance(Type type, string key) {
        var result = null;
        if (_previousGet != null)
            result = _previousGet(type, key);
        if (result == null) {
            // Try to use the local container here
        }
        return result;
    }
}