end*_*der 11 c# dependency-injection eventaggregator caliburn.micro
我学习卡利微并尝试使用的EventAggregator从官方网站.
但是,我有一个例外
"没有为此对象定义无参数构造函数."
消息本身很清楚,但示例中也没有包含无参数构造函数.如果我添加一个,带有参数的构造函数不会被命中,IEventAggregator仍然没有正确注入.
添加无参数构造函数后,这是我的发布者VM(没有它,将抛出异常):
public MainViewModel() { }
public MainViewModel(IEventAggregator ea) : this()
{
eventAggregator = ea;
}
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的引导程序:
public class AppBootstrapper : Bootstrapper<MainViewModel>
{
private readonly SimpleContainer container = new SimpleContainer();
protected override void Configure()
{
container.Singleton<IEventAggregator, EventAggregator>();
}
}
Run Code Online (Sandbox Code Playgroud)
这是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<IEventAggregator, EventAggregator>();
}
// ... Other Bootstrapper Config
}
// Acquiring the EventAggregator in a viewModel.
public class FooViewModel {
private readonly IEventAggregator _eventAggregator;
public FooViewModel(IEventAggregator eventAggregator) {
_eventAggregator = eventAggregator;
}
}
Run Code Online (Sandbox Code Playgroud)
我检查了这篇文章(用Caliburn Micro将EventAggregator注入ViewModel),但它简单地说没有为什么CM不用注入调用构造函数.
我还检查了CM的样品溶液,但它使用MEF作为DI溶液.
我错过了什么?
// ... Other Bootstrapper Config
Run Code Online (Sandbox Code Playgroud)
这是另一个重要的bootstrapper配置.
最好的选择是通过Caliburn.Micro.Start NuGet包安装Caliburn.Micro ,并查看提供的引导程序,它也使用SimpleContainerCaliburn.Micro提供的.
这里是完整的:
public class AppBootstrapper : BootstrapperBase
{
SimpleContainer container;
public AppBootstrapper()
{
Start();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, WindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<IShell, ShellViewModel>();
}
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<object> 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<IShell>();
}
}
Run Code Online (Sandbox Code Playgroud)
devdigital是正确的.他说
它是另一个重要的bootstrapper配置.
这是完全正确的.
如果您打算使用DI (SimpleContainer适合您),那么您必须覆盖GetInstance(), GetAllInstances(), BuildUp()引导程序中的方法,因为CM在需要容器中的某些内容时会调用这些方法.
在你的情况下发生的是这样的:
MainViewModel因为您将其指定为Bootstrapper中的泛型参数.MainViewModel有一个构造函数需要一个IEventAggregator.GetInstance()获取注册的任何内容IEventAggregator.GetInstance()所以它试图创建一个MainViewModel使用的实例Activator.CreateInstance().Activator.CreateInstance()不知道如何创建一个IEventAggregator如此它抛出异常(你得到的那个).要解决所有这些问题,你必须覆盖我告诉你的方法.您不需要安装Nuget Caliburn.Start软件包(如果您不喜欢打字并且想要保存一些按键,则可以使用它).
基本上你的最终解决方案应如下所示:
public class Bootstrapper : Bootstrapper<MainViewModel>
{
private readonly SimpleContainer _container = new SimpleContainer();
protected override void Configure()
{
_container.Instance<IWindowManager>(new WindowManager());
_container.Singleton<IEventAggregator, EventAggregator>();
_container.PerRequest<MainViewModel>();
}
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5507 次 |
| 最近记录: |