我将从问题摘要开始,然后我将详细介绍我到目前为止所得到的内容.
概述
在我的开发工作站中,我有Windows 8和Visual Studio 2012.我正在使用Caliburn和autofac,如this post所述(基本上是this的简化版本).
当我在我的开发机器中构建并运行应用程序时,一切都按预期进行.但是,当我获取二进制文件并在windows 7 / XP机器中执行它时,我得到以下错误,带有长堆栈跟踪:
system.invalIDOperationException: IoC is not initialized
我可以在环境(除OS之外)看到的唯一区别是我的开发工作站有.NET 4.5,而Win7 / XP有.NET 4.0.
细节
我能用一个简单的应用程序重现这个问题.解决方案:
Shellviewmodel只是一个空导体< Screen>. ShellVIEw只有一个TextBlock.
App.xaml遵循Caliburn的推荐:
<Application x:Class="WpfApplication2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication2"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionarIEs> <ResourceDictionary> <local:bootstrapper x:Key="bootstrapper" /> </ResourceDictionary> </ResourceDictionary.MergedDictionarIEs> </ResourceDictionary> </Application.Resources></Application>
App.xaml.cs代码已修改为捕获并显示异常:
public partial class App : Application{ public App () { // hook on error before app really starts AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); try { this.InitializeComponent(); } catch (Exception e) { MessageBox.Show(e.ToString()); throw; } } public static voID CurrentDomain_UnhandledException(object sender,UnhandledExceptionEventArgs e) { MessageBox.Show(((Exception)e.ExceptionObject).ToString()); }}
有趣的部分是bootstrapper.如上所述,我有一个应用程序,并与Caliburn和autofac一起运行,与一个类似于此处描述的bootstrapper一起工作.例如,我创建了一个简化版本:
public class bootstrapper : bootstrapper<Shellviewmodel>{ private IContainer container; protected IContainer Container { get { return this.container; } } protected overrIDe object GetInstance(Type serviceType,string key) { if (string.IsNullOrWhiteSpace(key)) { if (container.IsRegistered(serviceType)) return container.Resolve(serviceType); } else { if (container.IsRegistereDWithname(key,serviceType)) container.Resolvenamed(key,serviceType); } throw new Exception(string.Format("Could not locate any instances of contract {0}.",key ?? serviceType.name)); } protected overrIDe IEnumerable<object> GetAllinstances(Type serviceType) { return this.Container.Resolve(typeof(IEnumerable<>).MakeGenericType(serviceType)) as IEnumerable<object>; } protected overrIDe voID BuildUp(object instance) { this.Container.InjectPropertIEs(instance); } protected overrIDe voID Configure() { var builder = new ContainerBuilder(); builder.RegisterType<Shellviewmodel>(); builder.RegisterassemblyTypes(this.GetType().Assembly); builder.RegisterType<WindowManager>() .As<IWindowManager>() .SingleInstance(); builder.RegisterType<EventAggregator>() .As<IEventAggregator>() .SingleInstance(); this.container = builder.Build(); }}
在我的工作站中,它运行得很好:
我在bootstrapper的GetInstance方法中加入了一些断点,它们被正确命中.
然后,我拿了二进制文件(bin / DeBUG)并尝试在windows XP / 7虚拟机中运行它们.该应用程序无法启动,我得到以下异常:
system.invalIDOperationException: IoC is not initialized. at Caliburn.Micro.IoC.<.cctor>b__0(Type service,String key) in c:\Users\Rob\documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 13 at Caliburn.Micro.IoC.Get[T](String key) in c:\Users\Rob\documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 32 at Caliburn.Micro.bootstrapperBase.displayRootVIEwFor(Type viewmodelType,IDictionary`2 settings) in c:\Users\Rob\documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\bootstrapper.cs:line 254 at Caliburn.Micro.bootstrapperBase.displayRootVIEwFor[Tviewmodel](IDictionary`2 settings) in c:\Users\Rob\documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\bootstrapper.cs:line 264 at Caliburn.Micro.bootstrapper`1.OnStartup(Object sender,StartupEventArgs e) in c:\Users\Rob\documents\CodePlex\caliburnmicro\src\Caliburn.Micro.Silverlight\bootstrapper.cs:line 288 at System.windows.Application.OnStartup(StartupEventArgs e) at System.windows.Application.<.ctor>b__1(Object unused) at System.windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback,Object args,Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source,Delegate method,Int32 numArgs,Delegate catchHandler) at System.windows.Threading.dispatcherOperation.InvokeImpl() at System.windows.Threading.dispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code,CleanupCode backoutCode,Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state,Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state) at System.windows.Threading.dispatcherOperation.Invoke() at System.windows.Threading.dispatcher.ProcessQueue() at System.windows.Threading.dispatcher.WndProcHook(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean& handled) at MS.Win32.HwnDWrapper.WndProc(IntPtr hwnd,Boolean& handled) at MS.Win32.HwndSubclass.dispatcherCallbackOperation(Object o) at System.windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback,Delegate catchHandler) at System.windows.Threading.dispatcher.InvokeImpl(dispatcherPriority priority,TimeSpan timeout,Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,IntPtr lParam) at MS.Win32.UnsafeNativeMethods.MessageBox(HandleRef hWnd,String text,String caption,Int32 type) at System.windows.MessageBox.ShowCore(IntPtr owner,String messageBoxText,MessageBoxbutton button,MessageBoxImage icon,MessageBoxResult defaultResult,MessageBoxOptions options) at System.windows.MessageBox.Show(String messageBoxText) at WpfApplication2.App..ctor() in c:\Users\Public\Projetos\Outros\WpfApplication3\WpfApplication2\App.xaml.cs:line 27 at WpfApplication2.App.Main() in c:\Users\Public\Projetos\Outros\WpfApplication3\WpfApplication2\obj\DeBUG\App.g.cs:line 0
该消息显然是在初始化之前调用IoC类时的预期行为,如我们在Caliburn’s source中所见.但是,在bootstrapper调用Configure之后,IoC正确初始化.请参阅the source中的bootstrapperBase.StartRuntime方法.
如果我从bootstrapper中删除所有依赖注入逻辑,该应用程序在Win XP / 7上运行正常.
我花了一些时间试图找到究竟是什么触发了这种行为.我从bootstrapper中删除了所有内容,经过一些尝试,以下是触发问题所需的全部内容:
public class bootstrapper : bootstrapper<Shellviewmodel>{ protected overrIDe voID Configure() { var builder = new ContainerBuilder(); builder.RegisterType<Shellviewmodel>(); }}
如果我注释行builder.RegisterType< Shellviewmodel>();,该应用程序可以正常工作.
结论:在autofac ContainerBuilder中注册任何内容的简单 *** 作会触发行为.我甚至不需要使用它.我对此完全感到困惑.
我花了好几个小时来解决这个问题.我真的很想使用Caliburn和autofac,因为我喜欢它们.如果有人能说清楚它,我会很感激.
UPDATE
我注意到如果我在bootstrapper.Configure方法中调用MessageBox.Show,即使在我的Win8中使用VS2012进行调试,也会发生观察到的行为(“IoC未初始化”):
public class bootstrapper : bootstrapper<Shellviewmodel>{ protected overrIDe voID Configure() { MessageBox.Show("Configure"); }}
我正在考虑它,但我还不知道它意味着什么.
UPDATE
Link for the sample application.
UPDATE
在分析观察到的行为之后,我得出结论(正如Sniffer所做的那样)“IoC未初始化”错误的原因不是依赖注入,而是在bootstrapper启动之前调用MessageBox.Show.
我将MessageBox.Show更改为NLog的日志记录例程,将错误写入文件,然后我就能找到真正的异常.真正的问题来自于autofac针对PCL以及它与.NET 4.0 ClIEnt Profile一起运行的事实,我需要install the update 4.0.3 in target machine.
然而,抛开原来的问题,Caliburn实际上存在问题.在bootstrapper初始化之前调用MessageBox.Show似乎会触发在IoC配置之间发生的全新Application启动过程,从而生成观察到的异常.
我认为目前的问题偏离了原来的目的,我认为它应该是封闭的.我将在不受特定应用程序问题影响的环境中创建一个针对Caliburn.Micro问题的新问题.
解决方法 好吧,我在我的XP机器上运行你的代码并且你的上次更新有问题,你使用MessageBox类的那个,它导致你的windows 8机器上出现问题,但是前面的代码,你创建一个新容器并注册你说的Shellviewmodel在你的win 7 / xp机器上引起了问题并没有给我带来任何问题(编译并运行正常).现在我想知道为什么在Configure方法中使用MessageBox.Show()方法导致该异常,我想出了原因,并归结为:
> Caliburn.Micro(后来的CM)bootstrapper< TRootModel>构造函数调用Start()
> Start()调用StartRuntime()
> StartRuntime()按以下特定顺序调用:Configure()然后是IoC.Get = GetInstance,然后是IoC.GetAllinstances = GetAllinstances;然后IoC.BuildUp = BuildUp;
>当StartRuntime()调用Configure()时,你的代码被执行,特别是MessageBox.Show(),这是一个系统函数,它需要(必须)每个消息框都有一个所有者窗口,默认情况下所有者是你当前的活动应用程序窗口.
>现在在这个阶段运行一段系统代码,我不知道正在运行什么,但系统执行的代码调用OnStartup()方法覆盖CM在引导程序中覆盖并使用它显示您选择的TRootModel的视图.
>为了让Caliburn显示该TRootModel的视图,它需要一个IWindowManager的实例,并且它使用(你想通了)我们心爱的IoC,正如你从步骤3中看到的那样,它还没有初始化,它仍然卡在那个Configure()方法上并且没有继续前进.
简介:具有容器配置的代码在我的Win XP机器上没有问题,但配置()覆盖中的MessageBox.Show()方法的代码没有,我给你详细解释了原因.
@H_404_116@ 总结以上是内存溢出为你收集整理的c# – IoC未在Win7 / XP上初始化全部内容,希望文章能够帮你解决c# – IoC未在Win7 / XP上初始化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)