Browse Source

Merge branch 'master' of https://github.com/dotnet/eShopOnContainers

pull/711/head
Ramón Tomás 7 years ago
parent
commit
2e50097c65
49 changed files with 442 additions and 403 deletions
  1. +1
    -0
      docker-compose.override.yml
  2. +10
    -3
      docker-compose.prod.yml
  3. BIN
      docs/Developing-Enterprise-Mobile-Applications-with-XamarinForms.pdf
  4. BIN
      img/ebook_xamarin_patterns_cover.png
  5. +16
    -6
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml
  6. +4
    -4
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs
  7. +19
    -25
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Behaviors/LineColorBehavior.cs
  8. +22
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Converters/FirstValidationErrorConverter.cs
  9. +11
    -0
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Effects/EntryLineColorEffect.cs
  10. +0
    -18
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/AnimationExtension.cs
  11. +3
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs
  12. +2
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs
  13. +1
    -8
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/INavigationService.cs
  14. +33
    -90
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs
  15. +16
    -13
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Validations/ValidatableObject.cs
  16. +1
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ExtendedBindableObject.cs
  17. +1
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessageKeys.cs
  18. +4
    -5
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs
  19. +83
    -81
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs
  20. +12
    -14
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs
  21. +8
    -19
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs
  22. +2
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs
  23. +20
    -10
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs
  24. +2
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs
  25. +2
    -9
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs
  26. +1
    -1
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs
  27. +2
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs
  28. +4
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/BasketView.xaml
  29. +5
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CatalogView.xaml
  30. +2
    -5
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CatalogView.xaml.cs
  31. +8
    -10
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CheckoutView.xaml
  32. +39
    -7
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml
  33. +16
    -16
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml.cs
  34. +4
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/MainView.xaml
  35. +4
    -13
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/MainView.xaml.cs
  36. +4
    -2
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/OrderDetailView.xaml
  37. +6
    -4
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/ProfileView.xaml
  38. +5
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml
  39. +4
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj
  40. +3
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Effects/EntryLineColorEffect.cs
  41. +3
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.Windows/Effects/EntryLineColorEffect.cs
  42. +3
    -3
      src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Effects/EntryLineColorEffect.cs
  43. +2
    -1
      src/Services/Catalog/Catalog.API/Startup.cs
  44. +42
    -0
      src/Services/Identity/Identity.API/Certificate/Certificate.cs
  45. BIN
      src/Services/Identity/Identity.API/Certificate/idsrv3test.pfx
  46. +5
    -1
      src/Services/Identity/Identity.API/Identity.API.csproj
  47. +2
    -1
      src/Services/Identity/Identity.API/Startup.cs
  48. +1
    -0
      src/Web/WebMVC/Services/Utilities/ResilientHttpClient.cs
  49. +4
    -1
      src/Web/WebMVC/Startup.cs

+ 1
- 0
docker-compose.override.yml View File

@ -44,6 +44,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:5102
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
- identityUrl=http://identity.api:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- BasketUrl=http://basket.api:5103
- EventBusConnection=rabbitmq
ports:
- "5102:5102"


+ 10
- 3
docker-compose.prod.yml View File

@ -19,6 +19,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:5103
- ConnectionString=basket.data
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
- EventBusConnection=rabbitmq
ports:
- "5103:5103"
@ -28,6 +29,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:5101
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
- ExternalCatalogBaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5101 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
- EventBusConnection=rabbitmq
ports:
- "5101:5101"
@ -47,6 +49,8 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:5102
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
- identityUrl=http://identity.api:5105 #Local: You need to open your host's firewall at range 5100-5105. at range 5100-5105.
- BasketUrl=http://basket.api:5103
- EventBusConnection=rabbitmq
ports:
- "5102:5102"
@ -81,10 +85,13 @@ services:
webstatus:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:5107
- CatalogUrl=http://catalog.api:5101/hc
- OrderingUrl=http://ordering.api:5102/hc
- BasketUrl=http://basket.api:5103/hc
- IdentityUrl=http://10.0.75.1:5105/hc
- mvc=http://webmvc:5100/hc
- spa=http://webspa:5104/hc
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
ports:
- "5107:5107"
- "5107:5107"

BIN
docs/Developing-Enterprise-Mobile-Applications-with-XamarinForms.pdf View File


BIN
img/ebook_xamarin_patterns_cover.png View File

Before After
Width: 310  |  Height: 402  |  Size: 30 KiB

+ 16
- 6
src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml View File

@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:light="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Light"
xmlns:converters="clr-namespace:eShopOnContainers.Core.Converters;assembly=eShopOnContainers.Core"
xmlns:effects="clr-namespace:eShopOnContainers.Core.Effects;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
x:Class="eShopOnContainers.App">
<Application.Resources>
<ResourceDictionary MergedWith="light:LightThemeResources">
@ -17,6 +17,7 @@
<Color x:Key="GreenColor">#00A69C</Color>
<Color x:Key="DarkGreenColor">#00857D</Color>
<Color x:Key="GrayColor">#e2e2e2</Color>
<Color x:Key="ErrorColor">#ff5252</Color>
<!-- FONTS -->
<OnPlatform
@ -100,6 +101,7 @@
<!-- CONVERTERS -->
<converters:CountToBoolConverter x:Key="CountToBoolConverter" />
<converters:DatetimeConverter x:Key="DatetimeConverter" />
<converters:FirstValidationErrorConverter x:Key="FirstValidationErrorConverter" />
<converters:ImageConverter x:Key="ImageConverter" />
<converters:ItemTappedEventArgsConverter x:Key="ItemTappedEventArgsConverter" />
<converters:InverseCountToBoolConverter x:Key="InverseCountToBoolConverter" />
@ -109,6 +111,14 @@
<converters:WebNavigatingEventArgsConverter x:Key="WebNavigatingEventArgsConverter" />
<!-- STYLES -->
<Style x:Key="ValidationErrorLabelStyle"
TargetType="{x:Type Label}">
<Setter Property="TextColor"
Value="{StaticResource ErrorColor}" />
<Setter Property="FontSize"
Value="{StaticResource LittleSize}" />
</Style>
<Style x:Key="EntryStyle"
TargetType="{x:Type Entry}">
<Setter Property="FontFamily"
@ -125,9 +135,9 @@
Value="Bold" />
<Setter Property="Opacity"
Value="0.6" />
<Setter Property="effects:LineColorEffect.ApplyLineColor"
<Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
Value="True" />
<Setter Property="effects:LineColorEffect.LineColor"
<Setter Property="behaviors:LineColorBehavior.LineColor"
Value="{StaticResource BlackColor}" />
<Style.Triggers>
<Trigger TargetType="Entry"
@ -156,16 +166,16 @@
Value="Transparent" />
<Setter Property="Opacity"
Value="0.6" />
<Setter Property="effects:LineColorEffect.ApplyLineColor"
<Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
Value="True" />
<Setter Property="effects:LineColorEffect.LineColor"
<Setter Property="behaviors:LineColorBehavior.LineColor"
Value="Gray" />
<Style.Triggers>
<Trigger TargetType="Entry"
Property="IsFocused"
Value="True">
<Setter Property="Opacity" Value="1" />
<Setter Property="effects:LineColorEffect.LineColor"
<Setter Property="behaviors:LineColorBehavior.LineColor"
Value="{StaticResource GreenColor}" />
</Trigger>
</Style.Triggers>


+ 4
- 4
src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs View File

@ -1,6 +1,6 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Services;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -27,13 +27,13 @@ namespace eShopOnContainers
private void InitApp()
{
UseMockServices = Settings.UseMocks;
ViewModelLocator.Instance.UpdateDependencies(UseMockServices);
ViewModelLocator.Initialize();
ViewModelLocator.UpdateDependencies(UseMockServices);
}
private Task InitNavigation()
{
var navigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
var navigationService = ViewModelLocator.Resolve<INavigationService>();
return navigationService.InitializeAsync();
}


src/Mobile/eShopOnContainers/eShopOnContainers.Core/Effects/LineColorEffect.cs → src/Mobile/eShopOnContainers/eShopOnContainers.Core/Behaviors/LineColorBehavior.cs View File

@ -1,14 +1,18 @@
using System.Linq;
using Xamarin.Forms;
using eShopOnContainers.Core.Effects;
namespace eShopOnContainers.Core.Effects
namespace eShopOnContainers.Core.Behaviors
{
public static class LineColorEffect
public static class LineColorBehavior
{
public static readonly BindableProperty ApplyLineColorProperty =
BindableProperty.CreateAttached("ApplyLineColor", typeof(bool), typeof(LineColorEffect), false,
BindableProperty.CreateAttached("ApplyLineColor", typeof(bool), typeof(LineColorBehavior), false,
propertyChanged: OnApplyLineColorChanged);
public static readonly BindableProperty LineColorProperty =
BindableProperty.CreateAttached("LineColor", typeof(Color), typeof(LineColorBehavior), Color.Default);
public static bool GetApplyLineColor(BindableObject view)
{
return (bool)view.GetValue(ApplyLineColorProperty);
@ -19,6 +23,16 @@ namespace eShopOnContainers.Core.Effects
view.SetValue(ApplyLineColorProperty, value);
}
public static Color GetLineColor(BindableObject view)
{
return (Color)view.GetValue(LineColorProperty);
}
public static void SetLineColor(BindableObject view, Color value)
{
view.SetValue(LineColorProperty, value);
}
private static void OnApplyLineColorChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as View;
@ -28,9 +42,9 @@ namespace eShopOnContainers.Core.Effects
return;
}
bool hasShadow = (bool)newValue;
bool hasLine = (bool)newValue;
if (hasShadow)
if (hasLine)
{
view.Effects.Add(new EntryLineColorEffect());
}
@ -43,25 +57,5 @@ namespace eShopOnContainers.Core.Effects
}
}
}
public static readonly BindableProperty LineColorProperty =
BindableProperty.CreateAttached("LineColor", typeof(Color), typeof(LineColorEffect), Color.Default);
public static Color GetLineColor(BindableObject view)
{
return (Color)view.GetValue(LineColorProperty);
}
public static void SetLineColor(BindableObject view, Color value)
{
view.SetValue(LineColorProperty, value);
}
class EntryLineColorEffect : RoutingEffect
{
public EntryLineColorEffect() : base("eShopOnContainers.EntryLineColorEffect")
{
}
}
}
}

+ 22
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Converters/FirstValidationErrorConverter.cs View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Xamarin.Forms;
namespace eShopOnContainers.Core.Converters
{
public class FirstValidationErrorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ICollection<string> errors = value as ICollection<string>;
return errors != null && errors.Count > 0 ? errors.ElementAt(0) : null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

+ 11
- 0
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Effects/EntryLineColorEffect.cs View File

@ -0,0 +1,11 @@
using Xamarin.Forms;
namespace eShopOnContainers.Core.Effects
{
public class EntryLineColorEffect : RoutingEffect
{
public EntryLineColorEffect() : base("eShopOnContainers.EntryLineColorEffect")
{
}
}
}

+ 0
- 18
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Extensions/AnimationExtension.cs View File

@ -1,18 +0,0 @@
using eShopOnContainers.Core.Animations.Base;
using System;
using Xamarin.Forms;
namespace eShopOnContainers.Core.Extensions
{
public static class AnimationExtension
{
public static async void Animate(this VisualElement visualElement, AnimationBase animation, Action onFinishedCallback = null)
{
animation.Target = visualElement;
await animation.Begin();
onFinishedCallback?.Invoke();
}
}
}

+ 3
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/ServicesHelper.cs View File

@ -1,6 +1,6 @@
using eShopOnContainers.Core.Models.Basket;
using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -21,7 +21,7 @@ namespace eShopOnContainers.Core.Helpers
try
{
if (!ViewModelLocator.Instance.UseMockService
if (!ViewModelLocator.UseMockService
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
{
foreach (var catalogItem in catalogItems)
@ -54,7 +54,7 @@ namespace eShopOnContainers.Core.Helpers
try
{
if (!ViewModelLocator.Instance.UseMockService
if (!ViewModelLocator.UseMockService
&& Settings.UrlBase != GlobalSetting.DefaultEndpoint)
{
foreach (var basketItem in basketItems)


+ 2
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Helpers/Settings.cs View File

@ -1,4 +1,4 @@
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using Plugin.Settings;
using Plugin.Settings.Abstractions;
@ -27,7 +27,7 @@ namespace eShopOnContainers.Core.Helpers
private const string IdUrlBase = "url_base";
private static readonly string AccessTokenDefault = string.Empty;
private static readonly string IdTokenDefault = string.Empty;
private static readonly bool UseMocksDefault = ViewModelLocator.Instance.UseMockService;
private static readonly bool UseMocksDefault = true;
private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;
#endregion


+ 1
- 8
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/INavigationService.cs View File

@ -1,5 +1,4 @@
using eShopOnContainers.ViewModels.Base;
using System;
using eShopOnContainers.Core.ViewModels.Base;
using System.Threading.Tasks;
namespace eShopOnContainers.Services
@ -12,12 +11,6 @@ namespace eShopOnContainers.Services
Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase;
Task NavigateToAsync(Type viewModelType);
Task NavigateToAsync(Type viewModelType, object parameter);
Task NavigateBackAsync();
Task RemoveLastFromBackStackAsync();
Task RemoveBackStackAsync();


+ 33
- 90
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs View File

@ -1,9 +1,10 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.ViewModels;
using eShopOnContainers.Core.Views;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Threading.Tasks;
using Xamarin.Forms;
@ -11,23 +12,6 @@ namespace eShopOnContainers.Services
{
public class NavigationService : INavigationService
{
protected readonly Dictionary<Type, Type> _mappings;
protected Application CurrentApplication
{
get
{
return Application.Current;
}
}
public NavigationService()
{
_mappings = new Dictionary<Type, Type>();
CreatePageViewModelMappings();
}
public Task InitializeAsync()
{
if(string.IsNullOrEmpty(Settings.AuthAccessToken))
@ -46,32 +30,9 @@ namespace eShopOnContainers.Services
return InternalNavigateToAsync(typeof(TViewModel), parameter);
}
public Task NavigateToAsync(Type viewModelType)
public Task RemoveLastFromBackStackAsync()
{
return InternalNavigateToAsync(viewModelType, null);
}
public Task NavigateToAsync(Type viewModelType, object parameter)
{
return InternalNavigateToAsync(viewModelType, parameter);
}
public async Task NavigateBackAsync()
{
if (CurrentApplication.MainPage is CatalogView)
{
var mainPage = CurrentApplication.MainPage as CatalogView;
await mainPage.Navigation.PopAsync();
}
else if (CurrentApplication.MainPage != null)
{
await CurrentApplication.MainPage.Navigation.PopAsync();
}
}
public virtual Task RemoveLastFromBackStackAsync()
{
var mainPage = CurrentApplication.MainPage as CustomNavigationView;
var mainPage = Application.Current.MainPage as CustomNavigationView;
if (mainPage != null)
{
@ -82,9 +43,9 @@ namespace eShopOnContainers.Services
return Task.FromResult(true);
}
public virtual Task RemoveBackStackAsync()
public Task RemoveBackStackAsync()
{
var mainPage = CurrentApplication.MainPage as CustomNavigationView;
var mainPage = Application.Current.MainPage as CustomNavigationView;
if (mainPage != null)
{
@ -98,67 +59,49 @@ namespace eShopOnContainers.Services
return Task.FromResult(true);
}
protected virtual async Task InternalNavigateToAsync(Type viewModelType, object parameter)
private async Task InternalNavigateToAsync(Type viewModelType, object parameter)
{
Page page = CreateAndBindPage(viewModelType, parameter);
Page page = CreatePage(viewModelType, parameter);
if (page is LoginView)
{
CurrentApplication.MainPage = new CustomNavigationView(page);
Application.Current.MainPage = new CustomNavigationView(page);
}
else
{
var navigationPage = CurrentApplication.MainPage as CustomNavigationView;
{
var navigationPage = Application.Current.MainPage as CustomNavigationView;
if (navigationPage != null)
{
await navigationPage.PushAsync(page);
}
else
{
CurrentApplication.MainPage = new CustomNavigationView(page);
Application.Current.MainPage = new CustomNavigationView(page);
}
}
await (page.BindingContext as ViewModelBase).InitializeAsync(parameter);
}
protected Type GetPageTypeForViewModel(Type viewModelType)
{
if (!_mappings.ContainsKey(viewModelType))
{
throw new KeyNotFoundException($"No map for ${viewModelType} was found on navigation mappings");
}
return _mappings[viewModelType];
}
protected Page CreateAndBindPage(Type viewModelType, object parameter)
{
Type pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Mapping type for {viewModelType} is not a page");
}
Page page = Activator.CreateInstance(pageType) as Page;
ViewModelBase viewModel = ViewModelLocator.Instance.Resolve(viewModelType) as ViewModelBase;
page.BindingContext = viewModel;
return page;
}
private void CreatePageViewModelMappings()
{
_mappings.Add(typeof(BasketViewModel), typeof(BasketView));
_mappings.Add(typeof(CatalogViewModel), typeof(CatalogView));
_mappings.Add(typeof(CheckoutViewModel), typeof(CheckoutView));
_mappings.Add(typeof(LoginViewModel), typeof(LoginView));
_mappings.Add(typeof(MainViewModel), typeof(MainView));
_mappings.Add(typeof(OrderDetailViewModel), typeof(OrderDetailView));
_mappings.Add(typeof(ProfileViewModel), typeof(ProfileView));
_mappings.Add(typeof(SettingsViewModel), typeof(SettingsView));
}
private Type GetPageTypeForViewModel(Type viewModelType)
{
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;
var viewAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);
var viewType = Type.GetType(viewAssemblyName);
return viewType;
}
private Page CreatePage(Type viewModelType, object parameter)
{
Type pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Cannot locate page type for {viewModelType}");
}
Page page = Activator.CreateInstance(pageType) as Page;
return page;
}
}
}

+ 16
- 13
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Validations/ValidatableObject.cs View File

@ -1,6 +1,5 @@
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace eShopOnContainers.Core.Validations
@ -8,13 +7,24 @@ namespace eShopOnContainers.Core.Validations
public class ValidatableObject<T> : ExtendedBindableObject, IValidity
{
private readonly List<IValidationRule<T>> _validations;
private readonly ObservableCollection<string> _errors;
private List<string> _errors;
private T _value;
private bool _isValid;
public List<IValidationRule<T>> Validations => _validations;
public ObservableCollection<string> Errors => _errors;
public List<string> Errors
{
get
{
return _errors;
}
set
{
_errors = value;
RaisePropertyChanged(() => Errors);
}
}
public T Value
{
@ -22,7 +32,6 @@ namespace eShopOnContainers.Core.Validations
{
return _value;
}
set
{
_value = value;
@ -36,11 +45,9 @@ namespace eShopOnContainers.Core.Validations
{
return _isValid;
}
set
{
_isValid = value;
_errors.Clear();
RaisePropertyChanged(() => IsValid);
}
}
@ -48,7 +55,7 @@ namespace eShopOnContainers.Core.Validations
public ValidatableObject()
{
_isValid = true;
_errors = new ObservableCollection<string>();
_errors = new List<string>();
_validations = new List<IValidationRule<T>>();
}
@ -59,11 +66,7 @@ namespace eShopOnContainers.Core.Validations
IEnumerable<string> errors = _validations.Where(v => !v.Check(Value))
.Select(v => v.ValidationMessage);
foreach (var error in errors)
{
Errors.Add(error);
}
Errors = errors.ToList();
IsValid = !Errors.Any();
return this.IsValid;


+ 1
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ExtendedBindableObject.cs View File

@ -3,7 +3,7 @@ using System.Linq.Expressions;
using System.Reflection;
using Xamarin.Forms;
namespace eShopOnContainers.ViewModels.Base
namespace eShopOnContainers.Core.ViewModels.Base
{
public abstract class ExtendedBindableObject : BindableObject
{


src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessengerKeys.cs → src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessageKeys.cs View File

@ -1,6 +1,6 @@
namespace eShopOnContainers.Core.ViewModels.Base
{
public class MessengerKeys
public class MessageKeys
{
// Add product to basket
public const string AddProduct = "AddProduct";

+ 4
- 5
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelBase.cs View File

@ -1,9 +1,8 @@
using eShopOnContainers.Core;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Services;
using System.Threading.Tasks;
namespace eShopOnContainers.ViewModels.Base
namespace eShopOnContainers.Core.ViewModels.Base
{
public abstract class ViewModelBase : ExtendedBindableObject
{
@ -28,8 +27,8 @@ namespace eShopOnContainers.ViewModels.Base
public ViewModelBase()
{
DialogService = ViewModelLocator.Instance.Resolve<IDialogService>();
NavigationService = ViewModelLocator.Instance.Resolve<INavigationService>();
DialogService = ViewModelLocator.Resolve<IDialogService>();
NavigationService = ViewModelLocator.Resolve<INavigationService>();
GlobalSetting.Instance.BaseEndpoint = Settings.UrlBase;
}


+ 83
- 81
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs View File

@ -1,7 +1,8 @@
using Microsoft.Practices.Unity;
using eShopOnContainers.Core.ViewModels;
using eShopOnContainers.Services;
using System;
using System.Globalization;
using System.Reflection;
using eShopOnContainers.Core.Services.Catalog;
using eShopOnContainers.Core.Services.OpenUrl;
using eShopOnContainers.Core.Services.RequestProvider;
@ -9,100 +10,101 @@ using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Services.Identity;
using eShopOnContainers.Core.Services.Order;
using eShopOnContainers.Core.Services.User;
using Xamarin.Forms;
namespace eShopOnContainers.ViewModels.Base
namespace eShopOnContainers.Core.ViewModels.Base
{
public class ViewModelLocator
public static class ViewModelLocator
{
private bool _useMockService;
private readonly IUnityContainer _unityContainer;
private static readonly IUnityContainer _unityContainer = new UnityContainer();
private static readonly ViewModelLocator _instance = new ViewModelLocator();
public static readonly BindableProperty AutoWireViewModelProperty =
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
public static ViewModelLocator Instance
{
get { return _instance; }
}
public static bool GetAutoWireViewModel(BindableObject bindable)
{
return (bool)bindable.GetValue(ViewModelLocator.AutoWireViewModelProperty);
}
public bool UseMockService
{
get { return _useMockService; }
set { _useMockService = value; ; }
}
public static void SetAutoWireViewModel(BindableObject bindable, bool value)
{
bindable.SetValue(ViewModelLocator.AutoWireViewModelProperty, value);
}
protected ViewModelLocator()
{
_unityContainer = new UnityContainer();
public static bool UseMockService { get; set; }
// Services
_unityContainer.RegisterType<IDialogService, DialogService>();
RegisterSingleton<INavigationService, NavigationService>();
_unityContainer.RegisterType<IOpenUrlService, OpenUrlService>();
_unityContainer.RegisterType<IRequestProvider, RequestProvider>();
_unityContainer.RegisterType<IIdentityService, IdentityService>();
public static void Initialize()
{
// Services
_unityContainer.RegisterType<IDialogService, DialogService>();
_unityContainer.RegisterType<INavigationService, NavigationService>(new ContainerControlledLifetimeManager());
_unityContainer.RegisterType<IOpenUrlService, OpenUrlService>();
_unityContainer.RegisterType<IRequestProvider, RequestProvider>();
_unityContainer.RegisterType<IIdentityService, IdentityService>();
_unityContainer.RegisterType<ICatalogService, CatalogMockService>();
_unityContainer.RegisterType<IBasketService, BasketMockService>();
_unityContainer.RegisterType<IUserService, UserMockService>();
_unityContainer.RegisterType<ICatalogService, CatalogMockService>();
_unityContainer.RegisterType<IBasketService, BasketMockService>();
_unityContainer.RegisterType<IUserService, UserMockService>();
// View models
_unityContainer.RegisterType<BasketViewModel>();
_unityContainer.RegisterType<CatalogViewModel>();
_unityContainer.RegisterType<CheckoutViewModel>();
_unityContainer.RegisterType<LoginViewModel>();
_unityContainer.RegisterType<MainViewModel>();
_unityContainer.RegisterType<OrderDetailViewModel>();
_unityContainer.RegisterType<ProfileViewModel>();
_unityContainer.RegisterType<SettingsViewModel>();
}
// View models
_unityContainer.RegisterType<BasketViewModel>();
_unityContainer.RegisterType<CatalogViewModel>();
_unityContainer.RegisterType<CheckoutViewModel>();
_unityContainer.RegisterType<LoginViewModel>();
_unityContainer.RegisterType<MainViewModel>();
_unityContainer.RegisterType<OrderDetailViewModel>();
_unityContainer.RegisterType<ProfileViewModel>();
_unityContainer.RegisterType<SettingsViewModel>();
}
public static void UpdateDependencies(bool useMockServices)
{
// Change injected dependencies
if (useMockServices)
{
_unityContainer.RegisterInstance<ICatalogService>(new CatalogMockService());
_unityContainer.RegisterInstance<IBasketService>(new BasketMockService());
_unityContainer.RegisterInstance<IOrderService>(new OrderMockService());
_unityContainer.RegisterInstance<IUserService>(new UserMockService());
public void UpdateDependencies(bool useMockServices)
{
// Change injected dependencies
if (useMockServices)
{
_unityContainer.RegisterInstance<ICatalogService>(new CatalogMockService());
_unityContainer.RegisterInstance<IBasketService>(new BasketMockService());
_unityContainer.RegisterInstance<IOrderService>(new OrderMockService());
_unityContainer.RegisterInstance<IUserService>(new UserMockService());
UseMockService = true;
}
else
{
var requestProvider = Resolve<IRequestProvider>();
_unityContainer.RegisterInstance<ICatalogService>(new CatalogService(requestProvider));
_unityContainer.RegisterInstance<IBasketService>(new BasketService(requestProvider));
_unityContainer.RegisterInstance<IOrderService>(new OrderService(requestProvider));
_unityContainer.RegisterInstance<IUserService>(new UserService(requestProvider));
UseMockService = true;
}
else
{
var requestProvider = Resolve<IRequestProvider>();
_unityContainer.RegisterInstance<ICatalogService>(new CatalogService(requestProvider));
_unityContainer.RegisterInstance<IBasketService>(new BasketService(requestProvider));
_unityContainer.RegisterInstance<IOrderService>(new OrderService(requestProvider));
_unityContainer.RegisterInstance<IUserService>(new UserService(requestProvider));
UseMockService = false;
}
}
UseMockService = false;
}
}
public T Resolve<T>()
{
return _unityContainer.Resolve<T>();
}
public static T Resolve<T>()
{
return _unityContainer.Resolve<T>();
}
public object Resolve(Type type)
{
return _unityContainer.Resolve(type);
}
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as Element;
if (view == null)
{
return;
}
public void Register<T>(T instance)
{
_unityContainer.RegisterInstance<T>(instance);
}
var viewType = view.GetType();
var viewName = viewType.FullName.Replace(".Views.", ".ViewModels.");
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}Model, {1}", viewName, viewAssemblyName);
public void Register<TInterface, T>() where T : TInterface
{
_unityContainer.RegisterType<TInterface, T>();
}
public void RegisterSingleton<TInterface, T>() where T : TInterface
{
_unityContainer.RegisterType<TInterface, T>(new ContainerControlledLifetimeManager());
}
}
var viewModelType = Type.GetType(viewModelName);
if (viewModelType == null)
{
return;
}
var viewModel = _unityContainer.Resolve(viewModelType);
view.BindingContext = viewModel;
}
}
}

+ 12
- 14
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs View File

@ -4,8 +4,6 @@ using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Services.User;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.ViewModels.Base;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
@ -61,7 +59,7 @@ namespace eShopOnContainers.Core.ViewModels
}
}
public ICommand AddCommand => new Command<BasketItem>(AddItem);
public ICommand AddCommand => new Command<BasketItem>(async (item) => await AddItemAsync(item));
public ICommand CheckoutCommand => new Command(async () => await CheckoutAsync());
@ -82,22 +80,22 @@ namespace eShopOnContainers.Core.ViewModels
foreach (var basketItem in basket.Items)
{
BadgeCount += basketItem.Quantity;
AddBasketItem(basketItem);
await AddBasketItemAsync(basketItem);
}
}
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct);
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessengerKeys.AddProduct, (sender, arg) =>
MessagingCenter.Unsubscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct);
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct, async (sender, arg) =>
{
BadgeCount++;
AddCatalogItem(arg);
await AddCatalogItemAsync(arg);
});
await base.InitializeAsync(navigationData);
}
private void AddCatalogItem(CatalogItem item)
private async Task AddCatalogItemAsync(CatalogItem item)
{
BasketItems.Add(new BasketItem
{
@ -108,26 +106,26 @@ namespace eShopOnContainers.Core.ViewModels
Quantity = 1
});
ReCalculateTotal();
await ReCalculateTotalAsync();
}
private void AddItem(BasketItem item)
private async Task AddItemAsync(BasketItem item)
{
BadgeCount++;
AddBasketItem(item);
await AddBasketItemAsync(item);
RaisePropertyChanged(() => BasketItems);
}
private void AddBasketItem(BasketItem item)
private async Task AddBasketItemAsync(BasketItem item)
{
BasketItems.Add(item);
ReCalculateTotal();
await ReCalculateTotalAsync();
}
private async void ReCalculateTotal()
private async Task ReCalculateTotalAsync()
{
Total = 0;


+ 8
- 19
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs View File

@ -1,14 +1,11 @@
using System.Threading.Tasks;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Models.Catalog;
using eShopOnContainers.Core.Services.Catalog;
using System.Windows.Input;
using System.Linq;
using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Services.User;
namespace eShopOnContainers.Core.ViewModels
@ -20,19 +17,11 @@ namespace eShopOnContainers.Core.ViewModels
private CatalogBrand _brand;
private ObservableCollection<CatalogType> _types;
private CatalogType _type;
private IBasketService _basketService;
private ICatalogService _productsService;
private IUserService _userService;
public CatalogViewModel(
IBasketService basketService,
ICatalogService productsService,
IUserService userService)
public CatalogViewModel(ICatalogService productsService)
{
_basketService = basketService;
_productsService = productsService;
_userService = userService;
}
public ObservableCollection<CatalogItem> Products
@ -91,9 +80,9 @@ namespace eShopOnContainers.Core.ViewModels
public ICommand AddCatalogItemCommand => new Command<CatalogItem>(AddCatalogItem);
public ICommand FilterCommand => new Command(Filter);
public ICommand FilterCommand => new Command(async () => await FilterAsync());
public ICommand ClearFilterCommand => new Command(ClearFilter);
public ICommand ClearFilterCommand => new Command(async () => await ClearFilterAsync());
public override async Task InitializeAsync(object navigationData)
{
@ -110,10 +99,10 @@ namespace eShopOnContainers.Core.ViewModels
private void AddCatalogItem(CatalogItem catalogItem)
{
// Add new item to Basket
MessagingCenter.Send(this, MessengerKeys.AddProduct, catalogItem);
MessagingCenter.Send(this, MessageKeys.AddProduct, catalogItem);
}
private async void Filter()
private async Task FilterAsync()
{
if (Brand == null && Type == null)
{
@ -123,13 +112,13 @@ namespace eShopOnContainers.Core.ViewModels
IsBusy = true;
// Filter catalog products
MessagingCenter.Send(this, MessengerKeys.Filter);
MessagingCenter.Send(this, MessageKeys.Filter);
Products = await _productsService.FilterAsync(Brand.Id, Type.Id);
IsBusy = false;
}
private async void ClearFilter()
private async Task ClearFilterAsync()
{
IsBusy = true;


+ 2
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs View File

@ -1,5 +1,5 @@
using eShopOnContainers.Core.Models.Navigation;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Windows.Input;
using Xamarin.Forms;
using System.Threading.Tasks;
@ -138,7 +138,7 @@ namespace eShopOnContainers.Core.ViewModels
await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);
// Reset Basket badge
var basketViewModel = ViewModelLocator.Instance.Resolve<BasketViewModel>();
var basketViewModel = ViewModelLocator.Resolve<BasketViewModel>();
basketViewModel.BadgeCount = 0;
// Navigate to Orders


+ 20
- 10
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/LoginViewModel.cs View File

@ -2,9 +2,8 @@
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.Identity;
using eShopOnContainers.Core.Services.OpenUrl;
using eShopOnContainers.Core.Services.User;
using eShopOnContainers.Core.Validations;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using IdentityModel.Client;
using System;
using System.Diagnostics;
@ -25,16 +24,13 @@ namespace eShopOnContainers.Core.ViewModels
private IOpenUrlService _openUrlService;
private IIdentityService _identityService;
private IUserService _userService;
public LoginViewModel(
IOpenUrlService openUrlService,
IIdentityService identityService,
IUserService userService)
IIdentityService identityService)
{
_openUrlService = openUrlService;
_identityService = identityService;
_userService = userService;
_userName = new ValidatableObject<string>();
_password = new ValidatableObject<string>();
@ -131,6 +127,10 @@ namespace eShopOnContainers.Core.ViewModels
public ICommand SettingsCommand => new Command(async () => await SettingsAsync());
public ICommand ValidateUserNameCommand => new Command(() => ValidateUserName());
public ICommand ValidatePasswordCommand => new Command(() => ValidatePassword());
public override Task InitializeAsync(object navigationData)
{
if(navigationData is LogoutParameter)
@ -253,16 +253,26 @@ namespace eShopOnContainers.Core.ViewModels
private bool Validate()
{
bool isValidUser = _userName.Validate();
bool isValidPassword = _password.Validate();
bool isValidUser = ValidateUserName();
bool isValidPassword = ValidatePassword();
return isValidUser && isValidPassword;
}
private bool ValidateUserName()
{
return _userName.Validate();
}
private bool ValidatePassword()
{
return _password.Validate();
}
private void AddValidations()
{
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Username should not be empty" });
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Password should not be empty" });
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A username is required." });
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A password is required." });
}
public void InvalidateMock()


+ 2
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs View File

@ -1,8 +1,7 @@
using System.Threading.Tasks;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Models.Navigation;
using Xamarin.Forms;
using eShopOnContainers.Core.ViewModels.Base;
using System.Windows.Input;
namespace eShopOnContainers.Core.ViewModels
@ -19,7 +18,7 @@ namespace eShopOnContainers.Core.ViewModels
{
// Change selected application tab
var tabIndex = ((TabParameter)navigationData).TabIndex;
MessagingCenter.Send(this, MessengerKeys.ChangeTab, tabIndex);
MessagingCenter.Send(this, MessageKeys.ChangeTab, tabIndex);
}
return base.InitializeAsync(navigationData);


+ 2
- 9
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs View File

@ -1,6 +1,6 @@
using System.Threading.Tasks;
using eShopOnContainers.Core.Models.Orders;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.Core.Services.Catalog;
using eShopOnContainers.Core.Services.Basket;
using eShopOnContainers.Core.Services.Order;
@ -13,17 +13,10 @@ namespace eShopOnContainers.Core.ViewModels
{
private Order _order;
private IBasketService _orderService;
private ICatalogService _catalogService;
private IOrderService _ordersService;
public OrderDetailViewModel(
IBasketService orderService,
ICatalogService catalogService,
IOrderService ordersService)
public OrderDetailViewModel(IOrderService ordersService)
{
_orderService = orderService;
_catalogService = catalogService;
_ordersService = ordersService;
}


+ 1
- 1
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs View File

@ -3,7 +3,7 @@ using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.Models.Orders;
using eShopOnContainers.Core.Models.User;
using eShopOnContainers.Core.Services.Order;
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;


+ 2
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/SettingsViewModel.cs View File

@ -1,4 +1,4 @@
using eShopOnContainers.ViewModels.Base;
using eShopOnContainers.Core.ViewModels.Base;
using System.Windows.Input;
using Xamarin.Forms;
using System.Threading.Tasks;
@ -71,7 +71,7 @@ namespace eShopOnContainers.Core.ViewModels
private void MockServices()
{
ViewModelLocator.Instance.UpdateDependencies(!UseAzureServices);
ViewModelLocator.UpdateDependencies(!UseAzureServices);
UpdateInfo();
}


+ 4
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/BasketView.xaml View File

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.BasketView"
x:Class="eShopOnContainers.Core.Views.BasketView"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
Title="Cart">
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="Cart">
<ContentPage.Resources>
<ResourceDictionary>


+ 5
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CatalogView.xaml View File

@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.CatalogView"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core"
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core"
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="Catalog">
<ContentPage.Resources>
<ResourceDictionary>


+ 2
- 5
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CatalogView.xaml.cs View File

@ -8,17 +8,15 @@ namespace eShopOnContainers.Core.Views
{
public partial class CatalogView : ContentPage, IMenuContainerPage
{
private FiltersView _filterView;
private FiltersView _filterView = new FiltersView();
public CatalogView()
{
InitializeComponent();
_filterView = new FiltersView();
SlideMenu = _filterView;
MessagingCenter.Subscribe<CatalogViewModel>(this, MessengerKeys.Filter, (sender) =>
MessagingCenter.Subscribe<CatalogViewModel>(this, MessageKeys.Filter, (sender) =>
{
Filter();
});
@ -42,7 +40,6 @@ namespace eShopOnContainers.Core.Views
set;
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();


+ 8
- 10
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CheckoutView.xaml View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.CheckoutView"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
x:Class="eShopOnContainers.Core.Views.CheckoutView"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="Checkout">
<ContentPage.Resources>
<ResourceDictionary>
@ -82,8 +84,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- ORDER INFO -->
<Grid
x:Name="OrderInfo">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
@ -139,8 +140,7 @@
</Grid>
<!-- SHIPPING ADDRESS -->
<Grid
x:Name="ShippingAddress"
Grid.Row="1"
Grid.Row="1"
Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@ -167,9 +167,7 @@
</StackLayout>
</Grid>
<!-- ORDER ITEMS -->
<Grid
x:Name="OrderItems"
Grid.Row="2">
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />


+ 39
- 7
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml View File

@ -2,9 +2,11 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.LoginView"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core"
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core">
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true">
<ContentPage.Title>
<OnPlatform
x:TypeArguments="x:String"
@ -175,30 +177,60 @@
Margin="24">
<Label
Text="User name or email"
Style="{StaticResource HeaderLabelStyle}"/>
<Entry
Text="{Binding UserName.Value, Mode=TwoWay}">
<Entry.Style>
Style="{StaticResource HeaderLabelStyle}" />
<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
<Entry.Style>
<OnPlatform x:TypeArguments="Style"
iOS="{StaticResource EntryStyle}"
Android="{StaticResource EntryStyle}"
WinPhone="{StaticResource UwpEntryStyle}"/>
</Entry.Style>
<Entry.Behaviors>
<behaviors:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding ValidateUserNameCommand}" />
</Entry.Behaviors>
<Entry.Triggers>
<DataTrigger
TargetType="Entry"
Binding="{Binding UserName.IsValid}"
Value="False">
<Setter Property="behaviors:LineColorBehavior.LineColor" Value="{StaticResource ErrorColor}" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label
Text="{Binding UserName.Errors, Converter={StaticResource FirstValidationErrorConverter}"
Style="{StaticResource ValidationErrorLabelStyle}" />
<Label
Text="Password"
Style="{StaticResource HeaderLabelStyle}"/>
<Entry
IsPassword="True"
Text="{Binding Password.Value, Mode=TwoWay}"
Style="{StaticResource EntryStyle}">
Text="{Binding Password.Value, Mode=TwoWay}">
<Entry.Style>
<OnPlatform x:TypeArguments="Style"
iOS="{StaticResource EntryStyle}"
Android="{StaticResource EntryStyle}"
WinPhone="{StaticResource UwpEntryStyle}"/>
</Entry.Style>
<Entry.Behaviors>
<behaviors:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding ValidatePasswordCommand}" />
</Entry.Behaviors>
<Entry.Triggers>
<DataTrigger
TargetType="Entry"
Binding="{Binding Password.IsValid}"
Value="False">
<Setter Property="behaviors:LineColorBehavior.LineColor" Value="{StaticResource ErrorColor}" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label
Text="{Binding Password.Errors, Converter={StaticResource FirstValidationErrorConverter}"
Style="{StaticResource ValidationErrorLabelStyle}" />
</StackLayout>
<!-- LOGIN BUTTON -->
<Grid


+ 16
- 16
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/LoginView.xaml.cs View File

@ -1,5 +1,4 @@
using eShopOnContainers.Core.Helpers;
using eShopOnContainers.Core.ViewModels;
using eShopOnContainers.Core.ViewModels;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
@ -22,14 +21,16 @@ namespace eShopOnContainers.Core.Views
this.Content = null;
this.Content = content;
_animate = true;
await AnimateIn();
var vm = BindingContext as LoginViewModel;
if(vm != null)
var vm = BindingContext as LoginViewModel;
if (vm != null)
{
vm.InvalidateMock();
if (!vm.IsMock)
{
_animate = true;
await AnimateIn();
}
}
}
@ -54,14 +55,13 @@ namespace eShopOnContainers.Core.Views
{
while (_animate)
{
await uiElement.ScaleTo(1.05, duration, Easing.SinInOut);
await Task.WhenAll(
uiElement.FadeTo(1, duration, Easing.SinInOut),
uiElement.LayoutTo(new Rectangle(new Point(0, 0), new Size(uiElement.Width, uiElement.Height))),
uiElement.FadeTo(.9, duration, Easing.SinInOut),
uiElement.ScaleTo(1.15, duration, Easing.SinInOut)
);
await uiElement.ScaleTo(1.05, duration, Easing.SinInOut);
await Task.WhenAll(
uiElement.FadeTo(1, duration, Easing.SinInOut),
uiElement.LayoutTo(new Rectangle(new Point(0, 0), new Size(uiElement.Width, uiElement.Height))),
uiElement.FadeTo(.9, duration, Easing.SinInOut),
uiElement.ScaleTo(1.15, duration, Easing.SinInOut)
);
}
}
catch (Exception ex)


+ 4
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/MainView.xaml View File

@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.MainView"
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:controls="clr-namespace:eShopOnContainers.Core.Controls;assembly=eShopOnContainers.Core"
BarBackgroundColor="{StaticResource DarkGreenColor}"
BackgroundColor="{StaticResource BackgroundColor}"
BarTextColor="{StaticResource WhiteColor}">
BarTextColor="{StaticResource WhiteColor}"
viewModelBase:ViewModelLocator.AutoWireViewModel="true">
<TabbedPage.Title>
<OnPlatform
x:TypeArguments="x:String"


+ 4
- 13
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/MainView.xaml.cs View File

@ -1,6 +1,5 @@
using eShopOnContainers.Core.ViewModels;
using eShopOnContainers.Core.ViewModels.Base;
using eShopOnContainers.ViewModels.Base;
using Xamarin.Forms;
namespace eShopOnContainers.Core.Views
@ -16,7 +15,7 @@ namespace eShopOnContainers.Core.Views
{
base.OnAppearing();
MessagingCenter.Subscribe<MainViewModel, int>(this, MessengerKeys.ChangeTab, (sender, arg) =>
MessagingCenter.Subscribe<MainViewModel, int>(this, MessageKeys.ChangeTab, (sender, arg) =>
{
switch(arg)
{
@ -32,17 +31,9 @@ namespace eShopOnContainers.Core.Views
}
});
var homeViewModel = ViewModelLocator.Instance.Resolve<CatalogViewModel>();
await homeViewModel.InitializeAsync(null);
HomeView.BindingContext = homeViewModel;
var basketViewModel = ViewModelLocator.Instance.Resolve<BasketViewModel>();
await basketViewModel.InitializeAsync(null);
BasketView.BindingContext = basketViewModel;
var profileViewModel = ViewModelLocator.Instance.Resolve<ProfileViewModel>();
await profileViewModel.InitializeAsync(null);
ProfileView.BindingContext = profileViewModel;
await ((CatalogViewModel)HomeView.BindingContext).InitializeAsync(null);
await ((BasketViewModel)BasketView.BindingContext).InitializeAsync(null);
await ((ProfileViewModel)ProfileView.BindingContext).InitializeAsync(null);
}
}
}

+ 4
- 2
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/OrderDetailView.xaml View File

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.OrderDetailView"
x:Class="eShopOnContainers.Core.Views.OrderDetailView"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core"
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="{Binding Order.OrderNumber}">
<ContentPage.Resources>
<ResourceDictionary>


+ 6
- 4
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/ProfileView.xaml View File

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.ProfileView"
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core"
x:Class="eShopOnContainers.Core.Views.ProfileView"
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="My profile">
<ContentPage.Resources>
<ResourceDictionary>


+ 5
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/SettingsView.xaml View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="eShopOnContainers.Core.Views.SettingsView"
x:Class="eShopOnContainers.Core.Views.SettingsView"
xmlns:viewModelBase="clr-namespace:eShopOnContainers.Core.ViewModels.Base;assembly=eShopOnContainers.Core"
xmlns:controls="clr-namespace:eShopOnContainers.Core.Controls;assembly=eShopOnContainers.Core"
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core"
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
xmlns:behaviors="clr-namespace:eShopOnContainers.Core.Behaviors;assembly=eShopOnContainers.Core"
viewModelBase:ViewModelLocator.AutoWireViewModel="true"
Title="Settings">
<ContentPage.Resources>
<ResourceDictionary>


+ 4
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Core/eShopOnContainers.Core.csproj View File

@ -58,9 +58,7 @@
<Compile Include="Converters\ItemsToHeightConverter.cs" />
<Compile Include="Converters\ItemTappedEventArgsConverter.cs" />
<Compile Include="Converters\ToUpperConverter.cs" />
<Compile Include="Effects\LineColorEffect.cs" />
<Compile Include="Exceptions\ServiceAuthenticationException.cs" />
<Compile Include="Extensions\AnimationExtension.cs" />
<Compile Include="Extensions\ObservableExtension.cs" />
<Compile Include="GlobalSettings.cs" />
<Compile Include="Helpers\EasingHelper.cs" />
@ -111,7 +109,7 @@
<Compile Include="Validations\IValidity.cs" />
<Compile Include="Validations\ValidatableObject.cs" />
<Compile Include="ViewModels\Base\ExtendedBindableObject.cs" />
<Compile Include="ViewModels\Base\MessengerKeys.cs" />
<Compile Include="ViewModels\Base\MessageKeys.cs" />
<Compile Include="ViewModels\Base\ViewModelBase.cs" />
<Compile Include="ViewModels\Base\ViewModelLocator.cs" />
<Compile Include="ViewModels\BasketViewModel.cs" />
@ -165,6 +163,9 @@
<DependentUpon>ProductTemplate.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\WebNavigatingEventArgsConverter.cs" />
<Compile Include="Converters\FirstValidationErrorConverter.cs" />
<Compile Include="Effects\EntryLineColorEffect.cs" />
<Compile Include="Behaviors\LineColorBehavior.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />


+ 3
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Droid/Effects/EntryLineColorEffect.cs View File

@ -3,7 +3,7 @@ using eShopOnContainers.Droid.Effects;
using Xamarin.Forms.Platform.Android;
using System;
using Android.Widget;
using eShopOnContainers.Core.Effects;
using eShopOnContainers.Core.Behaviors;
using System.ComponentModel;
using System.Diagnostics;
@ -34,7 +34,7 @@ namespace eShopOnContainers.Droid.Effects
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
if (args.PropertyName == LineColorEffect.LineColorProperty.PropertyName)
if (args.PropertyName == LineColorBehavior.LineColorProperty.PropertyName)
{
UpdateLineColor();
}
@ -46,7 +46,7 @@ namespace eShopOnContainers.Droid.Effects
{
if (control != null)
{
control.Background.SetColorFilter(LineColorEffect.GetLineColor(Element).ToAndroid(), Android.Graphics.PorterDuff.Mode.SrcAtop);
control.Background.SetColorFilter(LineColorBehavior.GetLineColor(Element).ToAndroid(), Android.Graphics.PorterDuff.Mode.SrcAtop);
}
}
catch (Exception ex)


+ 3
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.Windows/Effects/EntryLineColorEffect.cs View File

@ -8,7 +8,7 @@ using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using Windows.UI.Xaml.Controls;
using eShopOnContainers.Windows.Effects;
using eShopOnContainers.Core.Effects;
using eShopOnContainers.Core.Behaviors;
[assembly: ResolutionGroupName("eShopOnContainers")]
[assembly: ExportEffect(typeof(EntryLineColorEffect), "EntryLineColorEffect")]
@ -38,7 +38,7 @@ namespace eShopOnContainers.Windows.Effects
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
if (args.PropertyName == LineColorEffect.LineColorProperty.PropertyName)
if (args.PropertyName == LineColorBehavior.LineColorProperty.PropertyName)
{
UpdateLineColor();
}
@ -49,7 +49,7 @@ namespace eShopOnContainers.Windows.Effects
if (control != null)
{
control.BorderThickness = new Xaml.Thickness(0, 0, 0, 1);
var lineColor = XamarinFormColorToWindowsColor(LineColorEffect.GetLineColor(Element));
var lineColor = XamarinFormColorToWindowsColor(LineColorBehavior.GetLineColor(Element));
control.BorderBrush = new Media.SolidColorBrush(lineColor);
var style = Xaml.Application.Current.Resources["FormTextBoxStyle"] as Xaml.Style;


+ 3
- 3
src/Mobile/eShopOnContainers/eShopOnContainers.iOS/Effects/EntryLineColorEffect.cs View File

@ -1,6 +1,6 @@
using CoreAnimation;
using CoreGraphics;
using eShopOnContainers.Core.Effects;
using eShopOnContainers.Core.Behaviors;
using eShopOnContainers.iOS.Effects;
using System;
using System.ComponentModel;
@ -39,7 +39,7 @@ namespace eShopOnContainers.iOS.Effects
{
base.OnElementPropertyChanged(args);
if (args.PropertyName == LineColorEffect.LineColorProperty.PropertyName ||
if (args.PropertyName == LineColorBehavior.LineColorProperty.PropertyName ||
args.PropertyName == "Height")
{
Initialize();
@ -71,7 +71,7 @@ namespace eShopOnContainers.iOS.Effects
}
lineLayer.Frame = new CGRect(0f, Control.Frame.Height - 1f, Control.Bounds.Width, 1f);
lineLayer.BorderColor = LineColorEffect.GetLineColor(Element).ToCGColor();
lineLayer.BorderColor = LineColorBehavior.GetLineColor(Element).ToCGColor();
control.TintColor = control.TextColor;
}


+ 2
- 1
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -20,6 +20,7 @@
using System.IO;
using System.Data.Common;
using System.Reflection;
using System.Threading.Tasks;
public class Startup
{
@ -48,7 +49,7 @@
services.AddHealthChecks(checks =>
{
checks.AddUrlCheck(Configuration["ExternalCatalogBaseUrl"]);
checks.AddSqlCheck("Catalog_Db", Configuration["ConnectionString"]);
});
services.AddMvc(options =>


+ 42
- 0
src/Services/Identity/Identity.API/Certificate/Certificate.cs View File

@ -0,0 +1,42 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
namespace Identity.API.Certificate
{
static class Certificate
{
public static X509Certificate2 Get()
{
var assembly = typeof(Certificate).GetTypeInfo().Assembly;
var names = assembly.GetManifestResourceNames();
/***********************************************************************************************
* Please note that here we are using a local certificate only for testing purposes. In a
* real environment the certificate should be created and stored in a secure way, which is out
* of the scope of this project.
**********************************************************************************************/
using (var stream = assembly.GetManifestResourceStream("Identity.API.Certificate.idsrv3test.pfx"))
{
return new X509Certificate2(ReadStream(stream), "idsrv3test");
}
}
private static byte[] ReadStream(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
}

BIN
src/Services/Identity/Identity.API/Certificate/idsrv3test.pfx View File


+ 5
- 1
src/Services/Identity/Identity.API/Identity.API.csproj View File

@ -12,7 +12,7 @@
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.0" />
@ -57,6 +57,10 @@
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Certificate\idsrv3test.pfx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.Data\Microsoft.Extensions.HealthChecks.Data.csproj" />


+ 2
- 1
src/Services/Identity/Identity.API/Startup.cs View File

@ -18,6 +18,7 @@ using System.Threading;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.HealthChecks;
using Identity.API.Certificate;
namespace eShopOnContainers.Identity
{
@ -75,7 +76,7 @@ namespace eShopOnContainers.Identity
// Adds IdentityServer
services.AddIdentityServer(x => x.IssuerUri = "null")
.AddTemporarySigningCredential()
.AddSigningCredential(Certificate.Get())
.AddInMemoryScopes(Config.GetScopes())
.AddInMemoryClients(Config.GetClients(clientUrls))
.AddAspNetIdentity<ApplicationUser>()


+ 1
- 0
src/Web/WebMVC/Services/Utilities/ResilientHttpClient.cs View File

@ -13,6 +13,7 @@ namespace WebMVC.Services.Utilities
/// <summary>
/// HttpClient wrapper that integrates Retry and Circuit
/// breaker policies when invoking HTTP services.
/// Based on Polly library: https://github.com/App-vNext/Polly
/// </summary>
public class ResilientHttpClient : IHttpClient
{


+ 4
- 1
src/Web/WebMVC/Startup.cs View File

@ -48,7 +48,10 @@ namespace Microsoft.eShopOnContainers.WebMVC
services.AddHealthChecks(checks =>
{
checks.AddUrlCheck(Configuration["CallBackUrl"]);
checks.AddUrlCheck(Configuration["CatalogUrl"]);
checks.AddUrlCheck(Configuration["OrderingUrl"]);
checks.AddUrlCheck(Configuration["BasketUrl"]);
checks.AddUrlCheck(Configuration["IdentityUrl"]);
});
// Add application services.


Loading…
Cancel
Save