【问题标题】:NullReferenceException in Caliburn.Micro's DisplayRootViewFor method when trying to use EventAggregator尝试使用 EventAggregator 时,Caliburn.Micro 的 DisplayRootViewFor 方法中出现 NullReferenceException
【发布时间】:2017-09-01 04:34:34
【问题描述】:

我正在尝试在我的 WPF 项目中使用 Caliburn Micro 的内置 EventAggregator,基于 this documentation。但是文档(我几乎总是在 Caliburn Micro 中找到它)似乎不完整,即示例代码不包含所有实现要求。

特别是,我没有在我的项目中使用 IoC 容器,我确定我丢失或误用了它的某些配置,这就是问题的根源。

问题:

  • 我在启动时在DisplayRootViewFor 方法中得到NullReferenceException
  • 我显然知道NullReferenceException 一般是什么,但我想知道如何解决这个与 Caliburn Micro 的应用程序引导程序配置相关的问题(并帮助其他在尝试做时可能遇到相同问题的用户同样的事情)。

注意事项:

  • 诚然,我不清楚应用引导程序是如何工作的,因为我总是发现 Caliburn Micro 的文档很难理解(与 MSDN 相比),而且我之前没有使用过 IoC 容器。
  • NullReferenceException 连接到GetInstance 覆盖方法,如果我将其注释掉,我得到“No parameterless constructor defined for this object”异常。
  • 我已经尝试了in this question 的解决方案,但似乎没有任何区别。

有人可以向我解释为什么 Caliburn.Micro 会抛出此异常,以及我应该如何将 EventAggregator 注入我的主视图模型?(因为试图将其作为参数传递在DisplayRootViewFor 中似乎不起作用。)


我的应用引导程序如下所示 - 基于 The Event AggregatorSimple IoC Container 文档页面的组合:

public class AppBootstrapper : BootstrapperBase
{
    private readonly SimpleContainer _container =
        new SimpleContainer();

    public AppBootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        _container.Singleton<IEventAggregator, EventAggregator>();
    }

    protected override object GetInstance(Type serviceType, string key)
    {
        return _container.GetInstance(serviceType, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return _container.GetAllInstances(serviceType);
    }

    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewFor<MainViewModel>();
    } 
}

我的MainViewModel 的构造函数如下所示——设置为注入EventAggregator

public MainViewModel(IEventAggregator eventAggregator)
{
    _eventAggregator = eventAggregator;
}

【问题讨论】:

    标签: c# wpf ioc-container caliburn.micro


    【解决方案1】:

    使用RegisterPerRequest 注册视图模型类型本身。试试这个:

    public class HelloBootstrapper : BootstrapperBase
    {
        private readonly SimpleContainer _container = new SimpleContainer();
        public HelloBootstrapper()
        {
            Initialize();
        }
    
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            base.OnStartup(sender, e);
            DisplayRootViewFor<MainViewModel>();
        }
    
        protected override void Configure()
        {
            _container.Singleton<IWindowManager, WindowManager>();
            _container.Singleton<IEventAggregator, EventAggregator>();
            _container.RegisterPerRequest(typeof(MainViewModel), null, typeof(MainViewModel));
        }
    
        protected override object GetInstance(Type serviceType, string key)
        {
            return _container.GetInstance(serviceType, key);
        }
    
        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
            return _container.GetAllInstances(serviceType);
        }
    
        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }
    }
    

    【讨论】:

    • 你又拯救了我的一天! :) 谢谢。我会确保阅读 RegisterPerRequest 以了解发生了什么。
    【解决方案2】:

    另外,注册每个 ViewModel 的代码也对我有用

    公共类 BootStrapper : BootstrapperBase {

        protected SimpleContainer _container = new SimpleContainer();
        public BootStrapper()
        {
            Initialize();
        }
    
        protected override void Configure()
        {
            _container.Instance(_container);
            _container
                .Singleton<IWindowManager, WindowManager>()
                .Singleton<IEventAggregator, EventAggregator>();
    
            GetType().Assembly.GetTypes()
                .Where(type => type.IsClass)
                .Where(type => type.Name.EndsWith("ViewModel"))
                .ToList()
                .ForEach(viewModelType => _container.RegisterPerRequest(
                    viewModelType, viewModelType.ToString(), viewModelType));
        }
    
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor<ShellViewModel>();
        }
    
        protected override object GetInstance(Type service, string key)
        {
            return _container.GetInstance(service, key);
    
        }
    
        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return _container.GetAllInstances(service);
        }
    
        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      相关资源
      最近更新 更多