Esempio n. 1
0
 internal IBindingTypeConverter GetConverterForTypes(Type lhs, Type rhs)
 {
     lock (_typeConverterCache)
     {
         return(_typeConverterCache.Get(Tuple.Create(lhs, rhs)));
     }
 }
 /// <inheritdoc/>
 public int GetAffinityForObject(Type type, string propertyName, bool beforeChanged = false)
 {
     lock (declaredInNSObject)
     {
         return(declaredInNSObject.Get(Tuple.Create(type, propertyName)) ? 15 : 0);
     }
 }
Esempio n. 3
0
        public static IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter, string eventName)
        {
            var type   = target.GetType();
            var binder = bindCommandEventCache.Get(type);

            if (binder == null)
            {
                throw new Exception(String.Format("Couldn't find a Command Binder for {0} and event {1}", type.FullName, eventName));
            }

            var eventArgsType = Reflection.GetEventArgsTypeForEvent(type, eventName);
            var mi            = binder.GetType().GetTypeInfo().DeclaredMethods.First(x => x.Name == "BindCommandToObject" && x.IsGenericMethod);

            mi = mi.MakeGenericMethod(new[] { eventArgsType });

            //var ret = binder.BindCommandToObject<TEventArgs>(command, target, commandParameter, eventName);
            var ret = (IDisposable)mi.Invoke(binder, new[] { command, target, commandParameter, eventName });

            if (ret == null)
            {
                throw new Exception(String.Format("Couldn't bind Command Binder for {0} and event {1}", type.FullName, eventName));
            }

            return(ret);
        }
Esempio n. 4
0
        string getPropertyValidationError(string propName)
        {
            PropertyExtraInfo pei;

            lock (allValidatedProperties) {
                if (!allValidatedProperties.Get(this.GetType()).TryGetValue(propName, out pei))
                {
                    return(null);
                }
            }

            foreach (var v in pei.ValidationAttributes)
            {
                try {
                    var ctx = new ValidationContext(this, null, null)
                    {
                        MemberName = propName
                    };
                    var pi = RxApp.getPropertyInfoForProperty(pei.Type, propName);
                    v.Validate(pi.GetValue(this, null), ctx);
                } catch (Exception ex) {
                    this.Log().InfoFormat("{0:X}.{1} failed validation: {2}",
                                          this.GetHashCode(), propName, ex.Message);
                    return(ex.Message);
                }
            }

            return(null);
        }
Esempio n. 5
0
        public static Action <object, object> GetValueSetterForProperty(Type type, string propName)
        {
            Contract.Requires(type != null);
            Contract.Requires(propName != null);

            lock (propReaderCache) {
                return(propWriterCache.Get(Tuple.Create(type, propName)));
            }
        }
Esempio n. 6
0
        public bool TryConvert(object from, Type toType, object conversionHint, out object result)
        {
            Contract.Requires(toType != null);

            var mi = referenceCastCache.Get(toType);

            result = mi.Invoke(null, new[] { from });
            return(true);
        }
Esempio n. 7
0
 public static IRxUIFullLogger GetLogger(Type type)
 {
     if (type == typeof(MemoizingMRUCache <Type, IRxUIFullLogger>))
     {
         return(nullLogger);
     }
     lock (loggerCache) {
         return(loggerCache.Get(type));
     }
 }
Esempio n. 8
0
        /// <summary>
        /// Gets a Type from the specified type name.
        /// Uses a cache to avoid having to use Reflection every time.
        /// </summary>
        /// <param name="type">The name of the type.</param>
        /// <param name="throwOnFailure">If we should throw an exception if the type can't be found.</param>
        /// <returns>The type that was found or null.</returns>
        /// <exception cref="TypeLoadException">If we were unable to find the type.</exception>
        public static Type ReallyFindType(string type, bool throwOnFailure)
        {
            Type ret = typeCache.Get(type);

            if (ret != null || !throwOnFailure)
            {
                return(ret);
            }

            throw new TypeLoadException();
        }
Esempio n. 9
0
 internal static Type reallyFindType(string type, bool throwOnFailure)
 {
     lock (typeCache) {
         var ret = typeCache.Get(type);
         if (ret != null || !throwOnFailure)
         {
             return(ret);
         }
         throw new TypeLoadException();
     }
 }
Esempio n. 10
0
        internal static PropertyInfo getPropertyInfoForProperty(Type type, string prop_name)
        {
            Contract.Requires(prop_name != null);
            PropertyInfo pi;

#if SILVERLIGHT
            lock (propInfoTypeCache) {
                pi = propInfoTypeCache.Get(new Tuple <Type, string>(type, prop_name));
            }
#else
            pi = propInfoTypeCache.Get(new Tuple <Type, string>(type, prop_name));
#endif

            if (pi == null)
            {
                throw new ArgumentException("You must declare a property named: " + prop_name);
            }

            return(pi);
        }
Esempio n. 11
0
        /// <summary>
        /// Log returns the current logger object, which allows the object to
        /// log messages with the type name attached.
        /// </summary>
        /// <returns></returns>
        public static ILog Log(this IEnableLogger This)
        {
            // Prevent recursive meta-logging
            if (This is MemoizingMRUCache <int, ILog> )
            {
                return(mruLogger);
            }

            lock (loggerCache) {
                return(loggerCache.Get(This.GetHashCode(), This));
            }
        }
        private static IObservable <IObservedChange <object, object> > NotifyForProperty(object sender, Expression expression, bool beforeChange, bool suppressWarnings)
        {
            var propertyName = expression.GetMemberInfo().Name;
            var result       = notifyFactoryCache.Get(Tuple.Create(sender.GetType(), propertyName, beforeChange));

            if (result == null)
            {
                throw new Exception($"Could not find a ICreatesObservableForProperty for {sender.GetType()} property {propertyName}. This should never happen, your service locator is probably broken. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation/nuget-packages for guidance.");
            }

            return(result.GetNotificationForProperty(sender, expression, propertyName, beforeChange, suppressWarnings));
        }
Esempio n. 13
0
        static IObservable <IObservedChange <object, object> > notifyForProperty(object sender, string propertyName, bool beforeChange)
        {
            var result = notifyFactoryCache.Get(sender.GetType());

            if (result == null)
            {
                throw new Exception(
                          String.Format("Couldn't find a ICreatesObservableForProperty for {0}. This should never happen, your service locator is probably broken.",
                                        sender.GetType()));
            }

            return(result.GetNotificationForProperty(sender, propertyName, beforeChange));
        }
Esempio n. 14
0
        public IFullLogger GetLogger(Type type)
        {
            if (RxApp.suppressLogging)
            {
                return(nullLogger);
            }
            if (type == typeof(MemoizingMRUCache <Type, IFullLogger>))
            {
                return(nullLogger);
            }

            lock (loggerCache) {
                return(loggerCache.Get(type));
            }
        }
        static IObservable <IObservedChange <object, object> > notifyForProperty(object sender, Expression expression, bool beforeChange)
        {
            var result = default(ICreatesObservableForProperty);

            lock (notifyFactoryCache) {
                result = notifyFactoryCache.Get(Tuple.Create(sender.GetType(), expression.GetMemberInfo().Name, beforeChange));
            }

            if (result == null)
            {
                throw new Exception(
                          String.Format("Couldn't find a ICreatesObservableForProperty for {0}. This should never happen, your service locator is probably broken.",
                                        sender.GetType()));
            }

            return(result.GetNotificationForProperty(sender, expression, beforeChange));
        }
Esempio n. 16
0
        internal static FieldInfo getFieldInfoForProperty <TObj>(string prop_name)
            where TObj : IReactiveNotifyPropertyChanged
        {
            Contract.Requires(prop_name != null);
            FieldInfo field;

            lock (fieldInfoTypeCache) {
                field = fieldInfoTypeCache.Get(new Tuple <Type, string>(typeof(TObj), prop_name));
            }

            if (field == null)
            {
                throw new ArgumentException("You must declare a backing field for this property named: " +
                                            RxApp.GetFieldNameForProperty(prop_name));
            }
            return(field);
        }
Esempio n. 17
0
        /// <summary>
        /// AutoPersist allows you to automatically call a method when an object
        /// has changed, throttling on a certain interval. Note that this object
        /// must mark its persistable properties via the [DataMember] attribute.
        /// Changes to properties not marked with DataMember will not trigger the
        /// object to be saved.
        /// </summary>
        /// <typeparam name="T">The reactive object type.</typeparam>
        /// <typeparam name="TDontCare">The save signal type.</typeparam>
        /// <param name="this">
        /// The reactive object to watch for changes.
        /// </param>
        /// <param name="doPersist">
        /// The asynchronous method to call to save the object to disk.
        /// </param>
        /// <param name="manualSaveSignal">
        /// When invoked, the object will be saved regardless of whether it has changed.
        /// </param>
        /// <param name="interval">
        /// The interval to save the object on. Note that if an object is constantly changing,
        /// it is possible that it will never be saved.
        /// </param>
        /// <returns>A Disposable to disable automatic persistence.</returns>
        public static IDisposable AutoPersist <T, TDontCare>(this T @this, Func <T, IObservable <Unit> > doPersist, IObservable <TDontCare> manualSaveSignal, TimeSpan?interval = null)
            where T : IReactiveObject
        {
            interval = interval ?? TimeSpan.FromSeconds(3.0);

            lock (dataContractCheckCache)
            {
                if (!dataContractCheckCache.Get(@this.GetType()))
                {
                    throw new ArgumentException("AutoPersist can only be applied to objects with [DataContract]");
                }
            }

            Dictionary <string, bool> persistableProperties;

            lock (persistablePropertiesCache)
            {
                persistableProperties = persistablePropertiesCache.Get(@this.GetType());
            }

            var saveHint = Observable.Merge(
                @this.GetChangedObservable().Where(x => persistableProperties.ContainsKey(x.PropertyName)).Select(_ => Unit.Default),
                manualSaveSignal.Select(_ => Unit.Default));

            var autoSaver = saveHint
                            .Throttle(interval.Value, RxApp.TaskpoolScheduler)
                            .SelectMany(_ => doPersist(@this))
                            .Publish();

            // NB: This rigamarole is to prevent the initialization of a class
            // from triggering a save
            var ret = new SingleAssignmentDisposable();

            RxApp.MainThreadScheduler.Schedule(() =>
            {
                if (ret.IsDisposed)
                {
                    return;
                }

                ret.Disposable = autoSaver.Connect();
            });

            return(ret);
        }
        public bool TryConvert(object from, Type toType, object conversionHint, out object result)
        {
            Contract.Requires(toType != null);

            var mi = default(MethodInfo);

            lock (referenceCastCache) {
                mi = referenceCastCache.Get(toType);
            }

            try {
                result = mi.Invoke(null, new[] { from });
            } catch (Exception ex) {
                this.Log().WarnException("Couldn't convert object to type: " + toType, ex);
                result = null;
                return(false);
            }
            return(true);
        }
Esempio n. 19
0
        /// <summary>
        /// Issues an request to fetch the value for the specified key as an
        /// async operation. The Observable returned will fire one time when the
        /// async operation finishes. If the operation is cached, an Observable
        /// that immediately fires upon subscribing will be returned.
        /// </summary>
        /// <param name="key">The key to provide to the calculation function.</param>
        /// <returns>Returns an Observable representing the future result.</returns>
        public IObservable <TVal> AsyncGet(TParam key)
        {
            IObservable <TVal> result;
            int myCall;
            var rs = new ReplaySubject <TVal>();

            lock (_innerCache) {
                if (_innerCache.TryGet(key, out result))
                {
                    this.Log().Debug("Cache hit: '{0}'", key);
                    return(result);
                }

                myCall = Interlocked.Increment(ref currentCall);

                _callQueue.Where(x => x == myCall).Subscribe(_ => {
                    this.Log().Debug("Dispatching '{0}'", key);
                    IObservable <TVal> fetched = null;
                    try {
                        fetched = _fetcher(key);
                    } catch (Exception ex) {
                        _callQueue.Release();
                        rs.OnError(ex);
                        return;
                    }

                    fetched.Subscribe(x => {
                        rs.OnNext(x);
                    }, ex => {
                        _callQueue.Release();
                        rs.OnError(ex);
                    }, () => {
                        _callQueue.Release();
                        rs.OnCompleted();
                    });
                });

                _innerCache.Get(key, rs);
            }

            _callQueue.OnNext(myCall);
            return(rs);
        }
Esempio n. 20
0
        /// <inheritdoc/>
        public bool TryConvert(object from, Type toType, object conversionHint, out object result)
        {
            Contract.Requires(toType != null);

            var mi = _referenceCastCache.Get(toType);

            try
            {
                result = mi.Invoke(null, new[] { from, toType });
            }
            catch (Exception ex)
            {
                this.Log().Warn(ex, "Couldn't convert object to type: " + toType);
                result = null;
                return(false);
            }

            return(true);
        }
Esempio n. 21
0
        public static IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter)
        {
            var type = target.GetType();

            var binder = bindCommandCache.Get(type);

            if (binder == null)
            {
                throw new Exception($"Couldn't find a Command Binder for {type.FullName}");
            }

            var ret = binder.BindCommandToObject(command, target, commandParameter);

            if (ret == null)
            {
                throw new Exception($"Couldn't bind Command Binder for {type.FullName}");
            }

            return(ret);
        }
Esempio n. 22
0
        static IReactiveNotifyPropertyChanged wrapInpcObjectIfNeeded(object obj)
        {
            if (obj == null)
            {
                return(null);
            }

            var ret = obj as IReactiveNotifyPropertyChanged;

            if (ret != null)
            {
                return(ret);
            }

            var inpc = obj as INotifyPropertyChanged;

            if (inpc != null)
            {
                return(wrapperCache.Get(inpc));
            }

            return(null);
        }
Esempio n. 23
0
        public static IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter)
        {
            var binder = default(ICreatesCommandBinding);
            var type   = target.GetType();

            lock (bindCommandCache) {
                binder = bindCommandCache.Get(type);
            }

            if (binder == null)
            {
                throw new Exception(String.Format("Couldn't find a Command Binder for {0}", type.FullName));
            }

            var ret = binder.BindCommandToObject(command, target, commandParameter);

            if (ret == null)
            {
                throw new Exception(String.Format("Couldn't bind Command Binder for {0}", type.FullName));
            }

            return(ret);
        }
Esempio n. 24
0
        /// <summary>
        /// WhenActivated allows you to register a Func to be called when a
        /// View is Activated.
        /// </summary>
        /// <param name="this">Object that supports activation.</param>
        /// <param name="block">
        /// The method to be called when the corresponding
        /// View is activated. It returns a list of Disposables that will be
        /// cleaned up when the View is deactivated.
        /// </param>
        /// <param name="view">
        /// The IActivatable will ordinarily also host the View
        /// Model, but in the event it is not, a class implementing <see cref="IViewFor" />
        /// can be supplied here.
        /// </param>
        /// <returns>A Disposable that deactivates this registration.</returns>
        public static IDisposable WhenActivated(this IActivatable @this, Func <IEnumerable <IDisposable> > block, IViewFor view)
        {
            var activationFetcher = activationFetcherCache.Get(@this.GetType());

            if (activationFetcher == null)
            {
                const string msg = "Don't know how to detect when {0} is activated/deactivated, you may need to implement IActivationForViewFetcher";
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, msg, @this.GetType().FullName));
            }

            var activationEvents = activationFetcher.GetActivationForView(@this);

            var vmDisposable = Disposable.Empty;

            if ((view ?? @this) is IViewFor v)
            {
                vmDisposable = HandleViewModelActivation(v, activationEvents);
            }

            var viewDisposable = HandleViewActivation(block, activationEvents);

            return(new CompositeDisposable(vmDisposable, viewDisposable));
        }
Esempio n. 25
0
        /// <summary>
        /// Attempts to return the current value of a property given a
        /// notification that it has changed. If any property in the
        /// property expression is null, false is returned.
        /// </summary>
        /// <param name="changeValue">The value of the property expression.</param>
        /// <returns>True if the entire expression was able to be followed, false otherwise</returns>
        public static bool TryGetValue <TSender, TValue>(this IObservedChange <TSender, TValue> This, out TValue changeValue)
        {
            if (!Equals(This.Value, default(TValue)))
            {
                changeValue = This.Value;
                return(true);
            }

            object current = This.Sender;

            string[] propNames = null;
            lock (propStringToNameCache) { propNames = propStringToNameCache.Get(This.PropertyName); }

            PropertyInfo pi;

            foreach (var propName in propNames.SkipLast(1))
            {
                if (current == null)
                {
                    changeValue = default(TValue);
                    return(false);
                }

                pi      = RxApp.getPropertyInfoOrThrow(current.GetType(), propName);
                current = pi.GetValue(current, null);
            }

            if (current == null)
            {
                changeValue = default(TValue);
                return(false);
            }

            pi          = RxApp.getPropertyInfoOrThrow(current.GetType(), propNames.Last());
            changeValue = (TValue)pi.GetValue(current, null);
            return(true);
        }
Esempio n. 26
0
        public int GetAffinityForObjects(Type lhs, Type rhs)
        {
            var converter = typeConverterCache.Get(Tuple.Create(lhs, rhs));

            return(converter != null ? 10 : 0);
        }
Esempio n. 27
0
 IBindingTypeConverter getConverterForTypes(Type lhs, Type rhs)
 {
     return(typeConverterCache.Get(Tuple.Create(lhs, rhs)));
 }
Esempio n. 28
0
        /// <inheritdoc/>
        public int GetAffinityForObjects(Type fromType, Type toType)
        {
            var converter = _typeConverterCache.Get(Tuple.Create(fromType, toType));

            return(converter != null ? 10 : 0);
        }