10

是否可以将 Unity 配置为检测循环引用或拦截类型解析器以显示一些调试信息?

例子

这是几个相互依赖的接口和类

public interface IThing1 { }

public class Thing1 : IThing1
{
    private IThing2 _thing2;

    public Thing1(IThing2 thing2)
    {
        _thing2 = thing2;
    }

}

public interface IThing2 { }

public class Thing2 : IThing2
{
    private IThing1 _thing1;

    public Thing2(IThing1 thing1)
    {
        _thing1 = thing1;
    }
}

温莎城堡

如果在 Castle Windsor 中配置了这两种类型,它将抛出异常并提供一些调试信息以查找循环引用:

Castle.MicroKernel.CircularDependencyException: Dependency cycle has been detected when trying to resolve component 'CircularIoC.Thing1'.
The resolution tree that resulted in the cycle is the following:
Component 'CircularIoC.Thing1' resolved as dependency of
    component 'CircularIoC.Thing2' resolved as dependency of
    component 'CircularIoC.Thing1' which is the root component being resolved.

统一

如果 Unity 配置为像这样解析这些类型

    private static void ResolveWithUnity()
    {
        var container = new UnityContainer();

        container.RegisterType<IThing1, Thing1>();
        container.RegisterType<IThing2, Thing2>();

        var thing = container.Resolve<IThing1>();

        container.Dispose();
    }

对 container.Resolve<> 的调用将导致 StackOverflowException。

这是记录在案的行为,但如果有一些更有用的信息会很好。是否有任何定制可以提供有关循环引用的更多信息?

或者,有什么方法可以连接到类型解析器进程以发出一些调试信息?我正在考虑装饰主要类型解析器以输出正在解析的类型的名称。这将提供一些反馈和指向导致循环引用的依赖项的指针。

虽然我知道更改为不同的 IoC 可以解决问题,但不幸的是,这不是一个选择。

4

1 回答 1

1

遗憾的是,Unity 不支持这个(非常重要的)功能。如果您愿意投入其中,您可以使用一些肘部油脂来实现智能装饰器。

您需要的是覆盖所有注册方法并为依赖项(依赖图)构建和更新数据结构。然后编写一个执行DFS以检测循环依赖的方法,您可以将它用作注册过程的终结器,如果循环依赖是可能的,它将检测预解析,或者在每次解析时使用它来处理请求的特定类型。

如您所见,这是很多工作......

另一种选择,只是用装饰器包装解决方法并捕获StackOverflowException,对其进行分析以确保它是由解析过程产生的,并构建适当的循环依赖异常。

于 2014-12-21T12:58:53.687 回答