在MVVM应用程序中使用autofac

时间:2018-02-28 14:45:36

标签: c# wpf xaml mvvm autofac

我的应用程序在点击加载应用程序设置的用户按钮后进入休息模式。我已在bootstrapper类中注册了该组件。

如何在bootstrap类中注册用户控制器的构造函数以避免中断?

public class Bootstrapper
{
    public IContainer Bootstrap()
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<LoginView>().AsSelf();
        builder.RegisterType<SchoolSectionDataService>().As<ISchoolSectionDataService>();
        builder.RegisterType<AdminView>().AsSelf();

        builder.RegisterType<School>().AsSelf();
        builder.RegisterType<MainSchoolSetupViewModel>().AsSelf();

        return builder.Build();
    }
}

并且用户控件是:

private MainSchoolSetupViewModel _viewModel;

public School(MainSchoolSetupViewModel schoolSetupViewModel)
{
    InitializeComponent();
    _viewModel = schoolSetupViewModel;
    DataContext = _viewModel;
    Loaded += UserControl_Loaded;
}

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    _viewModel.Load();
}

1 个答案:

答案 0 :(得分:1)

不幸的是,将viewmodel传递给用户控件的构造函数是不可能的,但很少有方法可以解决它。最重要的是建立组合DI和XAML时,MVVM只是将视图模型注册到容器中。

评论中提到了夫妻选项:

  1. 在Bootstrap中添加静态IContainer属性。在用户控件的构造函数中调用它来获取VM:

    public School()
    {
        InitializeComponent();
        _viewModel = Bootstrap.Container.Resolve<MainSchoolSetupViewModel>();
        ...
    
    1. 跳过DI,而是在XAML中创建viewmodel实例:
  2. <UserControl.DataContext>
       <local:SchoolViewModel/>
    </UserControl.DataContext>
    

    但很可能你想要其他的可能性:

    1. 使用ViewModelLocator帮助解决问题。这个答案中有详细记载:https://stackoverflow.com/a/25524753/66988
    2. 主要思想是创建一个新的ViewModelLocator类:

      class ViewModelLocator
      {
          public SchoolViewModel SchoolViewModel
          {
              get { return Bootstrap.Container.Resolve<SchoolViewModel>(); } 
          }
      }
      

      在App.xaml中创建它的静态实例,并使用它来创建用户控件的数据上下文:

      DataContext="{Binding SchoolViewModel, Source={StaticResource ViewModelLocator}}">
      

      对于其他解决方案,一个选项是查看某些MVVM框架的源代码,例如Caliburn.Micro。从Caliburn.Micro您可以找到您可能感兴趣的ViewModelLocator和ViewLocator。