/// <summary>
 /// Adds <paramref name="handler"/> to be when trying to create a key of the <typeparamref name="TKey"/> from parameters collection.
 /// </summary>
 /// <typeparam name="TKey">A type of the key.</typeparam>
 /// <param name="handler">A handler to be used.</param>
 /// <returns>Self (for fluency).</returns>
 public MappingCollection AddParametersToKey <TKey>(OutFunc <IReadOnlyKeyValueCollection, TKey, bool> handler)
     where TKey : IKey
 {
     Ensure.NotNull(handler, "handler");
     parametersToKey[typeof(TKey)] = new OutFuncWrapper <TKey>(handler).TryGet;
     return(this);
 }
        public void Context()
        {
            Converts.Repository
            .Add <string, int>(Int32.TryParse)
            .Add(new StringToListConverter <int>());

            List <int> list;

            Assert.AreEqual(true, Converts.Try("2,34,1", out list));
            AssertList(list);

            object rawList;

            Assert.AreEqual(true, Converts.Try(typeof(string), typeof(List <int>), "2,34,1", out rawList));
            Assert.IsInstanceOfType(rawList, typeof(List <int>));
            AssertList((List <int>)rawList);

            Func <string, List <int> > converter = Converts.Repository.GetConverter <string, List <int> >();

            list = converter("2,34,1");
            AssertList(list);

            OutFunc <string, List <int>, bool> tryConverter = Converts.Repository.GetTryConverter <string, List <int> >();

            Assert.AreEqual(true, tryConverter("2,34,1", out list));
            AssertList(list);
        }
        public IConverterRepository AddSearchHandler(OutFunc <ConverterSearchContext, IConverter, bool> searchHandler)
        {
            Ensure.NotNull(searchHandler, "searchHandler");
            lock (storageLock)
                onSearchConverter.Add(searchHandler);

            return(this);
        }
        /// <summary>
        /// Adds <paramref name="searchHandler"/> to be executed when generator was not found.
        /// (Last registered is executed the first).
        /// </summary>
        /// <param name="searchHandler">Generator provider method.</param>
        public ReflectionBehaviorFactoryCollection AddSearchHandler(OutFunc <Type, IReflectionBehaviorFactory, bool> searchHandler)
        {
            Ensure.NotNull(searchHandler, "searchHandler");

            lock (searchFactoryLock)
                onSearchFactory.Add(searchHandler);

            return(this);
        }
Пример #5
0
        /// <summary>
        /// Adds <paramref name="searchHandler"/> to be executed when generator was not found.
        /// (Last registered is executed the first).
        /// </summary>
        /// <param name="searchHandler">Generator provider method.</param>
        public CodeDomBehaviorGeneratorCollection AddSearchHandler(OutFunc <Type, ICodeDomBehaviorGenerator, bool> searchHandler)
        {
            Ensure.NotNull(searchHandler, "searchHandler");

            lock (searchHandlerLock)
                onSearchGenerator.Add(searchHandler);

            return(this);
        }
Пример #6
0
        /// <summary>
        /// Registers search handler when non handler was found for key.
        /// </summary>
        /// <param name="searchHandler">Search handler.</param>
        /// <returns>Self (for fluency).</returns>
        public DefaultDeleteDispatcher AddSearchHandler(OutFunc <string, IDeleteHandler, bool> searchHandler)
        {
            Ensure.NotNull(searchHandler, "searchHandler");

            lock (searchHandlerLock)
                onSearchHandler.Add(searchHandler);

            return(this);
        }
Пример #7
0
        /// <summary>
        /// Adds <paramref name="searchHandler"/> to be executed when model definition was not found.
        /// </summary>
        /// <param name="searchHandler">Model definition provider method.</param>
        public ModelDefinitionCollection AddSearchHandler(OutFunc <string, IModelDefinition, bool> searchHandler)
        {
            Ensure.NotNull(searchHandler, "searchHandler");

            lock (storageLock)
            {
                onSearchDefinition.Add(searchHandler);
            }

            return(this);
        }
Пример #8
0
        public void ParseInt()
        {
            OutFunc <string, int, bool> tryConverter = Converts.Repository.GetTryConverter <string, int>();

            int value;

            Assert.AreEqual(false, tryConverter("x", out value));

            tryConverter = Converts.Repository
                           .AddStringTo <int>(Int32.TryParse, true)
                           .GetTryConverter <string, int>();

            Assert.AreEqual(false, tryConverter("x", out value));
            Assert.AreEqual(true, tryConverter("15", out value));
            Assert.AreEqual(15, value);
        }
Пример #9
0
        /// <summary>
        /// Проверка Int на соотвествие условию
        /// </summary>
        private static T GetValidValue <T>(Func <T, bool> func, OutFunc <string, T> parseFunc, string message)
        {
            T value;

            while (true)
            {
                if (parseFunc.Invoke(Console.ReadLine(), out value) && func.Invoke(value))
                {
                    break;
                }
                else
                {
                    Console.WriteLine(message);
                }
            }
            return(value);
        }
Пример #10
0
        /// <summary>
        /// Метод для проверки на соответствие условию значения
        /// </summary>
        private static T GetValidValue <T>(Func <T, bool> func,
                                           OutFunc <string, T> parseFunc,
                                           string message,
                                           string checkString, Label label1)
        {
            T value;

            if (parseFunc.Invoke(checkString, out value) && func.Invoke(value))
            {
                return(value);
            }
            else
            {
                label1.Text = label1.Text + message;
                return(default(T));
            }
        }
Пример #11
0
        /// <summary>
        /// Creates a two-way binding between a view model and a view.
        /// This binding will attempt to convert the values of the
        /// view and view model properties using a <see cref="IBindingTypeConverter"/>
        /// if they are not of the same type.
        /// </summary>
        /// <typeparam name="TViewModel">The type of the view model that is bound.</typeparam>
        /// <typeparam name="TView">The type of the view being bound.</typeparam>
        /// <typeparam name="TVMProp">The type of the property bound on the view model.</typeparam>
        /// <typeparam name="TVProp">The type of the property bound on the view.</typeparam>
        /// <typeparam name="TDontCare">
        /// A dummy type, only the fact that <paramref name="signalViewUpdate"/>
        /// emits values is considered, not the actual values emitted.
        /// </typeparam>
        /// <param name="viewModel">The instance of the view model object to be bound.</param>
        /// <param name="view">The instance of the view object to be bound.</param>
        /// <param name="vmProperty">
        /// An expression representing the property to be bound to on the view model.
        /// This can be a child property, for example <c>x =&gt; x.Foo.Bar.Baz</c> in which case
        /// the binding will attempt to subscribe recursively to updates in order to
        /// always get and set the correct property.
        /// </param>
        /// <param name="viewProperty">
        /// An expression representing the property to be bound to on the view.
        /// This can be a child property, for example <c>x =&gt; x.Foo.Bar.Baz</c> in which case
        /// the binding will attempt to subscribe recursively to updates in order to
        /// always get and set the correct property.
        ///
        /// If it is left null, the framework will attempt to automagically figure out
        /// the control and property that is to be bound, by looking for a control of the
        /// same name as the <paramref name="vmProperty"/>, and its most natural property.
        /// </param>
        /// <param name="signalViewUpdate">
        /// An observable, that when signaled, indicates that the view property
        /// has been changed, and that the binding should update the view model
        /// property accordingly.
        /// </param>
        /// <param name="conversionHint">
        /// An object that can provide a hint for the converter.
        /// The semantics of this object is defined by the converter used.
        /// </param>
        /// <param name="vmToViewConverterOverride">
        /// An optional <see cref="IBindingTypeConverter"/> to use when converting from the
        /// viewModel to view property.
        /// </param>
        /// <param name="viewToVMConverterOverride">
        /// An optional <see cref="IBindingTypeConverter"/> to use when converting from the
        /// view to viewModel property.
        /// </param>
        /// <returns>
        /// An instance of <see cref="IDisposable"/> that, when disposed,
        /// disconnects the binding.
        /// </returns>
        public IReactiveBinding <TView, TViewModel, Tuple <object, bool> > Bind <TViewModel, TView, TVMProp, TVProp, TDontCare>(
            TViewModel viewModel,
            TView view,
            Expression <Func <TViewModel, TVMProp> > vmProperty,
            Expression <Func <TView, TVProp> > viewProperty,
            IObservable <TDontCare> signalViewUpdate,
            object conversionHint,
            IBindingTypeConverter vmToViewConverterOverride = null,
            IBindingTypeConverter viewToVMConverterOverride = null)
            where TViewModel : class
            where TView : class, IViewFor
        {
            var vmToViewConverter = vmToViewConverterOverride ?? GetConverterForTypes(typeof(TVMProp), typeof(TVProp));
            var viewToVMConverter = viewToVMConverterOverride ?? GetConverterForTypes(typeof(TVProp), typeof(TVMProp));

            if (vmToViewConverter == null || viewToVMConverter == null)
            {
                throw new ArgumentException(
                          $"Can't two-way convert between {typeof(TVMProp)} and {typeof(TVProp)}. To fix this, register a IBindingTypeConverter or call the version with converter Funcs.");
            }

            OutFunc <TVMProp, TVProp> vmToViewFunc = (TVMProp vmValue, out TVProp vValue) =>
            {
                object tmp;
                var    result = vmToViewConverter.TryConvert(vmValue, typeof(TVProp), conversionHint, out tmp);

                vValue = result ? (TVProp)tmp : default(TVProp);
                return(result);
            };
            OutFunc <TVProp, TVMProp> viewToVmFunc = (TVProp vValue, out TVMProp vmValue) =>
            {
                object tmp;
                var    result = viewToVMConverter.TryConvert(vValue, typeof(TVMProp), conversionHint, out tmp);

                vmValue = result ? (TVMProp)tmp : default(TVMProp);
                return(result);
            };

            return(BindImpl(viewModel, view, vmProperty, viewProperty, signalViewUpdate, vmToViewFunc, viewToVmFunc));
        }
        /// <summary>
        /// Adds <paramref name="tryConvert"/> for conversion from <see cref="String"/> to <typeparamref name="TTarget"/>.
        /// Alse adds support for nullable conversion from <see cref="String"/> to <see cref="Nullable{TTarget}"/>.
        /// </summary>
        /// <typeparam name="TTarget">Target type.</typeparam>
        /// <param name="repository">The repository to register converter to.</param>
        /// <param name="tryConvert">The converter delegate.</param>
        /// <param name="isWhitespaceAccepted">Whether whitespaces should be treated as nulls.</param>
        /// <returns><paramref name="repository"/>.</returns>
        public static IConverterRepository AddStringTo <TTarget>(this IConverterRepository repository, OutFunc <string, TTarget, bool> tryConvert, bool isWhitespaceAccepted = true)
            where TTarget : struct
        {
            Ensure.NotNull(repository, "repository");
            Ensure.NotNull(tryConvert, "tryConvert");

            IConverter <string, TTarget> converter = new DefaultConverter <string, TTarget>(tryConvert);

            return(repository
                   .Add <string, TTarget>(converter)
                   .Add <string, TTarget?>(new StringToNullableConverter <TTarget>(converter, isWhitespaceAccepted)));
        }
 /// <summary>
 /// Adds <paramref name="tryConvert"/> for conversion from <typeparamref name="TSource"/> to <typeparamref name="TTarget"/>.
 /// </summary>
 /// <typeparam name="TSource">Source type.</typeparam>
 /// <typeparam name="TTarget">Target type.</typeparam>
 /// <param name="repository">The repository to register converter to.</param>
 /// <param name="tryConvert">The converter delegate.</param>
 /// <returns><paramref name="repository"/>.</returns>
 public static IConverterRepository Add <TSource, TTarget>(this IConverterRepository repository, OutFunc <TSource, TTarget, bool> tryConvert)
 {
     Ensure.NotNull(repository, "repository");
     Ensure.NotNull(tryConvert, "tryConvert");
     return(Add(repository, new DefaultConverter <TSource, TTarget>(tryConvert)));
 }
        /// <summary>
        /// Adds <paramref name="tryConvert"/> for convertion of string value separated by <paramref name="separator"/>
        /// to <see cref="List{TTargetItem}"/>, <see cref="IList{TTargetItem}"/>, <see cref="ICollection{TTargetItem}"/> and <see cref="IEnumerable{TTargetItem}"/>.
        /// </summary>
        /// <typeparam name="TTargetItem">Type of collection item.</typeparam>
        /// <param name="repository">The repository to register converter to.</param>
        /// <param name="tryConvert">The converter delegate.</param>
        /// <param name="separator">Item separator.</param>
        /// <returns><paramref name="repository"/>.</returns>
        public static IConverterRepository AddStringToCollection <TTargetItem>(this IConverterRepository repository, OutFunc <string, TTargetItem, bool> tryConvert, string separator = ",")
        {
            Ensure.NotNull(repository, "repository");
            StringToCollectionConverter <TTargetItem> converter = new StringToCollectionConverter <TTargetItem>(separator, new DefaultConverter <string, TTargetItem>(tryConvert));

            return(repository
                   .Add <string, List <TTargetItem> >(converter)
                   .Add <string, IList <TTargetItem> >(converter)
                   .Add <string, ICollection <TTargetItem> >(converter)
                   .Add <string, IEnumerable <TTargetItem> >(converter));
        }
Пример #15
0
 /// <summary>
 /// Registers generic search handler for unregistered model identifiers.
 /// </summary>
 /// <param name="searchHandler">Search delegate for providing model view activator.</param>
 /// <returns>Self (for fluency).</returns>
 public ModelViewCollection <T> AddSearchHandler(OutFunc <IModelDefinition, IFactory <IModelView <T> >, bool> searchHandler)
 {
     Ensure.NotNull(searchHandler, "searchHandler");
     onSearchView.Add(searchHandler);
     return(this);
 }
Пример #16
0
 public FieldViewCollection <T> AddSearchHandler(OutFunc <Key, IFactory <IFieldView <T>, IFieldDefinition>, bool> searchHandler)
 {
     Ensure.NotNull(searchHandler, "searchHandler");
     onSearchView.Add(searchHandler);
     return(this);
 }
Пример #17
0
		/// <summary>
		/// Converts a function taking an "out" parameter to a function taking a "ref" parameter.
		/// </summary>
		/// <param name="func">The function to be converted.</param>
		/// <returns>The converted function.</returns>
		public static RefFunc<T, TRet> OutToRefFunc<T, TRet>(OutFunc<T, TRet> func)
		{
			return (RefFunc<T, TRet>)Delegate.CreateDelegate(TypeOf<RefFunc<T, TRet>>.TypeID, func.Target, func.Method);
		}
Пример #18
0
		/// <summary>
		/// Pins an "out" reference, so its internal address doesn't change.
		/// </summary>
		/// <param name="variable">The reference.</param>
		/// <param name="func">The function to receive the pinned reference.</param>
		/// <returns></returns>
		/// <returns>The value returned by <paramref name="func"/></returns>
		public static TRet Pin<T, TRet>(out T variable, OutFunc<T, TRet> func)
		{
			return CacheHelper<T>.WithRet<TRet>.Pin(out variable, OutToRefFunc(func));
		}
Пример #19
0
        private IReactiveBinding <TView, TViewModel, Tuple <object, bool> > BindImpl <TViewModel, TView, TVMProp, TVProp, TDontCare>(
            TViewModel viewModel,
            TView view,
            Expression <Func <TViewModel, TVMProp> > vmProperty,
            Expression <Func <TView, TVProp> > viewProperty,
            IObservable <TDontCare> signalViewUpdate,
            OutFunc <TVMProp, TVProp> vmToViewConverter,
            OutFunc <TVProp, TVMProp> viewToVmConverter)
            where TView : class, IViewFor
            where TViewModel : class
        {
            var signalInitialUpdate = new Subject <bool>();
            var vmExpression        = Reflection.Rewrite(vmProperty.Body);
            var viewExpression      = Reflection.Rewrite(viewProperty.Body);

            var signalObservable = signalViewUpdate != null
                                       ? signalViewUpdate.Select(_ => false)
                                       : view.WhenAnyDynamic(viewExpression, x => (TVProp)x.Value).Select(_ => false);

            var somethingChanged = Observable.Merge(
                Reflection.ViewModelWhenAnyValue(viewModel, view, vmExpression).Select(_ => true),
                signalInitialUpdate.Select(_ => true),
                signalObservable);

            var changeWithValues = somethingChanged.Select(isVm =>
            {
                TVMProp vmValue;
                TVProp vValue;
                if (!Reflection.TryGetValueForPropertyChain(out vmValue, view.ViewModel, vmExpression.GetExpressionChain()) ||
                    !Reflection.TryGetValueForPropertyChain(out vValue, view, viewExpression.GetExpressionChain()))
                {
                    return(null);
                }

                if (isVm)
                {
                    TVProp vmAsView;
                    if (!vmToViewConverter(vmValue, out vmAsView) || EqualityComparer <TVProp> .Default.Equals(vValue, vmAsView))
                    {
                        return(null);
                    }

                    return(Tuple.Create((object)vmAsView, isVm));
                }

                TVMProp vAsViewModel;
                if (!viewToVmConverter(vValue, out vAsViewModel) || EqualityComparer <TVMProp> .Default.Equals(vmValue, vAsViewModel))
                {
                    return(null);
                }

                return(Tuple.Create((object)vAsViewModel, isVm));
            });

            var ret = EvalBindingHooks(viewModel, view, vmExpression, viewExpression, BindingDirection.TwoWay);

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

            IObservable <Tuple <object, bool> > changes = changeWithValues.Where(tuple => tuple != null).Publish().RefCount();

            IDisposable disp = changes.Subscribe(isVmWithLatestValue =>
            {
                if (isVmWithLatestValue.Item2)
                {
                    Reflection.TrySetValueToPropertyChain(view, viewExpression.GetExpressionChain(), isVmWithLatestValue.Item1, false);
                }
                else
                {
                    Reflection.TrySetValueToPropertyChain(view.ViewModel, vmExpression.GetExpressionChain(), isVmWithLatestValue.Item1, false);
                }
            });

            // NB: Even though it's technically a two-way bind, most people
            // want the ViewModel to win at first.
            signalInitialUpdate.OnNext(true);

            return(new ReactiveBinding <TView, TViewModel, Tuple <object, bool> >(
                       view,
                       viewModel,
                       viewExpression,
                       vmExpression,
                       changes,
                       BindingDirection.TwoWay,
                       disp));
        }
Пример #20
0
 /// <summary>
 /// Creates new instance that converts by <paramref name="tryConvert"/>.
 /// </summary>
 /// <param name="tryConvert">Delegate for conversion of <typeparamref name="TSource"/> to <typeparamref name="TTarget"/>.</param>
 public DefaultConverter(OutFunc <TSource, TTarget, bool> tryConvert)
 {
     Ensure.NotNull(tryConvert, "converter");
     this.tryConvert = tryConvert;
 }
        public OutFunc <TSource, TTarget, bool> GetTryConverter <TSource, TTarget>()
        {
            Type sourceType = typeof(TSource);
            Type targetType = typeof(TTarget);

            // If target value is assignable from source, no conversion is needed.
            if (targetType.IsAssignableFrom(sourceType))
            {
                return((TSource sourceValue, out TTarget targetValue) =>
                {
                    targetValue = (TTarget)(object)sourceValue;
                    return true;
                });
            }

            // Find converter, look in storage or find using search handler.
            IConverter converter = null;
            Dictionary <Type, IConverter> sourceStorage;

            if (!storage.TryGetValue(sourceType, out sourceStorage) || !sourceStorage.TryGetValue(targetType, out converter))
            {
                onSearchConverter.TryExecute(new ConverterSearchContext(sourceType, targetType), out converter);
            }

            // If no converter was found, try context converters.
            if (converter == null && !IsConverterContextType(sourceType))
            {
                OutFunc <IConverterContext <TSource>, TTarget, bool> result = GetTryConverter <IConverterContext <TSource>, TTarget>();
                return((TSource sourceValue, out TTarget targetValue) => result(new DefaultConverterContext <TSource>(sourceValue, this), out targetValue));
            }

            // If no converter was found, conversion is not possible.
            if (converter == null)
            {
                return((TSource sourceValue, out TTarget targetValue) =>
                {
                    // If source value is null, return default value.
                    if (sourceValue == null)
                    {
                        targetValue = default(TTarget);
                        return true;
                    }

                    targetValue = default(TTarget);
                    return false;
                });
            }

            // Try cast to generic converter.
            IConverter <TSource, TTarget> genericConverter = converter as IConverter <TSource, TTarget>;

            if (genericConverter != null)
            {
                return(genericConverter.TryConvert);
            }

            // Convert using general converter.
            return((TSource sourceValue, out TTarget targetValue) =>
            {
                object targetObject;
                if (converter.TryConvert(sourceType, targetType, sourceValue, out targetObject))
                {
                    targetValue = (TTarget)targetObject;
                    return true;
                }

                // No other options for conversion.
                targetValue = default(TTarget);
                return false;
            });
        }
Пример #22
0
 public FuncBindingConverter(OutFunc <string, T, bool> converter)
 {
     Ensure.NotNull(converter, "converter");
     Converter = converter;
 }
 public OutFuncCollection <T, TOutput, TReturn> Remove(OutFunc <T, TOutput, TReturn> func)
 {
     Ensure.NotNull(func, "func");
     storage.Remove(func);
     return(this);
 }
 public OutFuncCollection(OutFunc <T, TOutput, TReturn> defaultFunc)
 {
     Ensure.NotNull(defaultFunc, "defaultFunc");
     this.defaultFunc = defaultFunc;
 }
 public IValidationHandlerCollection AddSearchHandler(OutFunc <Type, object, bool> searchHandler)
 {
     Ensure.NotNull(searchHandler, "searchHandler");
     onSearchHandler.Add(searchHandler);
     return(this);
 }
Пример #26
0
 private static void OutFunc_Method <T, R>(OutFunc <T, R> outFunc)
 {
 }
Пример #27
0
 /// <summary>
 /// Registers generic handler for providing feature.
 /// <paramref name="handler"/> takes typeof requested feature
 /// and returns <c>true</c> to indicate success; otherwise <c>false</c>.
 /// </summary>
 /// <param name="handler">Handler to register.</param>
 public void AddSearchHandler(OutFunc <Type, object, bool> handler)
 {
     Ensure.NotNull(handler, "handler");
     onSearchFeature.Add(handler);
 }
Пример #28
0
 /// <summary>
 /// Adds handle to be executed when coverting .NET type to XML type name and type mapping is missing.
 /// </summary>
 /// <param name="searchHandler">Handle to find type mapping.</param>
 /// <returns>Self (for fluency).</returns>
 public XmlTypeMappingCollection AddSearchNameHandler(OutFunc <Type, string, bool> searchHandler)
 {
     onSearchName.Add(searchHandler);
     return(this);
 }
Пример #29
0
 /// <summary>
 /// Adds <paramref name="searchHandler"/> to be executed when field metadata validator was not found.
 /// </summary>
 /// <param name="searchHandler">Field metadata validator method.</param>
 public FieldMetadataValidatorCollection AddSearchHandler(OutFunc <FieldMetadataValidatorKey, IFieldMetadataValidator, bool> searchHandler)
 {
     Ensure.NotNull(searchHandler, "searchHandler");
     onSearchValidator.Add(searchHandler);
     return(this);
 }
 public OutFuncWrapper(OutFunc <IReadOnlyKeyValueCollection, TKey, bool> inner)
 {
     Ensure.NotNull(inner, "inner");
     this.inner = inner;
 }