public static IObservable <T> CacheApiResult <T>( this IObservable <T> source, string cacheKey, IBlobCache blobCache, IFullLogger?logger = null, IScheduler?scheduler = null, bool forceUpdate = false, TimeSpan expiration = default) { expiration = expiration == TimeSpan.Zero ? Constants.DefaultCacheExpirationTimeOut : expiration; if (forceUpdate) { // TODO: [rlittlesii: July 30, 2020] Add retry and cached return(source.SelectMany(async value => { await blobCache.InsertObject(cacheKey, value, expiration); logger?.Debug($"CACHE: Writing {{Value}} to cache with key: {{CacheKey}}", value, cacheKey); return value; })); } blobCache .GetObject <T>(cacheKey) .Subscribe(obj => logger?.Debug("Found: {@Object}", obj)); // TODO: [rlittlesii: July 30, 2020] Add retry and cached return(blobCache .GetOrFetchObject( cacheKey, () => source.Timeout(Constants.DefaultRequestTimeout), DateTimeOffset.Now.Add(expiration))); }
/// <summary> /// Initializes a new instance of the <see cref="NavigationView"/> class. /// </summary> /// <param name="mainScheduler">The main scheduler to scheduler UI tasks on.</param> /// <param name="backgroundScheduler">The background scheduler.</param> /// <param name="viewLocator">The view locator which will find views associated with view models.</param> public NavigationView(IScheduler mainScheduler, IScheduler backgroundScheduler, IViewLocator viewLocator) { InitializeComponent(); _logger = this.Log(); BackgroundScheduler = backgroundScheduler; MainThreadScheduler = mainScheduler; _viewLocator = viewLocator; _mirroredPageStack = new Stack <IViewModel?>(); _mirroredModalStack = new Stack <IViewModel?>(); backButton.Visibility = Visibility.Collapsed; PagePopped = Observable .FromEvent <NavigatedEventHandler, NavigationEventArgs>( handler => (_, e) => handler(e), x => mainFrame.Navigated += x, x => mainFrame.Navigated -= x) .Do(_ => IsBackButtonVisible = mainFrame.CanGoBack) .Where(ep => ep.NavigationMode == NavigationMode.Back) .Select(ep => { if (!(ep.Content is IViewFor view)) { _logger.Debug($"The view ({ep.Content.GetType()}) does not implement IViewFor<>. Cannot set ViewModel from a back navigation."); }
/// <summary> /// Sends the value provided by the provided delegate, only if Debug is enabled. /// </summary> /// <typeparam name="T">The type of object we are logging about.</typeparam> /// <param name="logger">The logger to use.</param> /// <param name="function">The function to evaluate if Debug logging is enabled.</param> public static void Debug <T>(this IFullLogger logger, Func <string> function) { if (logger.IsDebugEnabled) { logger.Debug <T>(function.Invoke()); } }
public void Debug() { if (existingLogger.Level >= LogLevel.Debug) { existingLogger.Debug("df"); } }
public static IObservable <IChangeSet <TSource, TKey> > CacheChangeSet <TSource, TKey>( this IObservable <IChangeSet <TSource, TKey> > source, string cacheKey, IBlobCache?blobCache = null, IFullLogger?log = default) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (cacheKey == null) { throw new ArgumentNullException(nameof(cacheKey)); } blobCache ??= BlobCache.LocalMachine; return(Observable .Create <IChangeSet <TSource, TKey> >(observer => source .ToCollection() .Concat( blobCache .GetObject <List <TSource> >(cacheKey) .Catch(Observable.Return(new List <TSource>()))) .Subscribe(items => { log?.Debug("CACHE: Writing {Count} items to cache with key: {CacheKey}", items.Count, cacheKey); blobCache .InsertObject(cacheKey, items.ToList()) .Catch(Observable.Return(Unit.Default).Do(unit => log?.Error("Failed to add items to cache"))); }))); }
/// <summary> /// Sends the value provided by the provided delegate, only if Debug is enabled. /// </summary> /// <param name="logger">The logger to use.</param> /// <param name="function">The function to evaluate if Debug logging is enabled.</param> /// <param name="exception">A exception to log about.</param> public static void DebugException(this IFullLogger logger, Func <string> function, Exception exception) { if (logger.IsDebugEnabled) { logger.Debug(function.Invoke(), exception); } }
internal static Dictionary <string, int> GetDrawableList( IFullLogger log, Assembly[] assemblies) { // VS2019 onward var drawableTypes = assemblies .AsParallel() .SelectMany(a => GetTypesFromAssembly(a, log)) .Where(x => x.Name.Equals("Resource", StringComparison.Ordinal) && x.GetNestedType("Drawable") != null) .Select(x => x.GetNestedType("Drawable")) .ToArray(); if (log?.IsDebugEnabled == true) { var output = new StringBuilder(); output.Append("DrawableList. Got ").Append(drawableTypes.Length).AppendLine(" types."); foreach (var drawableType in drawableTypes) { output.Append("DrawableList Type: ").AppendLine(drawableType.Name); } log.Debug(output.ToString()); } var result = drawableTypes .AsParallel() .SelectMany(x => x.GetFields()) .Where(x => x.FieldType == typeof(int) && x.IsLiteral) .ToDictionary(k => k.Name, v => (int)v.GetRawConstantValue()); if (log?.IsDebugEnabled == true) { var output = new StringBuilder(); output.Append("DrawableList. Got ").Append(result.Count).AppendLine(" items."); foreach (var keyValuePair in result) { output.Append("DrawableList Item: ").AppendLine(keyValuePair.Key); } log.Debug(output.ToString()); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="NavigationView"/> class. /// </summary> /// <param name="mainScheduler">The main scheduler to scheduler UI tasks on.</param> /// <param name="backgroundScheduler">The background scheduler.</param> /// <param name="viewLocator">The view locator which will find views associated with view models.</param> public NavigationView(IScheduler mainScheduler, IScheduler backgroundScheduler, IViewLocator viewLocator) { InitializeComponent(); _logger = this.Log(); _backgroundScheduler = backgroundScheduler; _mainScheduler = mainScheduler; _viewLocator = viewLocator; _mirroredPageStack = new Stack <IViewModel?>(); _mirroredModalStack = new Stack <IViewModel?>(); backButton.Visibility = Visibility.Collapsed; PagePopped = Observable .FromEvent <NavigatedEventHandler, NavigationEventArgs>( handler => { return((sender, e) => handler(e)); }, x => mainFrame.Navigated += x, x => mainFrame.Navigated -= x) .Do(args => { if (mainFrame.CanGoBack) { IsBackButtonVisible = true; } else { IsBackButtonVisible = false; } }) .Where(ep => ep.NavigationMode == NavigationMode.Back) .Select(ep => { var view = ep.Content as IViewFor; if (view == null) { _logger.Debug($"The view ({ep.Content.GetType()}) does not implement IViewFor<>. Cannot set ViewModel from a back navigation."); } else { view.ViewModel = _mirroredPageStack.Peek(); } // Since view stack doesn't contain instances (only types), we have to store the latest viewmodel and return it on a back nav. // ep.Content contains an instance of the new view, but it may have just been created and its ViewModel property will be null. // But we want the view that was just removed. We need to send the old view's viewmodel to IViewStackService so that the ViewModel can be removed from the stack. return(_lastPoppedViewModel); }) .WhereNotNull(); BackRequested.Subscribe(); }
private IView LocateNavigationFor(IViewModel viewModel) { var view = _viewLocator.ResolveView(viewModel, "NavigationView"); var navigationPage = view as IView; if (navigationPage is null) { _logger.Debug($"No navigation view could be located for type '{viewModel.GetType().FullName}', using the default navigation page."); navigationPage = Locator.Current.GetService <IView>(nameof(NavigationView)) ?? Locator.Current.GetService <IView>(); } return(navigationPage); }
internal static Dictionary <string, int> GetDrawableList( IFullLogger log, Assembly[] assemblies) { // VS2019 onward var drawableTypes = assemblies .SelectMany(a => GetTypesFromAssembly(a, log)) .Where(x => x.Name == "Resource" && x.GetNestedType("Drawable") != null) .Select(x => x.GetNestedType("Drawable")) .ToArray(); if (log != null) { log.Debug(() => "DrawableList. Got " + drawableTypes.Length + " types."); foreach (var drawableType in drawableTypes) { log.Debug(() => "DrawableList Type: " + drawableType.Name); } } var result = drawableTypes .SelectMany(x => x.GetFields()) .Where(x => x.FieldType == typeof(int) && x.IsLiteral) .ToDictionary(k => k.Name, v => (int)v.GetRawConstantValue()); if (log != null) { log.Debug(() => "DrawableList. Got " + result.Count + " items."); foreach (var keyValuePair in result) { log.Debug(() => "DrawableList Item: " + keyValuePair.Key); } } return(result); }
/// <summary> /// Sends the value provided by the provided delegate, only if Debug is enabled. /// </summary> /// <typeparam name="T">The type of object we are logging about.</typeparam> /// <param name="logger">The logger to use.</param> /// <param name="function">The function to evaluate if Debug logging is enabled.</param> public static void Debug <T>(this IFullLogger logger, Func <string> function) { if (logger is null) { throw new ArgumentNullException(nameof(logger)); } if (function is null) { throw new ArgumentNullException(nameof(function)); } if (logger.IsDebugEnabled) { logger.Debug <T>(function.Invoke()); } }
/// <summary> /// Initializes a new instance of the <see cref="ViewStackService"/> class. /// </summary> /// <param name="view">The view.</param> public ViewStackService(IView view) { _logger = this.Log(); _view = view; _modalStack = new BehaviorSubject <IImmutableList <IPageViewModel> >(ImmutableList <IPageViewModel> .Empty); _pageStack = new BehaviorSubject <IImmutableList <IPageViewModel> >(ImmutableList <IPageViewModel> .Empty); // TODO: Make this SubscribeSafe(); _view.PagePopped.Do(poppedPage => { var currentPageStack = _pageStack.Value; if (currentPageStack.Count > 0 && poppedPage == currentPageStack[currentPageStack.Count - 1]) { var removedPage = PopStackAndTick(_pageStack); _logger.Debug("Removed page '{0}' from stack.", removedPage.Id); } }).SubscribeSafe(); }
public IControl Build(object data) { if (data == null) { _logger.Debug("data was null for ViewLocator"); return(new TextBlock { Text = "Null data" }); } lock (_viewMapping) { Type viewModelType = data.GetType(); if (!_viewMapping.TryGetValue(viewModelType, out Type? viewType)) { ModelForAttribute?modelForAttribute = viewModelType.GetCustomAttribute <ModelForAttribute>(); if (modelForAttribute == null) { _logger.Debug("data has no [ModelFor]"); _viewMapping.Add(viewModelType, null); } else if (modelForAttribute.View == null) { _logger.Debug("data [ModelFor] has no ViewModel"); _viewMapping.Add(viewModelType, null); } else { var viewForAttribute = modelForAttribute.View.GetCustomAttribute <ViewForAttribute>(); if (viewForAttribute == null) { _logger.Debug("data has [ModelFor({0})], but {0} has no corresponding [ViewFor]", viewModelType.Name); _viewMapping.Add(viewModelType, null); } else if (viewForAttribute.ViewModel == null) { _logger.Debug("data has [ModelFor({0})], but {0} has [ViewFor] has no ViewModel", viewModelType.Name); _viewMapping.Add(viewModelType, null); } else if (viewForAttribute.ViewModel != viewModelType) { _logger.Debug("data has [ModelFor({0})], but {0} has mismatched [ViewFor({1}] ", viewModelType.Name, viewForAttribute.ViewModel.Name); _viewMapping.Add(viewModelType, null); } else { _logger.Debug("data has [ModelFor({0})] with matching ViewFor", viewModelType.Name); _viewMapping.Add(viewModelType, modelForAttribute.View); } } } if (!_viewMapping.TryGetValue(viewModelType, out viewType) || viewType == null) { return(new TextBlock { Text = "No view found for : " + viewModelType.Name }); } return((IControl)Activator.CreateInstance(viewType) !); } }