I need some help to understand how to instantiate ViewModels without having all of them as parameters in the MainViewModel Class constructor.
Could any of you help me to get my head around and get rid of so many parameters in the constructor. I've read about FactoryPatterns but I don't understand how to implement it or maybe that is not the solution?. Anyway here's the code.
Thank you. Pls help me this is driving me nuts!
app.xaml.cs
private readonly ServiceProvider _serviceProvider;
public App()
{
ServiceCollection services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
}
private void ConfigureServices(ServiceCollection services)
{
services.AddSingleton<MainWindow>();
// Services
services.AddSingleton<ICustomerService, CustomerService>();
// ViewModels
services.AddScoped<MainViewModel>();
services.AddScoped<CustomerViewModel>();
services.AddScoped<CustomerAddViewModel>();
services.AddScoped<CustomerEditViewModel>();
services.AddScoped<ServiceViewModel>();
}
private void OnStartup(object sender, StartupEventArgs e)
{
var mainWindow = _serviceProvider.GetService<MainWindow>();
mainWindow.DataContext = _serviceProvider.GetService<MainViewModel>();
mainWindow.Show();
}
MainViewMode.cs
public class MainViewModel : ViewModelBase
{
private CustomerViewModel _customerViewModel;
private CustomerAddViewModel _customerAddViewModel;
private CustomerEditViewModel _customerEditViewModel;
private ViewModelBase _selectedViewModel;
public ViewModelBase SelectedViewModel
{
get => _selectedViewModel;
set
{
_selectedViewModel = value;
NotifyPropertyChanged();
}
}
public RelayCommand CustCommand { get; set; }
public RelayCommand ServCommand { get; set; }
**public MainViewModel(
CustomerViewModel customerViewModel,
CustomerAddViewModel customerAddViewModel,
CustomerEditViewModel customerEditViewModel)
{
_customerViewModel = customerViewModel;
_customerAddViewModel = customerAddViewModel;
_customerEditViewModel = customerEditViewModel;
CustCommand = new RelayCommand(OpenCustomer);
}**
private void OpenCustomer()
{
SelectedViewModel = _customerViewModel;
}
}
CustomerViewModel
public class CustomerViewModel : ViewModelBase
{
private ICustomerService _repo;
private ObservableCollection<Customer> _customers;
public ObservableCollection<Customer> Customers
{
get => _customers;
set
{
_customers = value;
NotifyPropertyChanged();
}
}
public CustomerViewModel(ICustomerService repo)
{
_repo = repo;
}
public async void LoadCustomers()
{
List<Customer> customers = await _repo.GetCustomers();
Customers = new ObservableCollection<Customer>(customers);
}
}
You're using constructor injection, which is only one of the ways to do DI. Another method is property injection, where you typically do something like this:
public class ClassToBeInjected
{
[Inject]
public SomeDataType PropertyToBeInjected {get; set;}
... etc ...
}
So long as ClassToBeInjected is being created via the DI framework, any properties tagged with [Inject] will also be injected automatically. Furthermore, any properties of SomeDataType that are tagged with the [Inject] attribute will also be injected, and so on down the heirarchy.
The exact mechanism of how this is achieved will depend on your DI framework. I've used the [Inject] attribute here, which is what Ninject uses, but each framework will have its own way of doing it.
You don't need to pass all your dependencies to MainViewModel, now it's easy because you only have three, what if they were 20? I think the best thing to do here is to inject the dependency container and get all your view models from there.
public class MainViewModel : ViewModelBase
{
private ServiceProvider _serviceProvider;
public MainViewModel(IServiceProvider provider)
{
_serviceProvider = provider;
}
private void SomeMethod()
{
CustomerViewModel viewModel = _serviceProvider.GetRequiredService<CustomerViewModel>();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With