2017-01-07 7 views
0

Я в настоящее время создаю приложение с инструментами WPF и MVVM Light.Inject service в ViewModel с MVVM Light toolkit

У меня есть этот вид модели:

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 это служба, которая обрабатывает отправки/обработки сообщений. Когда пользователь взаимодействует с элементом на экране, вызывается служба электронной почты (это было зарегистрировано в ServiceLocator)

Интересно, правильно ли реализовано мое приложение с шаблоном проектирования MVVM. И есть ли какие-либо более эффективные способы ввода услуг в модель представления (текущий подход требует много времени, объявляя свойство инициализации)

ответ

1

Интересно, правильно ли реализуется мое приложение с шаблоном проектирования MVVM.

Зависимость инъекции не имеет никакого отношения к шаблону MVVM. MVVM - это разделение озабоченности между элементами управления пользовательским интерфейсом и их логикой. Включение зависимостей позволяет вам вводить класс с любыми объектами, которые ему нужны, если класс не должен сам создавать эти объекты.

И есть ли более эффективные способы инъекционных услуг в поле зрения модели (нынешний подход занимает много времени, объявляющей инициализация собственности)

Если это не имеет никакого смысла для класса вида модели существовать без ссылка на услугу, вы должны использовать инъекцию зависимости конструктора вместо того, чтобы вводить зависимость через свойство. Вы можете прочитать об этом здесь:

Dependency injection through constructors or property setters?

Использование текущей реализации его можно использовать класс модели без услуги:

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

Лучше реализация будет что-то вроде этого:

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

Это гарантирует, что класс модели представления всегда имеет действительную ссылку на IEmailService. Он также позволяет внедрить его с любой реализацией интерфейса IEmailService при создании объекта.