国际奥委会没有在Win7的/ XP初始化 [英] IoC is not initialized on Win7/XP

查看:180
本文介绍了国际奥委会没有在Win7的/ XP初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在面临一个很奇怪的问题,试图运行Win7上/ XP WPF应用程序。 WPF应用程序的目标。NET 4.0和它引用Caliburn.Micro 1.5.2和3.1.0 Autofac

I'm facing a quite strange problem trying to run a WPF application on Win7/XP. The WPF application targets .NET 4.0 and it references Caliburn.Micro 1.5.2 and Autofac 3.1.0.

我要开始对问题的总结,然后我想给什么我有这么远的细节。

I'm going to start with a summary of the problem and then I'm going to give details about what I've got so far.

概述

在我的开发工作站我的Windows 8和Visual Studio 2012年我使用的是卡利和Autofac中的这个帖子(中的这个)。

In my dev workstation I have Windows 8 and Visual Studio 2012. I'm using Caliburn and Autofac as described in this post (basically a simplified version of this).

当我建立在我开发计算机上运行的应用程序,一切按预期。然而,当我把二进制文件和在Windows 7 / XP的计算机上执行他们,我得到以下错误,有很长的堆栈跟踪:

When I build and run the application in my dev machine, everything goes as expected. However, when I take the binaries and execute them in a Windows 7/XP machine, I get the following error, with a long stacktrace:

System.InvalidOperationException: IoC is not initialized

唯一的区别我可以在环境之间看到(除了操作系统)是我的开发工作站有.NET 4.5,而Win7的/ XP的人有.NET 4.0。

详情

我可以用一个简单的应用程序重现该问题。解决办法:

I was able to reproduce the issue with a simple application. The solution:

ShellViewModel 只是一个空的指挥<网> ShellView 刚一的TextBlock

ShellViewModel is just a empty Conductor<Screen>. ShellView has just a TextBlock.

的App.xaml 如下卡利recomendations:

The App.xaml follows Caliburn recomendations:

<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 code的修改,以捕捉和显示异常:

The App.xaml.cs code was modified to catch and show exceptions:

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());
    }
}

有趣的部分是引导程序。作为一个说,我有一个应用程序启动和卡利和Autofac一起合作了引导程序类似描述的此处。对于这个例子,我创建了一个简化版本:

The fun part is the Bootstrapper. As a said, I have an app up and running with Caliburn and Autofac working together with a Bootstrapper similar to the one described here. For the example, I created a simplified version:

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();
    }
}

在我的工作站,它运行得很好:

In my workstation, it runs just fine:

我已经把一些断点在引导程序的GetInstance 的方法和他们正在正确地打。

I've put some breakpoints in the Bootstrapper's GetInstance methods and they are being correctly hit.

然后,我把二进制文件(斌/调试),并试图在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, Object args, 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, ContextCallback callback, Object state, Boolean ignoreSyncCtx)

   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, 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, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)

   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)

   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)

   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

   at MS.Win32.UnsafeNativeMethods.MessageBox(HandleRef hWnd, String text, String caption, Int32 type)

   at System.Windows.MessageBox.ShowCore(IntPtr owner, String messageBoxText, String caption, 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

这消息apparentely是调用的IoC 初始化之前上课的时候​​,因为我们可以看到的卡利的源。但是,的IoC 引导程序的号召,配置。请参阅 BootstrapperBase.StartRuntime 在<方法href="http://caliburnmicro.$c$cplex.com/SourceControl/latest#src/Caliburn.Micro.Silverlight/Bootstrapper.cs"相对=nofollow>来源。

That message apparentely is the expected behavior when calling the IoC class before its initialization, as we can see in Caliburn's source. However, the IoC is correctly initialized right after the Bootstrapper's call to Configure. See BootstrapperBase.StartRuntime method in the source.

如果我删除所有的依赖注入逻辑的引导程序,该应用程序在Win XP运行正常/ 7。

我花了一段时间试图找到究竟是触发此行为。我删除一切从引导程序和一些尝试后,以下是所有需要触发的问题:

I spent sometime trying to find what exactly was triggering this behavior. I removed everything from the Bootstrapper and after some attempts, the following is all it takes to trigger the problem:

public class Bootstrapper : Bootstrapper<ShellViewModel>
{
    protected override void Configure()
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<ShellViewModel>();
    }
}

如果我评论该行 builder.RegisterType&LT; ShellViewModel&GT;(); ,应用程序的作品

If I comment the line builder.RegisterType<ShellViewModel>();, the app works.

结论:在Autofac ContainerBuilder注册什么的简单的动作触发的行为。我甚至都不需要使用它。我是由完全摸不着头脑。

Conclusion: the simple act of registering anything in an Autofac ContainerBuilder triggers the behaviors. I don't even need to use it. I'm totally puzzled by that.

我在这个问题上花了几个小时。我真的想用卡利和Autofac,因为我喜欢他们两个。如果任何人都可以揭示一些关于它的光,我AP preciate。

I've spent hours on this problem. I really want to use Caliburn and Autofac, because I like them both. If anyone could shed some light on it, I'd appreciate.

更新

我发现,如果我打个电话,在Bootstrapper.Configure方法的MessageBox.show观察到的行为(国际奥委会未初始化)会发生,即使与VS2012在我的Win8调试:

I've noticed that if I make a call to MessageBox.Show in the Bootstrapper.Configure method the observed behavior ("IoC is not initialized") will happen even debugging with VS2012 in my Win8:

public class Bootstrapper : Bootstrapper<ShellViewModel>
{
    protected override void Configure()
    {
        MessageBox.Show("Configure");
    }
}

我在想这件事,但我还不知道这意味着什么。

I'm thinking about it, but I don't know yet what it means.

更新

链接示例应用程序。

更新

分析观察到的行为之后,我得出的结论(如嗅探器一样)的的事业国际奥委会没有初始化的错误是不依赖注入,但调用的MessageBox。展引导程序的启动。

After analysing the observed behaviors, I came to the conclusion (as Sniffer did) that the cause of the "IoC is not initialized" error is not the dependency injection, but calling MessageBox.Show before the Bootstrapper's startup.

我改变了的MessageBox.show 来NLOG的日志程序编写错误的文件,并与我能够追查真正的例外。 真正的问题来自于这Autofac针对PCL的事实,并为它运行还好吧与.NET 4.0客户端配置文件,我需要<一个href="http://stackoverflow.com/questions/13871267/unable-to-resolve-assemblies-that-use-portable-class-libraries">install在目标机器更新4.0.3。

I changed the MessageBox.Show to NLog's logging routines to write errors to a file, and with that I was able track down the real exception. The real problem comes from the fact that Autofac targets PCL and for it to run allright with .NET 4.0 Client Profile, I need to install the update 4.0.3 in target machine.

不过,把原来的问题不谈,其实也有与卡利的一个问题。引导程序的初始化之前调用的MessageBox.show似乎触发了一个全新的应用程序启动过程中,国际奥委会配置之间发生,产生观测到的异常。

However, putting the original problem aside, there is in fact a problem with Caliburn. Calling MessageBox.Show before the Bootstrapper's initialization seems to trigger a whole new Application start process that happens between the IoC configuration, generating the observed exception.

我认为目前的问题已经从它的初衷背离,我认为它应该关闭。我将创建一个新的问题为目标的Caliburn.Micro问题不会影响我的具体应用的问题的环境。

I believe the current question has deviated from its original purpose and I think it should be closed. I will create a new question that targets the Caliburn.Micro problem in a environment not affected by my specific application's problems.

推荐答案

嗯,我跑你code在我的XP的机器,并与你最近更新有问题,你使用了一个消息框类,它使你在你的Windows 8设备的问题,但如果你创建一个新的容器并注册previous code中的 ShellViewModel 你所说的造成你的Win 7 / XP的计算机上的问题做的不可以的原因我任何问题的(它编译并运行正常)的。

Well i ran your code on my XP machine and had a problem with your last update, the one where you used the MessageBox class and it caused you issues on your windows 8 machine, but the previous code where you create a new container and register the ShellViewModel which you said caused problems on your win 7/xp machine did not cause me any problems (it compiled and ran OK).

现在我想知道,为什么使用的MessageBox.show()配置方法中的方法导致的异常样的,我想通了其中的原因,并将其归结为:

Now i was wondering why using the MessageBox.Show() method inside the Configure method is causing that exception and i kind of figured out the reason for that and it boils down to this:

  1. Caliburn.Micro的(CM从这里经过)引导程序&LT; TRootModel&GT; 构造函数调用开始()
  2. 开始()呼吁 StartRuntime()
  3. StartRuntime()呼吁,在这种特定的顺序:配置()然后 IoC.Get =的GetInstance 然后 IoC.GetAllInstances = GetAllInstances; 然后 IoC.BuildUp =堆积;
  4. StartRuntime()电话配置()您code被执行,特别是的MessageBox.show()这是一个系统函数,它的需要 (必须的),每一个消息框有一个所有者窗口,默认情况下,所有者你当前活动的应用程序窗口。
  5. 现在,在这个阶段一块系统code运行时,我不知道是什么正在运行,但由系统执行的一块code调用的 OnStartup ()方法重写该CM不覆盖的引导程序,并用它来显示视图的 TRootModel 您选择的。
  6. 在为了卡利显示视图的 TRootModel 需要 IWindowManager 的实例,来获取它使用的(你理解了它)的我们敬爱的的IoC 正如你从步骤3号看到,它拥有的不可以初始化的是,它仍然停留在那个配置()的方法,并没有继续前进。
  1. Caliburn.Micro's (CM from here after) Bootstrapper<TRootModel> constructor is calling Start()
  2. Start() is calling StartRuntime()
  3. StartRuntime() is calling and in this particular order: Configure() then IoC.Get = GetInstance and then IoC.GetAllInstances = GetAllInstances; and then IoC.BuildUp = BuildUp;
  4. When StartRuntime() calls Configure() your code is executed, specifically MessageBox.Show() which is a system function that requires ( a must ) that every message box have an owner window and the owner by default is your current active application window.
  5. Now at this stage a piece of system code is run, i don't know what is being run but the piece of code that is executed by the system calls the OnStartup() method override which CM does override in the bootstrapper and uses it to show the view for the TRootModel of your choosing.
  6. In order for Caliburn to show the view for that TRootModel it needs an instance of IWindowManager and to get that it uses ( you figured it out ) our beloved IoC which as you see from step number 3, it has not initialized yet, it still stuck on that Configure() method and hasn't moved on.

摘要:的code与容器的配置可以与我的Win XP的机器没有任何问题,但在code与的MessageBox.show()方法在配置()覆盖的,然后我给你的原因的详细说明。

Summary: The code with the container configuration works with no problems on my Win XP machine but the code with the MessageBox.Show() method in the Configure() override does not and i gave you a detailed explanation of the reason.

这篇关于国际奥委会没有在Win7的/ XP初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆