0
votes

I'm currently making an application with WPF and MVVM Light toolkit.

I have this view model :

public class MainViewModel : ViewModelBase
{
    // Instance of service which is used for sending email.
    private IEmailService _emailService;

    // Get/set instance of service which is used for sending email.
    public IEmailService EmailService
    {
        get
        {
            return _emailService;
        }
        set
        {
            Set("EmailService", ref _emailService, value);
        }
    }

    public MainViewModel()
    {
        _emailService = new ServiceLocator.Current.GetInstance<IEmailService>();
    }
}

Email service is a service which handles sending/processing emails. When user interacts with an element on the screen, email service is called (this has been registered in ServiceLocator)

I wonder if my implement is correct with MVVM design pattern or not. And are there any better ways to inject service into view model (the current approach takes a lot of time declaring initializing property)

1

1 Answers

1
votes

I wonder if my implement is correct with MVVM design pattern or not.

Dependency injection has nothing to do with the MVVM pattern really. MVVM is about separation of concern between user interface controls and their logic. Dependency injection enables you to inject a class with any objects it needs without the class having to create these objects itself.

And are there any better ways to inject service into view model (the current approach takes a lot of time declaring initializing property)

If it makes no sense for the view model class to exist without a reference to the service, you should use constructor dependency injection instead of injecting the dependency through a property. You can read more about this here:

Dependency injection through constructors or property setters?

Using your current implementation it is possible to use the view model class without the service:

MainViewModel vm = new MainViewModel();
vm.EmailService = null;

A better implementation would be something like this:

public class MainViewModel : ViewModelBase
{
    // Instance of service which is used for sending email.
    private readonly IEmailService _emailService;

    public MainViewModel(IEmailService emailService = null)
    {
        _emailService = emailService ?? ServiceLocator.Current.GetInstance<IEmailService>();

        if(_emailService is null)
            throw new ArgumentNullException(nameof(emailService));
    }
}

This makes sure that the view model class always has a valid reference to an IEmailService. It also makes it possible to inject it with any implementation of the IEmailService interface when you construct the object.