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
devdigital是对的。 他说
它是另一个重要的bootstrapper配置。
这是完全正确的。
如果您打算使用DI ( SimpleContainer
为您做的那样),那么您必须在引导程序中覆盖 GetInstance(), GetAllInstances(), BuildUp()
方法,因为CM在需要容器中的内容时调用这些方法。
在你的情况下发生的是这样的:
- CM尝试显示您的
MainViewModel
因为您将其指定为Bootstrapper中的generics参数。 - CM注意到您的
MainViewModel
有一个带有IEventAggregator
构造IEventAggregator
。 - CM调用
GetInstance()
来获取注册为IEventAggregator
任何IEventAggregator
。 - CM发现你没有覆盖
GetInstance()
所以它尝试使用Activator.CreateInstance()
创建一个MainViewModel
实例。 -
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