Exemplo n.º 1
0
        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)));
        }
Exemplo n.º 2
0
        /// <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.");
                }
Exemplo n.º 3
0
 /// <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());
     }
 }
Exemplo n.º 4
0
 public void Debug()
 {
     if (existingLogger.Level >= LogLevel.Debug)
     {
         existingLogger.Debug("df");
     }
 }
Exemplo n.º 5
0
        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")));
            })));
        }
Exemplo n.º 6
0
 /// <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);
     }
 }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        /// <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();
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        /// <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());
            }
        }
Exemplo n.º 12
0
        /// <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();
        }
Exemplo n.º 13
0
        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) !);
            }
        }