为什么我的 Autofac 注册的 Prism EventAggregator 没有正确注入到视图模型中?

Why my Autofac registered Prism EventAggregator is not injected properly into viewmodel?

在我的解决方案中,我使用了 AutofacPrism。下面是一个简化的项目,解释了会发生什么。

我正在 Autofac 的容器 class 中注册我的视图、视图模型和 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();
            }
        }

注意,将视图模型注册为单例时,效果是一样的。我像这样将 EventAggregator 注入我的虚拟机:

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[里面=54=] class 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
        }
    }

Child1ViewModel 的构造函数在调试期间被 hiten,只是 UpdateName 没有被执行。但是,如果我使用 EventAggregator 的直接调用,就像这样:

Utility.EventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

或者这个:

Utility.EventAggregator.GetEvent<UpdateNameEvent>().Publish(name);

有效!假设 Utility class 看起来像:

public class Utility
    {
        public static EventAggregator EventAggregator { get; set; }

        static Utility()
        {
            EventAggregator = new EventAggregator();
        }
    }

我怀疑在 Autofac 中注册聚合器存在一些问题,但我不知道是什么问题,我只是按照我发现的 odl exaples 使用它.

正在解析 Child1ViewModelMainViewModel:

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;
        }
    }

我假设您正在使用 Prism 的 ViewModelLocator 机制。我的假设是基于您手动实例化 ChildView1 而不是使用依赖注入容器解析它,并在评论中声明 viewModel 在后台解析。

您必须更改用于解析 ViewModel 实例的 Prism ViewModelLocator 容器,如下所示。

ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType) =>
{
    return YourAutofacContainer.Resolve<viewModelType>();
});

有关详细信息,请参阅 Control how ViewModels are Resolved

请记住,为了在整个应用程序中保持对象实例的单实例生命周期范围一致,您必须使用相同的依赖注入容器实例来解析对象和此对象的父对象,一直到根对象.