Caliburn Micro构造函数注入失败

我正在学习Caliburn Micro并尝试使用官方网站上的EventAggregator

但是,我得到了一个例外

“没有为此对象定义无参数构造函数。”

消息本身很清楚,但示例中也没有包含无参数构造函数。 如果我添加一个,带有参数的构造函数不会被命中, IEventAggregator仍未正确注入。

添加无参数构造函数后,这是我的发布者VM(没有它,将抛出exception):

  public MainViewModel() { } public MainViewModel(IEventAggregator ea) : this() { eventAggregator = ea; } 

这是我正在使用的引导程序:

 public class AppBootstrapper : Bootstrapper { private readonly SimpleContainer container = new SimpleContainer(); protected override void Configure() { container.Singleton(); } } 

这是CM的例子:

 // Creating the EventAggregator as a singleton. public class Bootstrapper : BootstrapperBase { private readonly SimpleContainer _container = new SimpleContainer(); // ... Other Bootstrapper Config protected override void Configure(){ _container.Singleton(); } // ... Other Bootstrapper Config } // Acquiring the EventAggregator in a viewModel. public class FooViewModel { private readonly IEventAggregator _eventAggregator; public FooViewModel(IEventAggregator eventAggregator) { _eventAggregator = eventAggregator; } } 

我检查了这篇文章( 用Caliburn Micro将EventAggregator注入ViewModel ),但它简单地说没有为什么CM不用注入调用构造函数。

我还检查了CM的样品溶液,但它使用MEF作为DI溶液。

我错过了什么?

 // ... Other Bootstrapper Config 

这是另一个重要的bootstrapper配置。

最好的选择是通过Caliburn.Micro.Start NuGet包安装Caliburn.Micro,并查看提供的bootstrapper,它也使用Caliburn.Micro提供的SimpleContainer

在这里它是完整的:

 public class AppBootstrapper : BootstrapperBase { SimpleContainer container; public AppBootstrapper() { Start(); } protected override void Configure() { container = new SimpleContainer(); container.Singleton(); container.Singleton(); container.PerRequest(); } protected override object GetInstance(Type service, string key) { var instance = container.GetInstance(service, key); if (instance != null) return instance; throw new InvalidOperationException("Could not locate any instances."); } protected override IEnumerable GetAllInstances(Type service) { return container.GetAllInstances(service); } protected override void BuildUp(object instance) { container.BuildUp(instance); } protected override void OnStartup(object sender, System.Windows.StartupEventArgs e) { DisplayRootViewFor(); } } 

devdigital是对的。 他说

它是另一个重要的bootstrapper配置。

这是完全正确的。

如果您打算使用DI SimpleContainer为您做的那样),那么您必须在引导程序中覆盖 GetInstance(), GetAllInstances(), BuildUp()方法,因为CM在需要容器中的内容时调用这些方法。

在你的情况下发生的是这样的:

  1. CM尝试显示您的MainViewModel因为您将其指定为Bootstrapper中的generics参数。
  2. CM注意到您的MainViewModel有一个带有IEventAggregator构造IEventAggregator
  3. CM调用GetInstance()来获取注册为IEventAggregator任何IEventAggregator
  4. CM发现你没有覆盖GetInstance()所以它尝试使用Activator.CreateInstance()创建一个MainViewModel实例。
  5. Activator.CreateInstance()不知道如何创建一个IEventAggregator因此它抛出一个exception(你得到的exception

要解决所有这些问题,你必须覆盖我告诉你的方法。 您不需要安装Nuget Caliburn.Start软件包(如果您不喜欢打字并且想保存一些按键,则可以使用它)

基本上你的最终解决方案应如下所示:

 public class Bootstrapper : Bootstrapper { private readonly SimpleContainer _container = new SimpleContainer(); protected override void Configure() { _container.Instance(new WindowManager()); _container.Singleton(); _container.PerRequest(); } protected override object GetInstance(Type service, string key) { return _container.GetInstance(service, key); } protected override IEnumerable GetAllInstances(Type service) { return _container.GetAllInstances(service); } protected override void BuildUp(object instance) { _container.BuildUp(instance); } }