/// <summary> /// Executes appropriate handler based on actual type of the <paramref name="view"/>. /// </summary> /// <param name="view">The view that is represented by a navigation or view controller.</param> /// <param name="navigationControllerHandler">The handler to execute if <paramref name="view"/> is <see cref="UINavigationController"/>.</param> /// <param name="viewControllerHandler">The handler to execute if <paramref name="view"/> is <see cref="UIViewController"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="view" /> or <paramref name="navigationControllerHandler" /> or <paramref name="viewControllerHandler" /> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="view" /> is derived from a class other than the <see cref="UINavigationController"/> or <see cref="UIViewController"/>. /// </exception> public static void As( this IView <ILifecycleViewModel> view, Action <UINavigationController> navigationControllerHandler, Action <UIViewController> viewControllerHandler) { if (view == null) { throw new ArgumentNullException(nameof(view)); } if (navigationControllerHandler == null) { throw new ArgumentNullException(nameof(navigationControllerHandler)); } if (viewControllerHandler == null) { throw new ArgumentNullException(nameof(viewControllerHandler)); } if (view is UINavigationController navigationController) { navigationControllerHandler(navigationController); } else if (view is UIViewController viewController) { viewControllerHandler(viewController); } else { throw new ArgumentException( $"Only views derived from the '{TypeFormatter.FormatName<UINavigationController>()}' or " + $"'{TypeFormatter.FormatName<UIViewController>()}' are supported.", nameof(view)); } }
internal static TView Get <TView, TViewModel>(TViewModel viewModel) where TView : class, IView <TViewModel> where TViewModel : class, ILifecycleViewModel { TView?view = null; for (var i = ViewsWeakReferences.Count - 1; i > -1; i--) { var viewWeakReference = ViewsWeakReferences[i]; if (viewWeakReference.TryGetTarget(out var cachedView)) { if (ReferenceEquals(cachedView.ViewModel, viewModel)) { view = (TView)cachedView; break; } } else { ViewsWeakReferences.Remove(viewWeakReference); } } if (view == null) { throw new InvalidOperationException( $"The view instance is missing for the provided '{TypeFormatter.FormatName(viewModel.GetType())}' view model one."); } return(view); }
/// <summary> /// Executes appropriate handler based on actual type of the <paramref name="view"/> with returning a result. /// </summary> /// <typeparam name="T">The type of the result.</typeparam> /// <param name="view">The view that is represented by the <see cref="UIViewController"/> or <see cref="UINavigationController"/>.</param> /// <param name="viewControllerHandler">The handler to execute when the <paramref name="view"/> is <see cref="UIViewController"/>.</param> /// <param name="navigationControllerHandler"> /// The handler to execute when the <paramref name="view"/> is <see cref="UINavigationController"/>. Can be <see langword="null"/>. /// <para>If the <paramref name="navigationControllerHandler"/> is <see langword="null"/> then the <paramref name="viewControllerHandler"/> will be used as a handler.</para> /// </param> /// <returns>A result returned by appropriate handler.</returns> /// <exception cref="ArgumentNullException"><paramref name="view" /> or <paramref name="viewControllerHandler" /> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="view" /> is derived from a class other than the <see cref="UIViewController"/>. /// </exception> public static T As <T>( this IView <ILifecycleViewModel> view, Func <UIViewController, T> viewControllerHandler, Func <UINavigationController, T>?navigationControllerHandler = null) { if (view == null) { throw new ArgumentNullException(nameof(view)); } if (viewControllerHandler == null) { throw new ArgumentNullException(nameof(viewControllerHandler)); } T result; if (view is UINavigationController navigationController) { result = (navigationControllerHandler ?? viewControllerHandler)(navigationController); } else if (view is UIViewController viewController) { result = viewControllerHandler(viewController); } else { throw new ArgumentException($"Only views derived from the '{TypeFormatter.FormatName<UIViewController>()}' type are supported.", nameof(view)); } return(result); }
/// <summary> /// Executes appropriate handler based on actual type of the <paramref name="view"/>. /// </summary> /// <param name="view">The view that is represented by an activity or fragment.</param> /// <param name="activityHandler">The handler to execute if <paramref name="view"/> is <see cref="Android.Support.V4.App.FragmentActivity"/>.</param> /// <param name="fragmentHandler">The handler to execute if <paramref name="view"/> is <see cref="Android.Support.V4.App.Fragment"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="view" /> or <paramref name="activityHandler" /> or <paramref name="fragmentHandler" /> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="view" /> is derived from a class other than the <see cref="Android.Support.V4.App.FragmentActivity"/> or <see cref="Android.Support.V4.App.Fragment"/>. /// </exception> public static void As( this IView <ILifecycleViewModel> view, Action <FragmentActivity> activityHandler, Action <Fragment> fragmentHandler) { if (view == null) { throw new ArgumentNullException(nameof(view)); } if (activityHandler == null) { throw new ArgumentNullException(nameof(activityHandler)); } if (fragmentHandler == null) { throw new ArgumentNullException(nameof(fragmentHandler)); } if (view is FragmentActivity activity) { activityHandler(activity); } else if (view is Fragment fragment) { fragmentHandler(fragment); } else { throw new ArgumentException( $"Only views derived from the '{TypeFormatter.FormatName<FragmentActivity>()}' or " + $"'{TypeFormatter.FormatName<Fragment>()}' are supported.", nameof(view)); } }
/// <summary> /// Performs forward navigation from the <paramref name="sourceView"/> to the target one with the provided lifecycle-aware view model <paramref name="parameters"/> /// and handling a lifecycle-aware view model result when it finished. /// </summary> /// <typeparam name="TTargetView">The type of the target view.</typeparam> /// <typeparam name="TParameters">The type of the target view model parameters.</typeparam> /// <typeparam name="TResult">The type of the target view model result.</typeparam> /// <param name="sourceView">The source navigation view from which navigation is performed from.</param> /// <param name="parameters">The target view model parameters. Can be <see langword="null"/>.</param> /// <param name="navigationStrategy"> /// The strategy used for performing navigation. Can be <see langword="null"/>. /// <para>The default is <see cref="ForwardNavigationStrategy.StartActivityForResult(Bundle?)"/>.</para> /// </param> /// <exception cref="ArgumentNullException"><paramref name="sourceView"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="sourceView" /> is derived from a class other than the <see cref="FragmentActivity"/> or <see cref="Fragment"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// <see cref="NavigationViewExtensions.GetActivity(INavigationView{ILifecycleViewModel})"/> returned <see langword="null"/> value for the provided <paramref name="sourceView"/>. /// </exception> public void NavigateForResult <TTargetView, TParameters, TResult>( INavigationView <ILifecycleViewModelWithResultHandler> sourceView, TParameters?parameters, ForwardNavigationDelegate?navigationStrategy = null) where TTargetView : FragmentActivity, INavigationView <ILifecycleViewModelWithParameters <TParameters> >, INavigationView <ILifecycleViewModelWithResult <TResult> > where TParameters : Parameters where TResult : Result { if (sourceView == null) { throw new ArgumentNullException(nameof(sourceView)); } var context = sourceView.GetActivity(); if (context == null) { throw new InvalidOperationException( $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetActivity)}' returned 'null' value."); } var targetViewIntent = new Intent(context, typeof(TTargetView)); targetViewIntent.PutParameters(parameters); var requestCode = sourceView.RequestCode.GetFor <DefaultResultMapper <TResult> >(); (navigationStrategy ?? NavigationStrategy.Forward.StartActivityForResult()).Invoke(sourceView, targetViewIntent, requestCode); }
public object ConvertBack(object value, Type targetType) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } var valueConverter = ValueConverterProvider.Get <TValueConverter>(); var convertedValue = BindingValue.UnsetValue; if (TryGetParameter(out var parameter)) { try { convertedValue = valueConverter.ConvertBack(value, targetType, parameter, _converterCulture); } catch (Exception ex) { Log($"An \"{LogFormatter.FormatException(ex)}\" exception occurred while converting \"{value ?? "null"}\" value from the target item to the source one " + $"using \"{TypeFormatter.FormatName<TValueConverter>()}\" value converter."); } } return(convertedValue); }
void ICommand.Execute(object parameter) { if (parameter != null) { throw new ArgumentException( $"\"{_name.SelfOrDefaultIfNullOrWhiteSpace(TypeFormatter.FormatName(GetType()))}\" command expects \"null\" value.", nameof(parameter)); } Execute(); }
public static T NotNull <T>( [AllowNull] this T value, [CallerMemberName] string?memberName = null, [CallerFilePath] string?filePath = null, [CallerLineNumber] int lineNumber = 0) { if (value != null) { return(value); } throw new AssertionException($"Value of type '{TypeFormatter.FormatName<T>()}' is null at {memberName}, {filePath}:{lineNumber}"); }
public TViewModel Create <TViewModel>() where TViewModel : class, IViewModel { var viewModel = CreateInstance <TViewModel>(); if (viewModel == null) { throw new InvalidOperationException( $"\"{TypeFormatter.FormatName(GetType())}\" returned \"null\" for the \"{TypeFormatter.FormatName<TViewModel>()}>\" view model instance."); } return(viewModel); }
/// <summary> /// Forward navigation using the <see cref="UINavigationController.SetViewControllers(UIViewController[], bool)"/> method. Target view delegate parameter is passed as a value. /// </summary> /// <returns>The forward navigation delegate.</returns> public ForwardNavigationDelegate SetViewControllers() { return((sourceView, targetView, animated) => { var navigationController = sourceView.GetNavigationController(); if (navigationController == null) { throw new InvalidOperationException( $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetNavigationController)}' returned 'null' value."); } navigationController.SetViewControllers(new UIViewController[] { targetView }, animated); }); }
/// <summary> /// Backward navigation using the <see cref="UINavigationController.PopToRootViewController(bool)"/> method. /// </summary> /// <returns>The backward navigation delegate.</returns> public BackwardNavigationDelegate PopToRootViewController() { return((sourceView, animated) => { var navigationController = sourceView.GetNavigationController(); if (navigationController == null) { throw new InvalidOperationException( $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetNavigationController)}' returned 'null' value."); } navigationController.PopToRootViewController(animated); }); }
public static INavigationView <ILifecycleViewModelWithResultHandler> Get(ILifecycleViewModelWithResultHandler viewModel) { if (viewModel == null) { throw new ArgumentNullException(nameof(viewModel)); } if (!ViewRegistry.TryGetView <ILifecycleViewModelWithResultHandler, INavigationView <ILifecycleViewModelWithResultHandler> >(viewModel, out var view)) { throw new InvalidOperationException( $"The view instance is missing for the provided '{TypeFormatter.FormatName(viewModel.GetType())}' view model."); } return(view); }
/// <summary> /// Backward navigation using the <see cref="UINavigationController.PopViewController(bool)"/> method. /// </summary> /// <returns>The backward navigation delegate.</returns> public ViewControllerBackwardNavigationDelegate PopViewController() { return((sourceView, animated) => { if (sourceView.NavigationController != null) { sourceView.NavigationController.PopViewController(animated); } else { Logger.LogDebug( $"Unable to pop '{TypeFormatter.FormatName(sourceView.GetType())}' instance due to " + $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(UIViewController.NavigationController)}' is 'null'."); } }); }
public static TView GetFragment <TView, TViewModel>(TViewModel viewModel) where TView : Fragment, INavigationView <TViewModel> where TViewModel : class, ILifecycleViewModel { if (viewModel == null) { throw new ArgumentNullException(nameof(viewModel)); } if (!ViewRegistry.TryGetView <TViewModel, TView>(viewModel, out var view)) { throw new InvalidOperationException( $"The view instance is missing for the provided '{TypeFormatter.FormatName(viewModel.GetType())}' view model."); } return(view); }
/// <summary> /// Forward navigation using the <see cref="UINavigationController.PushViewController(UIViewController, bool)"/> method. /// </summary> /// <returns>The forward navigation delegate.</returns> public ViewControllerForwardNavigationDelegate PushViewController() { return((sourceView, targetView, animated) => { var navigationController = sourceView.GetNavigationController(); if (navigationController != null) { navigationController.PushViewController(targetView, animated); } else { Logger.LogDebug( $"Unable to push '{TypeFormatter.FormatName(targetView.GetType())}' instance due to " + $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetNavigationController)}' returned 'null' value."); } }); }
/// <summary> /// Returns an existing lifecycle-aware <typeparamref name="TViewModel"/> instance by <paramref name="key"/> if it is presented in the <paramref name="store"/>, /// or creates a new one using the <paramref name="factory"/> with restoring its <paramref name="state"/>. /// </summary> /// <typeparam name="TViewModel">The type of the view model to get.</typeparam> /// <param name="store">The view model store.</param> /// <param name="key">The view model unique key.</param> /// <param name="factory">The view model factory.</param> /// <param name="state">The view model state bundle.</param> /// <param name="created"><see langword="true"/> if the view model is created by the <paramref name="factory"/>; otherwise, <see langword="false"/>.</param> /// <returns>The view model instance.</returns> /// <exception cref="ArgumentNullException"><paramref name="store"/> or <paramref name="key"/> or <paramref name="factory"/> is <see langword="null"/>.</exception> /// <exception cref="InvalidOperationException">The <paramref name="factory"/> returned <see langword="null"/> value for the <typeparamref name="TViewModel"/>.</exception> public static TViewModel Get <TViewModel>( ILifecycleViewModelStore store, string key, ILifecycleViewModelFactory factory, IBundle?state, out bool created) where TViewModel : class, ILifecycleViewModel, IStateOwner { if (store == null) { throw new ArgumentNullException(nameof(store)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (factory == null) { throw new ArgumentNullException(nameof(factory)); } var viewModel = store.Get <TViewModel>(key); created = false; if (viewModel == null) { viewModel = factory.Create <TViewModel>(); if (viewModel == null) { throw new InvalidOperationException( $"'{TypeFormatter.FormatName(factory.GetType())}.{nameof(ILifecycleViewModelFactory.Create)}' " + $"returned 'null' value for the '{TypeFormatter.FormatName<TViewModel>()}>' view model."); } viewModel.ImportState(state); store.Add(key, viewModel); created = true; } return(viewModel); }
public object GetService(Type serviceType) { if (_itemsProviders != null && _itemsProviders.TryGetValue(serviceType, out var itemProvider)) { var instance = itemProvider.Get(); if (instance == null) { throw new InvalidOperationException( $"\"{TypeFormatter.FormatName<IDependencyProvider>()}.{nameof(IDependencyProvider.Get)}\" " + $"returned \"null\" for the \"{TypeFormatter.FormatName(serviceType)}>\" type instance."); } return(instance); } throw new InvalidOperationException( $"Instance factory is not registered for the \"{TypeFormatter.FormatName(serviceType)}\" type. " + $"Use \"{TypeFormatter.FormatName<ISimpleIoc>()}.{nameof(ISimpleIoc.Register)}\" method for the factory registration."); }
/// <summary> /// Backward navigation using the <see cref="UINavigationController.PopToViewController(UIViewController, bool)"/> method. /// </summary> /// <param name="targetView">The target view controller for navigation.</param> /// <returns>The backward navigation delegate.</returns> /// <exception cref="ArgumentNullException"><paramref name="targetView"/> is <see langword="null"/>.</exception> public ViewControllerBackwardNavigationDelegate PopToViewController(UIViewController targetView) { if (targetView == null) { throw new ArgumentNullException(nameof(targetView)); } return((sourceView, animated) => { if (sourceView.NavigationController != null) { sourceView.NavigationController.PopToViewController(targetView, animated); } else { Logger.LogDebug( $"Unable to pop to '{TypeFormatter.FormatName(targetView.GetType())}' instance due to " + $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(UIViewController.NavigationController)}' is 'null'."); } }); }
/// <summary> /// Performs forward navigation from the <paramref name="sourceView"/> to the target one. /// </summary> /// <typeparam name="TTargetView">The type of the target view.</typeparam> /// <param name="sourceView">The source navigation view from which navigation is performed from.</param> /// <param name="navigationStrategy"> /// The strategy used for performing navigation. Can be <see langword="null"/>. /// <para>The default is <see cref="ForwardNavigationStrategy.StartActivity(Bundle?)"/>.</para> /// </param> /// <exception cref="ArgumentNullException"><paramref name="sourceView"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="sourceView" /> is derived from a class other than the <see cref="FragmentActivity"/> or <see cref="Fragment"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// <see cref="NavigationViewExtensions.GetActivity(INavigationView{ILifecycleViewModel})"/> returned <see langword="null"/> value for the provided <paramref name="sourceView"/>. /// </exception> public void Navigate <TTargetView>( INavigationView <ILifecycleViewModel> sourceView, ForwardNavigationDelegate?navigationStrategy = null) where TTargetView : FragmentActivity { if (sourceView == null) { throw new ArgumentNullException(nameof(sourceView)); } var context = sourceView.GetActivity(); if (context == null) { throw new InvalidOperationException( $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetActivity)}' returned 'null' value."); } var targetViewIntent = new Intent(context, typeof(TTargetView)); (navigationStrategy ?? NavigationStrategy.Forward.StartActivity()).Invoke(sourceView, targetViewIntent, RequestCode.InvalidRequestCode); }
public static object GetRequiredService(this IServiceProvider serviceProvider, Type serviceType) { if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } if (serviceType == null) { throw new ArgumentNullException(nameof(serviceType)); } var service = serviceProvider.GetService(serviceType); if (service == null) { throw new InvalidOperationException( $"Service of type '{TypeFormatter.FormatName(serviceType)}' is not registered in the service collection. " + $"Use '{TypeFormatter.FormatName<IServiceCollection>()}.{nameof(IServiceCollection.Add)}' method for the service registration."); } return(service); }
/// <summary> /// Forward navigation using the <see cref="UINavigationController.SetViewControllers(UIViewController[], bool)"/> method. /// </summary> /// <param name="viewControllersProvider">The function that takes the target view delegate parameter as input /// and returns array of <see cref="UIViewController"/> to set.</param> /// <returns>The forward navigation delegate.</returns> /// <exception cref="ArgumentNullException"><paramref name="viewControllersProvider"/> is <see langword="null"/>.</exception> public ViewControllerForwardNavigationDelegate SetViewControllers(Func <UIViewController, UIViewController[]> viewControllersProvider) { if (viewControllersProvider == null) { throw new ArgumentNullException(nameof(viewControllersProvider)); } return((sourceView, targetView, animated) => { var navigationController = sourceView.GetNavigationController(); if (navigationController != null) { navigationController.SetViewControllers(viewControllersProvider(targetView), animated); } else { Logger.LogDebug( $"Unable to set view controllers due to " + $"'{TypeFormatter.FormatName(sourceView.GetType())}.{nameof(NavigationViewExtensions.GetNavigationController)}' returned 'null' value."); } }); }
/// <summary> /// Executes appropriate handler based on actual type of the <paramref name="view"/> with returning a result. /// </summary> /// <typeparam name="T">The type of the result.</typeparam> /// <param name="view">The view that is represented by an activity or fragment.</param> /// <param name="activityHandler">The handler to execute if <paramref name="view"/> is <see cref="Android.Support.V4.App.FragmentActivity"/>.</param> /// <param name="fragmentHandler">The handler to execute if <paramref name="view"/> is <see cref="Android.Support.V4.App.Fragment"/>.</param> /// <returns>A result returned by appropriate handler.</returns> /// <exception cref="ArgumentNullException"><paramref name="view" /> or <paramref name="activityHandler" /> or <paramref name="fragmentHandler" /> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"> /// The <paramref name="view" /> is derived from a class other than the <see cref="Android.Support.V4.App.FragmentActivity"/> or <see cref="Android.Support.V4.App.Fragment"/>. /// </exception> public static T As <T>( this IView <ILifecycleViewModel> view, Func <FragmentActivity, T> activityHandler, Func <Fragment, T> fragmentHandler) { if (view == null) { throw new ArgumentNullException(nameof(view)); } if (activityHandler == null) { throw new ArgumentNullException(nameof(activityHandler)); } if (fragmentHandler == null) { throw new ArgumentNullException(nameof(fragmentHandler)); } T result; if (view is FragmentActivity activity) { result = activityHandler(activity); } else if (view is Fragment fragment) { result = fragmentHandler(fragment); } else { throw new ArgumentException( $"Only views derived from the '{TypeFormatter.FormatName<FragmentActivity>()}' or " + $"'{TypeFormatter.FormatName<Fragment>()}' are supported.", nameof(view)); } return(result); }
internal static TView Get <TView, TViewModel>([NotNull] TViewModel viewModel) where TView : class, IView <TViewModel> where TViewModel : class, IViewModel { TView view = null; if (_viewsWeakReferences != null) { foreach (var viewWeakReference in _viewsWeakReferences) { if (viewWeakReference.TryGetTarget(out var cachedView) && ReferenceEquals(cachedView.ViewModel, viewModel)) { view = (TView)cachedView; break; } } } if (view == null) { throw new ArgumentException($"View instance is missing for provided \"{TypeFormatter.FormatName(viewModel.GetType())}\" view model.", nameof(viewModel)); } return(view); }