Ejemplo n.º 1
0
        public MainViewModel(IBlobCache?store = null, IScheduler?scheduler = null)
        {
            this.store     = store ?? Locator.Current.GetService <IBlobCache>(StoreKey);
            this.scheduler = scheduler ?? Scheduler.Default;

            this.HomePage = new HomePageViewModel();

            this.fileViewModelsSource = new SourceCache <FileViewModel, string>(x => x.FileName);

            this.fileViewModelsSource.Connect()
            .Bind(out var fileViewModels)
            .DisposeMany()
            .Subscribe();

            this.Files = fileViewModels;

            this.CreateFile = ReactiveCommand.CreateFromTask <CreateFileModel, CreateFileModel?>(this.OnCreateFileAsync);
            this.OpenFile   = ReactiveCommand.CreateFromTask <OpenFileModel, OpenFileModel?>(this.OnOpenFileAsync);
            this.CloseFile  = ReactiveCommand.CreateFromTask <string, string>(this.OnCloseFileAsync);
            this.Shutdown   = ReactiveCommand.CreateFromTask(this.OnShutdownAsync);
            this.ShowAbout  = ReactiveCommand.CreateFromTask(async() => await Dialog.ShowMessage.Handle(
                                                                 new MessageModel("AboutText", "AboutTitle")));

            this.HomePage.CreateFile
            .WhereNotNull()
            .InvokeCommand(this.CreateFile);

            this.HomePage.OpenFile
            .WhereNotNull()
            .Select(file => new OpenFileModel(file))
            .InvokeCommand(this.OpenFile);
        }
Ejemplo n.º 2
0
        private static ObservableAsPropertyHelper <TRet> ObservableToProperty <TObj, TRet>(
            this TObj target,
            IObservable <TRet> observable,
            string property,
            TRet initialValue      = default(TRet),
            bool deferSubscription = false,
            IScheduler?scheduler   = null)
            where TObj : class, IReactiveObject
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (observable == null)
            {
                throw new ArgumentNullException(nameof(observable));
            }

            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            return(new ObservableAsPropertyHelper <TRet>(
                       observable,
                       _ => target.RaisingPropertyChanged(property),
                       _ => target.RaisingPropertyChanging(property),
                       initialValue,
                       deferSubscription,
                       scheduler));
        }
Ejemplo n.º 3
0
        public static ReactiveCommandWithHistory <TParam, TResult> CreateWithHistoryFromObservable <TParam, TResult>(
            string commandKey,
            Func <TParam, TResult, IObservable <TResult> > execute,
            Func <TParam, TResult, IObservable <TResult> > discard,
            IHistory history,
            IObservable <bool>?canExecute = null,
            IScheduler?outputScheduler    = null)
        {
            if (history == null)
            {
                throw new ArgumentNullException(nameof(history));
            }
            if (discard == null)
            {
                throw new ArgumentNullException(nameof(discard));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }

            return(CreateWithHistoryFromObservable(
                       commandKey, execute, discard,
                       HistoryContext.GetContext(history, outputScheduler),
                       canExecute, outputScheduler));
        }
Ejemplo n.º 4
0
        public static ReactiveCommandWithHistory <TParam, TResult> CreateWithHistoryFromObservable <TParam, TResult>(
            string commandKey,
            Func <TParam, TResult, IObservable <TResult> > execute,
            Func <TParam, TResult, IObservable <TResult> > discard,
            HistoryContext context,
            IObservable <bool>?canExecute = null,
            IScheduler?outputScheduler    = null)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }
            if (discard == null)
            {
                throw new ArgumentNullException(nameof(discard));
            }

            return(new ReactiveCommandWithHistory <TParam, TResult>(
                       commandKey, execute, discard, context,
                       canExecute ?? Observables.True,
                       outputScheduler ?? RxApp.MainThreadScheduler));
        }
Ejemplo n.º 5
0
        public static ReactiveCommandWithHistory <Unit, Unit> CreateWithHistory(
            string commandKey,
            Action execute,
            Action discard,
            IHistory history,
            IObservable <bool>?canExecute = null,
            IScheduler?outputScheduler    = null)
        {
            if (history == null)
            {
                throw new ArgumentNullException(nameof(history));
            }
            if (discard == null)
            {
                throw new ArgumentNullException(nameof(discard));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }

            return(CreateWithHistory <Unit, Unit>(commandKey,
                                                  (param, result) => { execute(); return Unit.Default; },
                                                  (param, result) => { discard(); return Unit.Default; },
                                                  history, canExecute, outputScheduler));
        }
Ejemplo n.º 6
0
        public static ReactiveCommandWithHistory <Unit, TResult> CreateWithHistory <TResult>(
            string commandKey,
            Func <TResult, TResult> execute,
            Func <TResult, TResult> discard,
            IHistory history,
            IObservable <bool>?canExecute = null,
            IScheduler?outputScheduler    = null)
        {
            if (history == null)
            {
                throw new ArgumentNullException(nameof(history));
            }
            if (discard == null)
            {
                throw new ArgumentNullException(nameof(discard));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }

            return(CreateWithHistory <Unit, TResult>(commandKey,
                                                     (param, result) => execute(result),
                                                     (param, result) => discard(result),
                                                     history, canExecute, outputScheduler));
        }
Ejemplo n.º 7
0
 public static ReactiveCommandWithHistory <TParam, TResult> CreateWithHistory <TParam, TResult>(
     string commandKey,
     Func <TParam, TResult, TResult> execute,
     Func <TParam, TResult, TResult> discard,
     IObservable <bool>?canExecute = null,
     IScheduler?outputScheduler    = null,
     string historyId = "")
 {
     return(new ReactiveCommandWithHistory <TParam, TResult>(commandKey,
                                                             (param, result) => Observable.Create <TResult>(
                                                                 observer =>
     {
         observer.OnNext(execute(param, result));
         observer.OnCompleted();
         return new CompositeDisposable();
     }),
                                                             (param, result) => Observable.Create <TResult>(
                                                                 observer =>
     {
         observer.OnNext(discard(param, result));
         observer.OnCompleted();
         return new CompositeDisposable();
     }),
                                                             HistoryContext.GetContext(historyId, outputScheduler),
                                                             canExecute ?? Observables.True,
                                                             outputScheduler ?? RxApp.MainThreadScheduler));
 }
Ejemplo n.º 8
0
        public static ReactiveCommandWithHistory <Unit, Unit> CreateWithHistoryFromTask(
            string commandKey,
            Func <CancellationToken, Task> execute,
            Func <CancellationToken, Task> discard,
            IHistory history,
            IObservable <bool>?canExecute = null,
            IScheduler?outputScheduler    = null)
        {
            if (history == null)
            {
                throw new ArgumentNullException(nameof(history));
            }
            if (discard == null)
            {
                throw new ArgumentNullException(nameof(discard));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }

            return(CreateWithHistoryFromObservable <Unit, Unit>(commandKey,
                                                                (param, result) => Observable.StartAsync(ct => execute(ct)),
                                                                (param, result) => Observable.StartAsync(ct => discard(ct)),
                                                                history, canExecute, outputScheduler));
        }
Ejemplo n.º 9
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)));
        }
Ejemplo n.º 10
0
        protected TitledFormBase(ResourceManager?resourceManager, IScheduler?scheduler = null)
            : base(resourceManager, scheduler)
        {
            this.InitializeTitles(title => !title.IsOriginal, out this.titles);
            this.InitializeTitles(title => title.IsOriginal, out this.originalTitles);

            this.FormTitle = this.Titles.ToObservableChangeSet()
                             .AutoRefresh(vm => vm.Name)
                             .AutoRefresh(vm => vm.Priority)
                             .ToCollection()
                             .Select(vms => vms.OrderBy(vm => vm.Priority).Select(vm => vm.Name).FirstOrDefault())
                             .Select(this.GetFormTitle)
                             .ObserveOn(RxApp.MainThreadScheduler);

            var canAddTitle = this.Titles.ToObservableChangeSet()
                              .Count()
                              .Select(count => count < MaxTitleCount);

            var canAddOriginalTitle = this.OriginalTitles.ToObservableChangeSet()
                                      .Count()
                                      .Select(count => count < MaxTitleCount);

            this.Close = ReactiveCommand.Create(() => { });

            this.AddTitle         = ReactiveCommand.Create(() => this.OnAddTitle(false), canAddTitle);
            this.AddOriginalTitle = ReactiveCommand.Create(() => this.OnAddTitle(true), canAddOriginalTitle);
        }
Ejemplo n.º 11
0
 public FilterOnObservable(IObservable <IChangeSet <TObject> > source, Func <TObject, IObservable <bool> > filter, TimeSpan?buffer = null, IScheduler?scheduler = null)
 {
     _source    = source ?? throw new ArgumentNullException(nameof(source));
     _filter    = filter ?? throw new ArgumentNullException(nameof(filter));
     _buffer    = buffer;
     _scheduler = scheduler;
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObservableAsPropertyHelper{T}"/> class.
        /// </summary>
        /// <param name="observable">
        /// The Observable to base the property on.
        /// </param>
        /// <param name="onChanged">
        /// The action to take when the property changes, typically this will call
        /// the ViewModel's RaisePropertyChanged method.
        /// </param>
        /// <param name="onChanging">
        /// The action to take when the property changes, typically this will call
        /// the ViewModel's RaisePropertyChanging method.
        /// </param>
        /// <param name="initialValue">
        /// The initial value of the property.
        /// </param>
        /// <param name="deferSubscription">
        /// A value indicating whether the <see cref="ObservableAsPropertyHelper{T}"/>
        /// should defer the subscription to the <paramref name="observable"/> source
        /// until the first call to <see cref="Value"/>, or if it should immediately
        /// subscribe to the <paramref name="observable"/> source.
        /// </param>
        /// <param name="scheduler">
        /// The scheduler that the notifications will provided on - this
        /// should normally be a Dispatcher-based scheduler.
        /// </param>
        public ObservableAsPropertyHelper(
            IObservable <T> observable,
            Action <T> onChanged,
            Action <T>?onChanging  = null,
            T initialValue         = default,
            bool deferSubscription = false,
            IScheduler?scheduler   = null)
        {
            Contract.Requires(observable != null);
            Contract.Requires(onChanged != null);

            scheduler  = scheduler ?? CurrentThreadScheduler.Instance;
            onChanging = onChanging ?? (_ => { });

            _subject = new ScheduledSubject <T>(scheduler);
            _subject.Subscribe(
                x =>
            {
                onChanging(x);
                _lastValue = x;
                onChanged !(x);
            },
                ex => _thrownExceptions.Value.OnNext(ex))
            .DisposeWith(_disposable);

            _thrownExceptions = new Lazy <ISubject <Exception> >(() => new ScheduledSubject <Exception>(CurrentThreadScheduler.Instance, RxApp.DefaultExceptionHandler));

            _lastValue = initialValue;
            _source    = observable.StartWith(initialValue).DistinctUntilChanged();
            if (!deferSubscription)
            {
                _source.Subscribe(_subject).DisposeWith(_disposable);
                _activated = 1;
            }
        }
Ejemplo n.º 13
0
        public MiniseriesFormViewModel(
            Series series,
            ReadOnlyObservableCollection <Kind> kinds,
            ReadOnlyObservableCollection <Tag> tags,
            string fileName,
            ResourceManager?resourceManager       = null,
            IScheduler?scheduler                  = null,
            IEntityService <Series>?seriesService = null,
            ISettingsService?settingsService      = null)
            : base(series.Entry, tags, resourceManager, scheduler)
        {
            this.Series = series;
            this.Kinds  = kinds;

            this.seriesService   = seriesService ?? Locator.Current.GetService <IEntityService <Series> >(fileName);
            this.settingsService = settingsService ?? Locator.Current.GetService <ISettingsService>(fileName);

            this.CopyProperties();

            this.ChannelRule = this.ValidationRule(
                vm => vm.Channel, channel => !String.IsNullOrWhiteSpace(channel), "ChannelEmpty");

            this.ImdbLinkRule           = this.ValidationRule(vm => vm.ImdbLink, link => link.IsUrl(), "ImdbLinkInvalid");
            this.RottenTomatoesLinkRule = this.ValidationRule(
                vm => vm.RottenTomatoesLink, link => link.IsUrl(), "RottenTomatoesLinkInvalid");
            this.PosterUrlRule = this.ValidationRule(vm => vm.PosterUrl, url => url.IsUrl(), "PosterUrlInvalid");

            this.ConvertToSeries = ReactiveCommand.Create(() => { });

            this.CanDeleteWhenNotChanged();
            this.CanCreateFranchise();
            this.EnableChangeTracking();
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Converts an observable into having exponential backoff retry support.
        /// </summary>
        /// <typeparam name="T">The type of the observable.</typeparam>
        /// <param name="source">The observable to add support to.</param>
        /// <param name="retryCount">The number of times to retry for.</param>
        /// <param name="strategy">The strategy to use for retrying. If null uses the DefaultStrategy.</param>
        /// <param name="retryOnError">Determines if a retry should be made based on the passed in exception. Defaults to retry on all exceptions.</param>
        /// <param name="scheduler">The scheduler to the output to.</param>
        /// <param name="log">The logger to output to.</param>
        /// <returns>The observable with exponential backoff retry support.</returns>
        public static IObservable <T> RetryWithBackoff <T>(
            this IObservable <T> source,
            int?retryCount = null,
            Func <int, TimeSpan>?strategy       = null,
            Func <Exception, bool>?retryOnError = null,
            IScheduler?scheduler = null,
            IFullLogger?log      = default)
        {
            strategy ??= DefaultStrategy;
            scheduler ??= DefaultScheduler.Instance;
            retryOnError ??= _ => true;
            var attempt = 0;

            IObservable <Notification <T> > deferred = Observable.Defer(() =>
            {
                var num = attempt;
                attempt = num + 1;
                return((num == 0 ? source : source.DelaySubscription(strategy(attempt - 1), scheduler))
                       .Select(Notification.CreateOnNext)
                       .Catch((Func <Exception, IObservable <Notification <T> > >)(ex =>
                {
                    log?.Warn(ex, $"Retrying attempt: {attempt}");
                    return !retryOnError(ex)
                                ? Observable.Return(Notification.CreateOnError <T>(ex))
                                : Observable.Throw <Notification <T> >(ex);
                })));
            });

            return((retryCount is null ? deferred.Retry() : deferred.Retry(retryCount.Value)).Dematerialize());
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Returns a handle to the Scheduler produced by this factory.
        /// </summary>
        /// <remarks>
        /// If one of the <see cref="Initialize()" /> methods has not be previously
        /// called, then the default (no-arg) <see cref="Initialize()" /> method
        /// will be called by this method.
        /// </remarks>
        public virtual async Task <IScheduler> GetScheduler(CancellationToken cancellationToken = default)
        {
            if (cfg == null)
            {
                Initialize();
            }

            SchedulerRepository schedRep = SchedulerRepository.Instance;

            IScheduler?sched = await schedRep.Lookup(SchedulerName, cancellationToken).ConfigureAwait(false);

            if (sched != null)
            {
                if (sched.IsShutdown)
                {
                    schedRep.Remove(SchedulerName);
                }
                else
                {
                    return(sched);
                }
            }

            sched = await Instantiate().ConfigureAwait(false);

            return(sched !);
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Creates a <see cref="CombinedReactiveCommand{TParam, TResult}"/> that composes all the provided child commands.
 /// </summary>
 /// <param name="childCommands">
 /// The child commands that the combined command will compose.
 /// </param>
 /// <param name="canExecute">
 /// An optional observable that dictates the availability of the command for execution (in addition to the availability specified
 /// by each individual child command).
 /// </param>
 /// <param name="outputScheduler">
 /// An optional scheduler that is used to surface events. Defaults to <c>RxApp.MainThreadScheduler</c>.
 /// </param>
 /// <returns>
 /// The <c>CombinedReactiveCommand</c> instance.
 /// </returns>
 /// <typeparam name="TParam">
 /// The type of the parameter passed through to command execution.
 /// </typeparam>
 /// <typeparam name="TResult">
 /// The type of the command's result.
 /// </typeparam>
 public static CombinedReactiveCommand <TParam, TResult> CreateCombined <TParam, TResult>(
     IEnumerable <ReactiveCommandBase <TParam, TResult> > childCommands,
     IObservable <bool>?canExecute = null,
     IScheduler?outputScheduler    = null)
 {
     return(new CombinedReactiveCommand <TParam, TResult>(childCommands, canExecute ?? Observables.True, outputScheduler ?? RxApp.MainThreadScheduler));
 }
Ejemplo n.º 17
0
    private async Task ConfigureTimer()
    {
        var props = new NameValueCollection
        {
            { "quartz.serializer.type", "binary" }
        };
        var factory = new StdSchedulerFactory(props);
        var data    = new JobDataMap
        {
            { "Queue", _queue },
            { "ApplicationNameService", _applicationNameService }
        };

        _scheduler = await factory.GetScheduler().ConfigureAwait(false);

        var job = JobBuilder.Create <TimerJob>()
                  .SetJobData(data)
                  .Build();

        var trigger = TriggerBuilder.Create()
                      .StartNow()
                      .WithCronSchedule(_options.GetCronString())
                      .Build();

        await _scheduler.ScheduleJob(job, trigger).ConfigureAwait(false);
    }
Ejemplo n.º 18
0
        protected SeriesComponentFormBase(
            SeriesFormViewModel parent,
            IObservable <int> maxSequenceNumber,
            ResourceManager?resourceManager,
            IScheduler?scheduler = null)
            : base(resourceManager, scheduler)
        {
            this.Parent = parent;

            this.GoToSeries = ReactiveCommand.Create <Unit, SeriesFormViewModel>(_ => this.Parent, this.Valid);

            var isNotFirst = this.WhenAnyValue(vm => vm.SequenceNumber)
                             .Select(num => num != 1);

            var isNotLast = Observable.CombineLatest(this.WhenAnyValue(vm => vm.SequenceNumber), maxSequenceNumber)
                            .Select(nums => nums[0] < nums[1]);

            this.MoveUp   = ReactiveCommand.Create(() => { this.SequenceNumber--; }, isNotFirst);
            this.MoveDown = ReactiveCommand.Create(() => { this.SequenceNumber++; }, isNotLast);

            this.GoToNext = ReactiveCommand.Create(
                () => { },
                Observable.CombineLatest(isNotLast, this.Valid).AllTrue());

            this.GoToPrevious = ReactiveCommand.Create(
                () => { },
                Observable.CombineLatest(isNotFirst, this.Valid).AllTrue());
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Create a <see cref="MappingView{TSource, TResult}"/> for <paramref name="source"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the collection.</typeparam>
        /// <typeparam name="TResult">The type of the elements in the resulting collection.</typeparam>
        /// <param name="source">The source collection.</param>
        /// <param name="selector">
        /// The function mapping an element of type <typeparamref name="TSource"/> to <typeparamref name="TResult"/>.
        /// The second parameter is the index of the element.
        /// </param>
        /// <param name="updater">
        /// The function updating an element for which the index changed.
        /// The second parameter is the index of the element.
        /// </param>
        /// <param name="onRemove">An action to perform when an item is removed from the collection. Typically it will be x => x.Dispose().</param>
        /// <param name="bufferTime">The time to buffer changes before updating and notifying.</param>
        /// <param name="scheduler">The scheduler to notify changes on.</param>
        /// <param name="leaveOpen">True means that the <paramref name="source"/> is not disposed when this instance is disposed.</param>
        /// <param name="triggers">Additional triggers for when mapping is updated.</param>
        /// <returns>A <see cref="MappingView{TSource, TResult}"/>.</returns>
        public static MappingView <TSource, TResult> Create <TSource, TResult>(
            this IEnumerable <TSource> source,
            Func <TSource, int, TResult> selector,
            Func <TResult, int, TResult> updater,
            Action <TResult> onRemove,
            TimeSpan bufferTime,
            IScheduler?scheduler = null,
            bool leaveOpen       = true,
            params IObservable <object?>[] triggers)
            where TResult : class
        {
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (selector is null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            if (updater is null)
            {
                throw new ArgumentNullException(nameof(updater));
            }

            return(new MappingView <TSource, TResult>(source, Mapper.Create(selector, updater, onRemove), bufferTime, scheduler, leaveOpen, triggers));
        }
Ejemplo n.º 20
0
        public MovieFormViewModel(
            Movie movie,
            ReadOnlyObservableCollection <Kind> kinds,
            ReadOnlyObservableCollection <Tag> tags,
            string fileName,
            ResourceManager?resourceManager     = null,
            IScheduler?scheduler                = null,
            IEntityService <Movie>?movieService = null)
            : base(movie.Entry, tags, resourceManager, scheduler)
        {
            this.Movie = movie;
            this.Kinds = kinds;

            this.movieService = movieService ?? Locator.Current.GetService <IEntityService <Movie> >(fileName);

            this.CopyProperties();

            this.YearRule               = this.ValidationRule(vm => vm.Year, MovieMinYear, MovieMaxYear);
            this.ImdbLinkRule           = this.ValidationRule(vm => vm.ImdbLink, link => link.IsUrl(), "ImdbLinkInvalid");
            this.RottenTomatoesLinkRule = this.ValidationRule(
                vm => vm.RottenTomatoesLink, link => link.IsUrl(), "RottenTomatoesLinkInvalid");
            this.PosterUrlRule = this.ValidationRule(vm => vm.PosterUrl, url => url.IsUrl(), "PosterUrlInvalid");

            this.InitializeValueDependencies();
            this.CanDeleteWhenNotChanged();
            this.CanCreateFranchise();
            this.EnableChangeTracking();
        }
Ejemplo n.º 21
0
 public IObservable <IChangeSet <IModListingGetter> > Get(
     out IObservable <ErrorResponse> state,
     IScheduler?scheduler = null)
 {
     return(InternalGet(out state)
            .ObserveOnIfApplicable(scheduler));
 }
Ejemplo n.º 22
0
 private InputHandler NewHandler(
     PipeReader inputStream,
     IOutputHandler outputHandler,
     IReceiver receiver,
     IRequestProcessIdentifier requestProcessIdentifier,
     IRequestRouter <IHandlerDescriptor?> requestRouter,
     ILoggerFactory loggerFactory,
     IResponseRouter responseRouter,
     IScheduler?scheduler = null
     ) =>
 new InputHandler(
     inputStream,
     outputHandler,
     receiver,
     requestProcessIdentifier,
     requestRouter,
     responseRouter,
     loggerFactory,
     _unhandledException,
     null,
     TimeSpan.FromSeconds(30),
     true,
     null,
     scheduler ?? TaskPoolScheduler.Default
     );
        public SpecialEpisodeFormViewModel(
            SpecialEpisode episode,
            SeriesFormViewModel parent,
            IObservable <int> maxSequenceNumber,
            ResourceManager?resourceManager,
            IScheduler?scheduler = null)
            : base(parent, maxSequenceNumber, resourceManager, scheduler)
        {
            this.SpecialEpisode = episode;
            this.CopyProperties();

            this.ChannelRule = this.ValidationRule(
                vm => vm.Channel, channel => !String.IsNullOrWhiteSpace(channel), "ChannelEmpty");

            this.YearRule = this.ValidationRule(vm => vm.Year, SeriesMinYear, SeriesMaxYear);

            this.RottenTomatoesLinkRule = this.ValidationRule(
                vm => vm.RottenTomatoesLink, link => link.IsUrl(), "RottenTomatoesLinkInvalid");

            this.PosterUrlRule = this.ValidationRule(vm => vm.PosterUrl, url => url.IsUrl(), "PosterUrlInvalid");

            this.InitializeValueDependencies();
            this.CanAlwaysDelete();
            this.EnableChangeTracking();
        }
Ejemplo n.º 24
0
    private static ObservableAsPropertyHelper <TRet> ObservableToProperty <TObj, TRet>(
        this TObj target,
        IObservable <TRet?> observable,
        Expression <Func <TObj, TRet> > property,
        Func <TRet> getInitialValue,
        bool deferSubscription = false,
        IScheduler?scheduler   = null)
        where TObj : class, IReactiveObject
    {
        if (target is null)
        {
            throw new ArgumentNullException(nameof(target));
        }

        if (observable is null)
        {
            throw new ArgumentNullException(nameof(observable));
        }

        if (property is null)
        {
            throw new ArgumentNullException(nameof(property));
        }

        var expression = Reflection.Rewrite(property.Body);

        var parent = expression.GetParent();

        if (parent is null)
        {
            throw new ArgumentException("The property expression does not have a valid parent.", nameof(property));
        }

        if (parent.NodeType != ExpressionType.Parameter)
        {
            throw new ArgumentException("Property expression must be of the form 'x => x.SomeProperty'");
        }

        var memberInfo = expression.GetMemberInfo();

        if (memberInfo is null)
        {
            throw new ArgumentException("The property expression does not point towards a valid member.", nameof(property));
        }

        var name = memberInfo.Name;

        if (expression is IndexExpression)
        {
            name += "[]";
        }

        return(new ObservableAsPropertyHelper <TRet>(
                   observable,
                   _ => target.RaisingPropertyChanged(name),
                   _ => target.RaisingPropertyChanging(name),
                   getInitialValue,
                   deferSubscription,
                   scheduler));
    }
Ejemplo n.º 25
0
    /// <summary>
    /// Converts an Observable to an ObservableAsPropertyHelper and
    /// automatically provides the onChanged method to raise the property
    /// changed notification.
    /// </summary>
    /// <typeparam name="TObj">The object type.</typeparam>
    /// <typeparam name="TRet">The result type.</typeparam>
    /// <param name="target">
    /// The observable to convert to an ObservableAsPropertyHelper.
    /// </param>
    /// <param name="source">
    /// The ReactiveObject that has the property.
    /// </param>
    /// <param name="property">
    /// The name of the property that has changed. Recommended for use with nameof() or a FODY.
    /// </param>
    /// <param name="result">
    /// An out param matching the return value, provided for convenience.
    /// </param>
    /// <param name="getInitialValue">
    /// The function used to retrieve the initial value of the property.
    /// </param>
    /// <param name="deferSubscription">
    /// A value indicating whether the <see cref="ObservableAsPropertyHelper{T}"/>
    /// should defer the subscription to the <paramref name="target"/> source
    /// until the first call to <see cref="ObservableAsPropertyHelper{T}.Value"/>,
    /// or if it should immediately subscribe to the <paramref name="target"/> source.
    /// </param>
    /// <param name="scheduler">
    /// The scheduler that the notifications will be provided on - this should
    /// normally be a Dispatcher-based scheduler.
    /// </param>
    /// <returns>
    /// An initialized ObservableAsPropertyHelper; use this as the backing
    /// field for your property.
    /// </returns>
    public static ObservableAsPropertyHelper <TRet> ToProperty <TObj, TRet>(
        this IObservable <TRet> target,
        TObj source,
        string property,
        out ObservableAsPropertyHelper <TRet> result,
        Func <TRet> getInitialValue,
        bool deferSubscription = false,
        IScheduler?scheduler   = null) // TODO: Create Test
        where TObj : class, IReactiveObject
    {
        if (target is null)
        {
            throw new ArgumentNullException(nameof(target));
        }

        if (source is null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        if (string.IsNullOrWhiteSpace(property))
        {
            throw new ArgumentException($"'{nameof(property)}' cannot be null or whitespace", nameof(property));
        }

        result = source.ObservableToProperty(
            target,
            property,
            getInitialValue,
            deferSubscription,
            scheduler);

        return(result);
    }
Ejemplo n.º 26
0
    /// <summary>
    /// Converts an Observable to an ObservableAsPropertyHelper and
    /// automatically provides the onChanged method to raise the property
    /// changed notification.
    /// </summary>
    /// <typeparam name="TObj">The object type.</typeparam>
    /// <typeparam name="TRet">The result type.</typeparam>
    /// <param name="target">
    /// The observable to convert to an ObservableAsPropertyHelper.
    /// </param>
    /// <param name="source">
    /// The ReactiveObject that has the property.
    /// </param>
    /// <param name="property">
    /// An Expression representing the property (i.e. <c>x => x.SomeProperty</c>).
    /// </param>
    /// <param name="deferSubscription">
    /// A value indicating whether the <see cref="ObservableAsPropertyHelper{T}"/>
    /// should defer the subscription to the <paramref name="target"/> source
    /// until the first call to <see cref="ObservableAsPropertyHelper{T}.Value"/>,
    /// or if it should immediately subscribe to the <paramref name="target"/> source.
    /// </param>
    /// <param name="scheduler">
    /// The scheduler that the notifications will be provided on - this should normally
    /// be a Dispatcher-based scheduler.
    /// </param>
    /// <returns>
    /// An initialized ObservableAsPropertyHelper; use this as the backing field
    /// for your property.
    /// </returns>
    public static ObservableAsPropertyHelper <TRet> ToProperty <TObj, TRet>(
        this IObservable <TRet> target,
        TObj source,
        Expression <Func <TObj, TRet> > property,
        bool deferSubscription = false,
        IScheduler?scheduler   = null) // TODO: Create Test
        where TObj : class, IReactiveObject
    {
        if (target is null)
        {
            throw new ArgumentNullException(nameof(target));
        }

        if (source is null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        if (property is null)
        {
            throw new ArgumentNullException(nameof(property));
        }

        return(source.ObservableToProperty(target, property, deferSubscription, scheduler));
    }
Ejemplo n.º 27
0
 public AutoRefresh(IObservable <IChangeSet <TObject> > source, Func <TObject, IObservable <TAny> > reEvaluator, TimeSpan?buffer = null, IScheduler?scheduler = null)
 {
     _source      = source ?? throw new ArgumentNullException(nameof(source));
     _reEvaluator = reEvaluator ?? throw new ArgumentNullException(nameof(reEvaluator));
     _buffer      = buffer;
     _scheduler   = scheduler;
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Converts an Observable to an ObservableAsPropertyHelper and
 /// automatically provides the onChanged method to raise the property
 /// changed notification.
 /// </summary>
 /// <typeparam name="TObj">The object type.</typeparam>
 /// <typeparam name="TRet">The result type.</typeparam>
 /// <param name="target">
 /// The observable to convert to an ObservableAsPropertyHelper.
 /// </param>
 /// <param name="source">
 /// The ReactiveObject that has the property.
 /// </param>
 /// <param name="property">
 /// An Expression representing the property (i.e. <c>x => x.SomeProperty</c>).
 /// </param>
 /// <param name="getInitialValue">
 /// The function used to retrieve the initial value of the property.
 /// </param>
 /// <param name="deferSubscription">
 /// A value indicating whether the <see cref="ObservableAsPropertyHelper{T}"/>
 /// should defer the subscription to the <paramref name="target"/> source
 /// until the first call to <see cref="ObservableAsPropertyHelper{T}.Value"/>,
 /// or if it should immediately subscribe to the <paramref name="target"/> source.
 /// </param>
 /// <param name="scheduler">
 /// The scheduler that the notifications will be provided on - this should normally
 /// be a Dispatcher-based scheduler.
 /// </param>
 /// <returns>
 /// An initialized ObservableAsPropertyHelper; use this as the backing field
 /// for your property.
 /// </returns>
 public static ObservableAsPropertyHelper <TRet> ToProperty <TObj, TRet>(
     this IObservable <TRet> target,
     TObj source,
     Expression <Func <TObj, TRet> > property,
     Func <TRet> getInitialValue,
     bool deferSubscription = false,
     IScheduler?scheduler   = null) // TODO: Create Test
     where TObj : class, IReactiveObject => source.ObservableToProperty(target, property, getInitialValue, deferSubscription, scheduler);
Ejemplo n.º 29
0
 public FilterOnProperty(IObservable <IChangeSet <TObject> > source, Expression <Func <TObject, TProperty> > propertySelector, Func <TObject, bool> predicate, TimeSpan?throttle = null, IScheduler?scheduler = null)
 {
     _source           = source;
     _propertySelector = propertySelector;
     _predicate        = predicate;
     _throttle         = throttle;
     _scheduler        = scheduler;
 }
 public GroupOnPropertyWithImmutableState(IObservable <IChangeSet <TObject> > source, Expression <Func <TObject, TGroup> > groupSelectorKey, TimeSpan?throttle = null, IScheduler?scheduler = null)
 {
     _source           = source ?? throw new ArgumentNullException(nameof(source));
     _groupSelector    = groupSelectorKey.Compile();
     _propertySelector = groupSelectorKey;
     _throttle         = throttle;
     _scheduler        = scheduler;
 }