使用Ninject在XBAP应用程序中堆栈溢出

时间:2013-12-27 21:55:34

标签: c# wpf ninject xbap ninject-extensions

当我在XBAP(WPF浏览器)应用程序中使用Ninject和任何扩展时,我得到Stack Overflow异常(小双关语)。

这是堆栈跟踪。它相当大,但很完整(这就是为什么我把它贴在pastebin上):

http://pastebin.com/su9M1c7V

我正在尝试使用Ninject的约定和工厂扩展。如果我引用任何一个的汇编,我会得到堆栈溢出异常。所以要明确的是,当我删除对两个库的引用时,应用程序运行正确。

这真的很奇怪,因为Ninject似乎正在创建新的AppDomain,但CLR显然试图加载进入/执行程序集(我的解决方案中唯一的一个)并执行它。这显然会导致堆栈溢出异常。

我也在使用 Caliburn.Micro ,还有其他库: Caliburn.Micro.Contrib Caliburn.Micro.Extras (沿着与他们的依赖关系) - 所有最新版本。

有没有人有想法,是什么原因以及如何解决?

1 个答案:

答案 0 :(得分:1)

在摆弄AppDomains之后,我发现Ninject与此无关。

(以下是一个详尽的解释,解决方案/解决方法在答案的最后)

Ninject在AppDomain中创建单独的AssemblyNameRetriever以检索程序集名称。就我而言,这些程序集是Ninject扩展:

private static AppDomain CreateTemporaryAppDomain()
{
    return AppDomain.CreateDomain(
        "NinjectModuleLoader",
        AppDomain.CurrentDomain.Evidence,
        AppDomain.CurrentDomain.SetupInformation);
}

问题在于AppDomainSetup属性中存储的对象AppDomain.CurrentDomain.SetupInformation。它将ActivationArguments属性设置为ActivationArguments类的实例,其中包含导致条目程序集执行的信息(这很好,因为XBAP应用程序必须以某种方式启动)。

但是,由于Ninject使用相同的设置信息,因此会导致无限递归,从而导致我们最喜欢的 StackOverflow 异常。

解决方法是将属性ActivationArguments设置为null。但是,AppDomain类会在AppDomainSetup属性getter中创建SetupInformation对象的副本。因此,有必要获取AppDomainSetup对象的副本,将ActivationArguments设置为null并通过反射设置值_FusionStore字段{{1这个对象的类。

<强> TL; DR : 在创建Ninject内核之前,我们必须调用此代码:

AppDomain

不知道这是否会在以后引起任何问题。到目前为止,我认为这段代码需要完全信任,因为它访问私有字段(并设置其值)。