C# 为什么我的Autofac注册的Prism EventAggregator未正确注入viewmodel?
在我的解决方案中,我使用了自动传真,以及棱镜。下面是一个简单的项目,解释了发生了什么 我正在Autofac的容器类中注册我的视图、视图模型和C# 为什么我的Autofac注册的Prism EventAggregator未正确注入viewmodel?,c#,wpf,mvvm,prism,autofac,C#,Wpf,Mvvm,Prism,Autofac,在我的解决方案中,我使用了自动传真,以及棱镜。下面是一个简单的项目,解释了发生了什么 我正在Autofac的容器类中注册我的视图、视图模型和EventAggregator,如下所示: public class BootStrapper { public IContainer BootStrap() { var builder = new ContainerBuilder();
EventAggregator
,如下所示:
public class BootStrapper
{
public IContainer BootStrap()
{
var builder = new ContainerBuilder();
builder.RegisterType<EventAggregator>()
.As<IEventAggregator>().SingleInstance();
builder.RegisterType<MainWindow>().AsSelf();
builder.RegisterType<ChildView1>().AsSelf();
builder.RegisterType<MainViewModel>().AsSelf();
builder.RegisterType<Child1ViewModel>().AsSelf();
return builder.Build();
}
}
public class MainViewModel
{
private IEventAggregator _eventAggregator;
public MainViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
UpdateName("Name1");
}
public void UpdateName(string name)
{
ChildView1 win1 = new ChildView1(); //in the backend Child1ViewModel is assigend to its DataContext
win1.Show();
_eventAggregator.GetEvent<UpdateNameEvent>().Publish(name); //this does not work
}
}
上面的代码不起作用。由于某种原因(我希望您能告诉我原因),在执行UpdateName
方法时,此依赖项不起作用,并且Child1ViewModel类UpdateName
方法内部未执行:
public class Child1ViewModel : ViewModelBase
{
private IEventAggregator _eventAggregator;
public Child1ViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged();
}
}
private void UpdateName(string name)
{
this.Name = name; //debug does not hit this code line
}
}
我怀疑在Autofac中注册聚合器有问题,但我不知道问题出在哪里,我只是根据我发现的odl示例使用它
解析Child1ViewModel和MainViewModel:
public partial class ChildView1 : Window
{
public ChildView1()
{
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
Child1ViewModel vm = container.Resolve<Child1ViewModel>();
InitializeComponent();
DataContext = vm;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
MainViewModel vm = container.Resolve<MainViewModel>();
InitializeComponent();
DataContext = vm;
}
}
public部分类childview 1:窗口
{
公共儿童视图1()
{
var bootStrapper=new bootStrapper();
var container=bootStrapper.BootStrap();
Child1ViewModel vm=container.Resolve();
初始化组件();
DataContext=vm;
}
}
公共部分类主窗口:窗口
{
公共主窗口()
{
var bootStrapper=new bootStrapper();
var container=bootStrapper.BootStrap();
MainViewModel vm=container.Resolve();
初始化组件();
DataContext=vm;
}
}
我假设您使用的是Prism的ViewModelLocator机制。我的假设是,您正在手动实例化ChildView1,而不是使用依赖项注入容器来解析它,并在注释中声明viewModel是在后台解析的
必须更改用于解析ViewModel实例的Prism ViewModelLocator的容器,如下所示
ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType)=>
{
返回AutoFacContainer.Resolve();
});
有关更多信息,请参阅
请记住,为了使对象实例的单实例生存期范围在整个应用程序中保持一致,必须使用相同的依赖项注入容器实例来解析对象和此对象的父对象,直至根对象。我使用Autofac IoC,每个VM在每个视图后端解析,要分配DataContext,能否显示解析MainViewModel和Child1ViewModel的代码?顺便说一句,如果实用程序类实际上是应用程序的一部分,而不是用来证明你的观点的示例,那么你也必须使用ioc来解决事件聚合器。刚刚更新了问题,解决了这两个问题,现在我们可以清楚地看到你的问题,正如我在回答的最后一段中所说的,我的怀疑是正确的。您正在创建依赖项注入容器的两个不同实例,并期望获得事件聚合器的单个实例。只需将容器创建移动到应用程序的合成根目录,并在整个应用程序中使用依赖项注入容器的单个实例。您建议我在
App.xaml.cs
中解析这两个VM?
public partial class ChildView1 : Window
{
public ChildView1()
{
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
Child1ViewModel vm = container.Resolve<Child1ViewModel>();
InitializeComponent();
DataContext = vm;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
MainViewModel vm = container.Resolve<MainViewModel>();
InitializeComponent();
DataContext = vm;
}
}