Skip to content

Commit efa81cf

Browse files
David BritchDavid Britch
authored andcommitted
ViewModelLocator is now responsible for connecting view models to views.
Uses an auto-wiring convention-based approach.
1 parent 721e35f commit efa81cf

26 files changed

Lines changed: 171 additions & 194 deletions

src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using eShopOnContainers.Core.Helpers;
22
using eShopOnContainers.Services;
3-
using eShopOnContainers.ViewModels.Base;
3+
using eShopOnContainers.Core.ViewModels.Base;
44
using System.Threading.Tasks;
55
using Xamarin.Forms;
66
using Xamarin.Forms.Xaml;
@@ -27,13 +27,13 @@ public App()
2727
private void InitApp()
2828
{
2929
UseMockServices = Settings.UseMocks;
30-
31-
ViewModelLocator.Instance.UpdateDependencies(UseMockServices);
30+
ViewModelLocator.Initialize();
31+
ViewModelLocator.UpdateDependencies(UseMockServices);
3232
}
3333

3434
private Task InitNavigation()
3535
{
36-
var navigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
36+
var navigationService = ViewModelLocator.Resolve<INavigationService>();
3737
return navigationService.InitializeAsync();
3838
}
3939

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using eShopOnContainers.Core.Models.Basket;
22
using eShopOnContainers.Core.Models.Catalog;
3-
using eShopOnContainers.ViewModels.Base;
3+
using eShopOnContainers.Core.ViewModels.Base;
44
using System;
55
using System.Collections.Generic;
66
using System.Diagnostics;
@@ -21,7 +21,7 @@ public static void FixCatalogItemPictureUri(IEnumerable<CatalogItem> catalogItem
2121

2222
try
2323
{
24-
if (!ViewModelLocator.Instance.UseMockService
24+
if (!ViewModelLocator.UseMockService
2525
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
2626
{
2727
foreach (var catalogItem in catalogItems)
@@ -54,7 +54,7 @@ public static void FixBasketItemPictureUri(IEnumerable<BasketItem> basketItems)
5454

5555
try
5656
{
57-
if (!ViewModelLocator.Instance.UseMockService
57+
if (!ViewModelLocator.UseMockService
5858
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
5959
{
6060
foreach (var basketItem in basketItems)

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using eShopOnContainers.ViewModels.Base;
1+
using eShopOnContainers.Core.ViewModels.Base;
22
using Plugin.Settings;
33
using Plugin.Settings.Abstractions;
44

@@ -27,7 +27,7 @@ private static ISettings AppSettings
2727
private const string IdUrlBase = "url_base";
2828
private static readonly string AccessTokenDefault = string.Empty;
2929
private static readonly string IdTokenDefault = string.Empty;
30-
private static readonly bool UseMocksDefault = ViewModelLocator.Instance.UseMockService;
30+
private static readonly bool UseMocksDefault = ViewModelLocator.UseMockService;
3131
private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
3232

3333
#endregion

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/INavigationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using eShopOnContainers.ViewModels.Base;
1+
using eShopOnContainers.Core.ViewModels.Base;
22
using System;
33
using System.Threading.Tasks;
44

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs

Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
using eShopOnContainers.Core.Helpers;
22
using eShopOnContainers.Core.ViewModels;
33
using eShopOnContainers.Core.Views;
4-
using eShopOnContainers.ViewModels.Base;
4+
using eShopOnContainers.Core.ViewModels.Base;
55
using System;
6-
using System.Collections.Generic;
6+
using System.Globalization;
7+
using System.Reflection;
78
using System.Threading.Tasks;
89
using Xamarin.Forms;
910

1011
namespace eShopOnContainers.Services
1112
{
1213
public class NavigationService : INavigationService
1314
{
14-
protected readonly Dictionary<Type, Type> _mappings;
15-
1615
protected Application CurrentApplication
1716
{
1817
get
@@ -21,13 +20,6 @@ protected Application CurrentApplication
2120
}
2221
}
2322

24-
public NavigationService()
25-
{
26-
_mappings = new Dictionary<Type, Type>();
27-
28-
CreatePageViewModelMappings();
29-
}
30-
3123
public Task InitializeAsync()
3224
{
3325
if(string.IsNullOrEmpty(Settings.AuthAccessToken))
@@ -100,7 +92,7 @@ public virtual Task RemoveBackStackAsync()
10092

10193
protected virtual async Task InternalNavigateToAsync(Type viewModelType, object parameter)
10294
{
103-
Page page = CreateAndBindPage(viewModelType, parameter);
95+
Page page = CreatePage(viewModelType, parameter);
10496

10597
if (page is LoginView)
10698
{
@@ -109,7 +101,6 @@ protected virtual async Task InternalNavigateToAsync(Type viewModelType, object
109101
else
110102
{
111103
var navigationPage = CurrentApplication.MainPage as CustomNavigationView;
112-
113104
if (navigationPage != null)
114105
{
115106
await navigationPage.PushAsync(page);
@@ -123,42 +114,25 @@ protected virtual async Task InternalNavigateToAsync(Type viewModelType, object
123114
await (page.BindingContext as ViewModelBase).InitializeAsync(parameter);
124115
}
125116

126-
protected Type GetPageTypeForViewModel(Type viewModelType)
127-
{
128-
if (!_mappings.ContainsKey(viewModelType))
129-
{
130-
throw new KeyNotFoundException($"No map for ${viewModelType} was found on navigation mappings");
131-
}
132-
133-
return _mappings[viewModelType];
134-
}
135-
136-
protected Page CreateAndBindPage(Type viewModelType, object parameter)
137-
{
138-
Type pageType = GetPageTypeForViewModel(viewModelType);
139-
140-
if (pageType == null)
141-
{
142-
throw new Exception($"Mapping type for {viewModelType} is not a page");
143-
}
144-
145-
Page page = Activator.CreateInstance(pageType) as Page;
146-
ViewModelBase viewModel = ViewModelLocator.Instance.Resolve(viewModelType) as ViewModelBase;
147-
page.BindingContext = viewModel;
148-
149-
return page;
150-
}
151-
152-
private void CreatePageViewModelMappings()
153-
{
154-
_mappings.Add(typeof(BasketViewModel), typeof(BasketView));
155-
_mappings.Add(typeof(CatalogViewModel), typeof(CatalogView));
156-
_mappings.Add(typeof(CheckoutViewModel), typeof(CheckoutView));
157-
_mappings.Add(typeof(LoginViewModel), typeof(LoginView));
158-
_mappings.Add(typeof(MainViewModel), typeof(MainView));
159-
_mappings.Add(typeof(OrderDetailViewModel), typeof(OrderDetailView));
160-
_mappings.Add(typeof(ProfileViewModel), typeof(ProfileView));
161-
_mappings.Add(typeof(SettingsViewModel), typeof(SettingsView));
162-
}
117+
protected Type GetPageTypeForViewModel(Type viewModelType)
118+
{
119+
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
120+
var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;
121+
var viewAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);
122+
var viewType = Type.GetType(viewAssemblyName);
123+
return viewType;
124+
}
125+
126+
protected Page CreatePage(Type viewModelType, object parameter)
127+
{
128+
Type pageType = GetPageTypeForViewModel(viewModelType);
129+
if (pageType == null)
130+
{
131+
throw new Exception($"Cannot locate page type for {viewModelType}");
132+
}
133+
134+
Page page = Activator.CreateInstance(pageType) as Page;
135+
return page;
136+
}
163137
}
164138
}

src/Mobile/eShopOnContainers/eShopOnContainers.Core/Validations/ValidatableObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using eShopOnContainers.ViewModels.Base;
1+
using eShopOnContainers.Core.ViewModels.Base;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.Linq;

src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ExtendedBindableObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Reflection;
44
using Xamarin.Forms;
55

6-
namespace eShopOnContainers.ViewModels.Base
6+
namespace eShopOnContainers.Core.ViewModels.Base
77
{
88
public abstract class ExtendedBindableObject : BindableObject
99
{

src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using eShopOnContainers.Core;
2-
using eShopOnContainers.Core.Helpers;
1+
using eShopOnContainers.Core.Helpers;
32
using eShopOnContainers.Services;
43
using System.Threading.Tasks;
54

6-
namespace eShopOnContainers.ViewModels.Base
5+
namespace eShopOnContainers.Core.ViewModels.Base
76
{
87
public abstract class ViewModelBase : ExtendedBindableObject
98
{
@@ -28,8 +27,8 @@ public bool IsBusy
2827

2928
public ViewModelBase()
3029
{
31-
DialogService = ViewModelLocator.Instance.Resolve<IDialogService>();
32-
NavigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
30+
DialogService = ViewModelLocator.Resolve<IDialogService>();
31+
NavigationService = ViewModelLocator.Resolve<INavigationService>();
3332
GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase;
3433
}
3534

0 commit comments

Comments
 (0)