private IDisposable BindCommandInternal <TView, TProp, TParam>(
            IObservable <TProp> @this,
            TView view,
            Expression controlExpression,
            IObservable <TParam> withParameter,
            string toEvent,
            Func <ICommand, ICommand> commandFixuper = null)
            where TView : class, IViewFor
            where TProp : ICommand
        {
            IDisposable disp = Disposable.Empty;

            var bindInfo = Observable.CombineLatest(
                @this,
                view.SubscribeToExpressionChain <TView, object>(controlExpression, false, false, RxApp.SuppressViewCommandBindingMessage).Select(x => x.Value),
                (val, host) => new { val, host });

            var propSub = bindInfo
                          .Where(x => x.host != null)
                          .Subscribe(x =>
            {
                disp.Dispose();
                if (x == null)
                {
                    disp = Disposable.Empty;
                    return;
                }

                var cmd = commandFixuper != null ? commandFixuper(x.val) : x.val;
                if (toEvent != null)
                {
                    disp = CreatesCommandBinding.BindCommandToObject(cmd, x.host, withParameter.Select(y => (object)y), toEvent);
                }
                else
                {
                    disp = CreatesCommandBinding.BindCommandToObject(cmd, x.host, withParameter.Select(y => (object)y));
                }
            });

            return(Disposable.Create(() =>
            {
                propSub.Dispose();
                disp.Dispose();
            }));
        }
Example #2
0
        /// <summary>
        /// Initializes static members of the <see cref="RxApp"/> class.
        /// </summary>
        /// <exception cref="UnhandledErrorException">Default exception when we have an unhandled exception.</exception>
        public static void Initialize(IDependencyResolver dependencyResolver, IScheduler mainThreadScheduler = null)
        {
            _dependencyResolver = dependencyResolver;
            _taskpoolScheduler  = TaskPoolScheduler.Default;
            _logger             = _dependencyResolver.GetInstance <ILogger>();

            ExecutionMode = mainThreadScheduler != null ? ExecutionMode.Dispatcher : ExecutionMode.UnitTest;

            switch (ExecutionMode)
            {
            case ExecutionMode.Dispatcher:
                _logger.LogInformation("Initializing to normal mode");
                _mainThreadScheduler = mainThreadScheduler;
                SuppressViewCommandBindingMessage = true;
                break;

            case ExecutionMode.UnitTest:
                _logger.LogInformation("Detected Unit Test Runner, setting MainThreadScheduler to CurrentThread");
                // For unit tests we need to set MainThreadScheduler to CurrentThread
                _mainThreadScheduler = CurrentThreadScheduler.Instance;
                break;

            default:
                throw new NotImplementedException($"{nameof(ExecutionMode)} {ExecutionMode}");
            }

            DefaultExceptionHandler = Observer.Create <Exception>(ex =>
            {
                // NB: If you're seeing this, it means that an
                // RxPropertyHelper or the CanExecute of a
                // ReactiveCommand ended in an OnError. Instead of silently
                // breaking, Inferno will halt here if a debugger is attached.
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }

                MainThreadScheduler.Schedule(() => throw new UnhandledErrorException(
                                                 "An object implementing IHandleObservableErrors (often a ReactiveCommand or RxPropertyHelper) has errored, thereby breaking its observable pipeline. To prevent this, ensure the pipeline does not error, or Subscribe to the ThrownExceptions property of the object in question to handle the erroneous case.",
                                                 ex));
            });

            #region Configuration of static classes and shared state

            IEnableLoggerExtensions.Initialize(_logger);
            ReactiveLoggerExtensions.Initialize(_logger);
            IReactiveObjectExtensions.Initialize(_logger);

            var observableForPropertyFactories = _dependencyResolver.GetAllInstances <ICreatesObservableForProperty>();
            ReactiveNotifyPropertyChangedExtensions.Initialize(observableForPropertyFactories);

            var commandBinderImplementation = _dependencyResolver.GetInstance <ICommandBinderImplementation>();
            CommandBinder.Initialize(commandBinderImplementation);

            var commandBindingFactories = _dependencyResolver.GetAllInstances <ICreatesCommandBinding>();
            CreatesCommandBinding.Initialize(commandBindingFactories);

            var bindingTypeConverters      = _dependencyResolver.GetAllInstances(typeof(IBindingTypeConverter)).OfType <IBindingTypeConverter>();
            var setMethodBindingConverters = _dependencyResolver.GetAllInstances(typeof(ISetMethodBindingConverter)).OfType <ISetMethodBindingConverter>();
            var propertyBindingHooks       = _dependencyResolver.GetAllInstances(typeof(IPropertyBindingHook)).OfType <IPropertyBindingHook>();
            PropertyBinderImplementation.Initialize(_logger, bindingTypeConverters, setMethodBindingConverters, propertyBindingHooks);

            #endregion Configuration of static classes and shared state
        }