Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

Présentation et bonnes pratiques du pattern MVVM - MIC Belgique

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Prochain SlideShare
MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2
Chargement dans…3
×

Consultez-les par la suite

1 sur 39 Publicité

Présentation et bonnes pratiques du pattern MVVM - MIC Belgique

Télécharger pour lire hors ligne

Le Model View ViewModel (MVVM) est une architecture et une méthode de conception utilisée dans le génie logiciel. Apparu en 2004, MVVM est adapté pour le développement des applications basées sur les technologies Windows (desktop, tablette ou mobile), mais également Web/HTML5. Cette méthode permet de séparer la vue de la logique et de l'accès aux données en accentuant les principes de binding et d’événement. Une bonne vue générale a été donnée par Laurent Bugnion, le père du MVVMLight, dans le podcast #11 de DevApps (http://devapps.be/podcast/11).

http://www.meetup.com/fr-FR/micbelgique/events/228368909/?eventId=228368909

Le Model View ViewModel (MVVM) est une architecture et une méthode de conception utilisée dans le génie logiciel. Apparu en 2004, MVVM est adapté pour le développement des applications basées sur les technologies Windows (desktop, tablette ou mobile), mais également Web/HTML5. Cette méthode permet de séparer la vue de la logique et de l'accès aux données en accentuant les principes de binding et d’événement. Une bonne vue générale a été donnée par Laurent Bugnion, le père du MVVMLight, dans le podcast #11 de DevApps (http://devapps.be/podcast/11).

http://www.meetup.com/fr-FR/micbelgique/events/228368909/?eventId=228368909

Publicité
Publicité

Plus De Contenu Connexe

Diaporamas pour vous (20)

Les utilisateurs ont également aimé (20)

Publicité

Similaire à Présentation et bonnes pratiques du pattern MVVM - MIC Belgique (20)

Plus par Denis Voituron (20)

Publicité

Plus récents (20)

Présentation et bonnes pratiques du pattern MVVM - MIC Belgique

  1. 1. 1
  2. 2. 2 Denis Voituron Civil engineer (Mons) Company founder Developer: VB3, VB.Net, C# .Net Software Architect (Trasys) Blogger Speaker (DevApps.be)
  3. 3. 3 • Introduction • Getting Started • Services and DesignServices • Localization • Commands • Messenger • Unit Tests and TestServices
  4. 4. 4
  5. 5. 5
  6. 6. 6 Pattern Model Business Logic View Presentation UI ViewModel Presentation Logic Command Binding Method call Event MVVMMODEL VIEW VIEWMODEL
  7. 7. 7 Pattern Model Business Logic View Presentation UI ViewModel Presentation Logic Command Binding Method call Event Friend FirstName LastName DateOfBirth PictureUrl ObservableObject FriendPage <Page DataContext="{Binding ViewModel}"> <TextBlock Text="{Binding FullName}" /> <TextBlock Text="{Binding Age}" /> <Image Source="{Binding Photo}" /> </Page> FriendViewModel FullName Age Photo ViewModelBase
  8. 8. 8 • Code behind is not always bad, but can complicate things. • MVVM is a variation of MVC. • The goal is to decouple the View from the Model. • Easier to maintain. • Easier to test • Allow to create design time data. @LBugnion
  9. 9. 9 MVVM Light v5 Toolkit to help MVVM developments Open Source project Supported by Microsoft http://www.mvvmlight.net
  10. 10. 10
  11. 11. 11
  12. 12. 12 Window Dialog Page View
  13. 13. 13 public class Friend { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Picture { get; set; } public string Location { get; set; } public string Message { get; set; } } public class Friend : ObservableObject { private string _firstName = String.Empty; public string FirstName { get { return _firstName; } set { Set(() => this.FirstName, ref _firstName, value); } } Model
  14. 14. 14 public interface IDataService { Task<Friend[]> GetFriendsAsync(); } public class DataService : IDataService { public async Task<Friend[]> GetFriendsAsync() { ... } } public class DesignDataService : IDataService { public async Task<Friend[]> GetFriendsAsync() { ... } } Model
  15. 15. 15 public class MainViewModel { public MainViewModel() { _dataService = new DataService(); } } public class MainViewModel { public MainViewModel(IDataService dataservice) { _dataService = dataservice; } } DataService for Test, for Production, for Design, …
  16. 16. 16 public class ViewModelLocator { public ViewModelLocator() { // SimpleIoC ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); // Models if (ViewModelBase.IsInDesignModeStatic) SimpleIoc.Default.Register<IDataService, DataService>(); else SimpleIoc.Default.Register<IDataService, DesignDataService>(); // ViewModels SimpleIoc.Default.Register<ViewModels.MainViewModel>(); } } View Model <Application xmlns:locator="using:SampleMvvmLight.ViewModels" ... > <Application.Resources> <locator:ViewModelLocator x:Key="ViewModelLocator" /> </Application.Resources> </Application>
  17. 17. 17 public abstract class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase { // Default constructor used by the Design or Production Mode public ViewModelBase() : this(ServiceLocator.Current.GetInstance<Models.IDataService>(), ServiceLocator.Current.GetInstance<IDialogService>(), ServiceLocator.Current.GetInstance<INavigationService>()) { if (ViewModelBase.IsInDesignModeStatic) OnLoadedAsync(); } // Default constructor with all usable services protected ViewModelBase(IDataService dataservice, IDialogService dialogService, INavigationService navigationService) { this.DateService = dataservice; this.DialogService = dialogService; this.NavigationService = navigationService; } } View Model
  18. 18. 18 Snippet ‘mvvminpcsetlambda’ View Model public class MainViewModel : ViewModelBase { protected async override Task OnLoadedAsync() { this.Friends = await this.DateService.GetFriendsAsync(); } private Friend[] _friends = null; public Friend[] Friends { get { return _friends; } set { Set(() => Friends, ref _friends, value); } } }
  19. 19. 19 private ViewModels.MainViewModel ViewModel { get { return ((MainViewModel)Resources["ViewModel"]); } } View <Page xmlns:vm="using:SampleMvvmLight.ViewModels"> <!-- Create a new instance of the associated ViewModel --> <Page.Resources> <vm:MainViewModel x:Key="ViewModel" /> </Page.Resources> <!-- Content --> <Grid DataContext="{StaticResource ViewModel}"> <ListView Margin="10,33,10,10" ItemsSource="{Binding Friends}" /> </Grid> </Page>
  20. 20. 20 Rules for views and view models User controls vs templated controls @ricosuter
  21. 21. 21 View model instantiation <MySubView DataContext="{Binding MySubViewModel}" /> <MySubView Project="{Binding SelectedProject}" /> public MyView() { InitializeComponent(); Loaded += async delegate { await ViewModel.OnLoaded(); }; Unloaded += async delegate { await ViewModel.OnUnloaded(); }; }
  22. 22. 22
  23. 23. 23 Interface for testing, designing and running Sample public interface IDataService { Task<Friend[]> GetFriendsAsync(); } public class DataService : IDataService { const string UrlBase = "http://xxx.azurewebsites.net/friends.aspx"; public async Task<Friend[]> GetFriendsAsync() { var client = new HttpClient(); string json = await client.GetStringAsync(new Uri(UrlBase)); var result = JsonConvert.DeserializeObject<ListOfFriends>(json); return result.Data.ToArray(); }
  24. 24. 24 SimpleIoc.Default.Register<IDialogService, DialogService>(); await this.DialogService.ShowMessage ("My message", "My title"); await this.DialogService.ShowMessageBox("My message", "My title"); await this.DialogService.ShowError(MyException, ...);
  25. 25. 25 private INavigationService CreateNavigationService() { var navigationService = new NavigationService(); navigationService.Configure(MAIN_PAGE, typeof(MainPage)); navigationService.Configure(DETAIL_PAGE, typeof(DetailPage)); return navigationService; } ... SimpleIoc.Default.Register<INavigationService>(() => CreateNavigationService()); public class NavigationService : INavigationService { public void NavigateTo<T>(string pageKey, T parameter) { ... } public void GoBack() { ... } }
  26. 26. 26 Navigate to the second page Retrieve parameters public class FirstViewModel : ViewModelBase { ... this.NavigationService.NavigateTo<string>(ViewModelLocator.DETAIL_PAGE, "ABC"); } public class SecondViewModel : ViewModelBase { public DetailViewModel() { this.NavigationRegistering<int>(); } protected async override Task OnNavigationFrom(object parameter) { this.Friend = await this.DateService.GetFriendAsync((int)parameter); } }
  27. 27. 27 Resource files • Resw Need a T4 file • Resx Configurable MyResources.Culture = new CultureInfo("fr"); CultureInfo.CurrentCulture = new CultureInfo("fr");
  28. 28. 28 The following prefixes or postfixes are recommended: (bigger projects, the keys should start with a module name. e.g. ‘Search_ButtonOK’) * * * * * * * * * * @ricosuter
  29. 29. 29
  30. 30. 30 Commands are instantiated in constructor. • Name "xxxCommand" • "xxxExecute" and "CanXxxExecute" public MainViewModel() { DisplayDetailCommand = new RelayCommand<Friend> (DisplayDetailExecute, CanDisplayDetailExecute); } public RelayCommand<Friend> DisplayDetailCommand { get; private set; } public void DisplayDetailExecute(Friend parameter) { ... } public bool CanDisplayDetailExecute(Friend parameter) { return true; } <Button Command="{Binding DisplayDetailCommand}" CommandParameter="{Binding SelectedFriend}" /> Snippet ‘mvvmrelaymethodcanexecute’
  31. 31. 31
  32. 32. 32 • It is an "event bus". • A message distribution system. • One default instance (Messenger.Default) @LBugnion
  33. 33. 33 Messenger.Default.Send<string>("Hello World"); Messenger.Default.Register<string> ( this, (message) => { ... } ); Messenger.Default.Unregister<string>(this);
  34. 34. 34
  35. 35. 35 • TestDataService • TestDialogService • TestNavigationService • TestServiceRegister public static void Registering() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register<IDataService, TestDataService>(); SimpleIoc.Default.Register<IDialogService, TestDialogService>(); SimpleIoc.Default.Register<INavigationService, TestNavigationService>(); }
  36. 36. 36 • Initialization • Test [TestClass] public class MainViewModelTests { [TestInitialize] public void Initialize() { TestServiceRegister.Registering(); } } [TestMethod] public async Task ComputeNumberOfFriends() { MainViewModel main = new MainViewModel(); await main.CallOnLoaded(); Assert.AreEqual(3, main.Friends.Length); }
  37. 37. 37
  38. 38. 38 • • • • • • • • •
  39. 39. 39 Ressources • • • • •

×