简体   繁体   中英

using autofac in MVVM application

My application is going on a break mode after hitting a user button that loads the app setup. I have registered the component in the bootstrapper class.

How can I register the constructor of the user controller in bootstrap class so as to avoid the break?

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

and the user control is:

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

Unfortunately passing viewmodel into user control's constructor is not possible but there few ways around it. The main thing usually is when building combining DI and XAML and MVVM is that only the view models are registered into the container.

Couple options are mentioned in the comments:

  1. Add a static IContainer property in your Bootstrap. Call it in you user control's constructor to get the VM:

     public School() { InitializeComponent(); _viewModel = Bootstrap.Container.Resolve<MainSchoolSetupViewModel>(); ... 
    1. Skip DI and instead create the viewmodel instance in XAML:
 <UserControl.DataContext> <local:SchoolViewModel/> </UserControl.DataContext> 

But it's quite likely that you want to there's other possibilities:

  1. Use ViewModelLocator to help out with DI. This is well documented in this answer: https://stackoverflow.com/a/25524753/66988

The main idea is that you create a new ViewModelLocator class:

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

And create a static instance of it in App.xaml and use it to create the data context of your user control:

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

For other solutions, one option is to check out source code of some of MVVM Frameworks, like Caliburn.Micro . From Caliburn.Micro you can find ViewModelLocator and ViewLocator which might interest you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM