当我在XBAP(WPF浏览器)应用程序中使用Ninject和任何扩展时,我得到Stack Overflow异常(小双关语)。
这是堆栈跟踪。它相当大,但很完整(这就是为什么我把它贴在pastebin上):
我正在尝试使用Ninject的约定和工厂扩展。如果我引用任何一个的汇编,我会得到堆栈溢出异常。所以要明确的是,当我删除对两个库的引用时,应用程序运行正确。
这真的很奇怪,因为Ninject似乎正在创建新的AppDomain,但CLR显然试图加载进入/执行程序集(我的解决方案中唯一的一个)并执行它。这显然会导致堆栈溢出异常。
我也在使用 Caliburn.Micro ,还有其他库: Caliburn.Micro.Contrib , Caliburn.Micro.Extras (沿着与他们的依赖关系) - 所有最新版本。
有没有人有想法,是什么原因以及如何解决?
答案 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
不知道这是否会在以后引起任何问题。到目前为止,我认为这段代码需要完全信任,因为它访问私有字段(并设置其值)。