Пример #1
0
        public void LookupGetAndSet()
        {
            var get = AccessorCache <Person> .LookupGet(p => p.Name, out var prop);

            Assert.AreEqual("Name", prop);

            var set = AccessorCache <Person> .LookupSet(p => p.Name, out prop);

            Assert.AreEqual("Name", prop);

            var person = new Person {
                Name = "tanaka"
            };

            get(person).Is("tanaka");
            set(person, "kimura");
            person.Name.Is("kimura");
        }
Пример #2
0
    public bool SetPropertyPathValue(object?value)
    {
        if (Source == null)
        {
            return(false);
        }

        if (Next != null)
        {
            return(Next.SetPropertyPathValue(value));
        }
        else
        {
            var setter = _setAccessor ?? (_setAccessor = AccessorCache.LookupSet(Source.GetType(), PropertyName));
            setter.DynamicInvoke(Source, value);
            return(true);
        }
    }
        /// <summary>
        /// Data binding method.
        /// </summary>
        /// <typeparam name="TView">View type</typeparam>
        /// <typeparam name="TProperty">Property type</typeparam>
        /// <param name="self">View</param>
        /// <param name="propertySelector">Target property selector</param>
        /// <param name="source">Source property</param>
        /// <returns>Data binding token</returns>
        public static IDisposable SetBinding <TView, TProperty>(
            this TView self,
            Expression <Func <TView, TProperty> > propertySelector,
            ReadOnlyReactiveProperty <TProperty> source)
            where TView : View
        {
            var d = new CompositeDisposable();

            bool   isUpdating = false;
            string propertyName;
            var    setter = AccessorCache <TView> .LookupSet(propertySelector, out propertyName);

            source
            .Where(_ => !isUpdating)
            .Subscribe(x => setter(self, x))
            .AddTo(d);
            return(d);
        }
Пример #4
0
    private static IObservable <TProperty> ObserveSimpleProperty <TSubject, TProperty>(
        this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector,
        bool isPushCurrentValueAtFirst = true)
        where TSubject : INotifyPropertyChanged
    {
        var isFirst  = true;
        var accessor = AccessorCache <TSubject> .LookupGet(propertySelector, out var propertyName);

        return(Observable.Defer(() =>
        {
            var flag = isFirst;
            isFirst = false;

            var q = subject.PropertyChangedAsObservable()
                    .Where(e => e.PropertyName == propertyName || string.IsNullOrEmpty(e.PropertyName))
                    .Select(_ => accessor.Invoke(subject));
            return (isPushCurrentValueAtFirst && flag) ? q.StartWith(accessor.Invoke(subject)) : q;
        }));
    }
        private static IDisposable CreateOneWayBinding <T, TTarget, TProperty>(IObservable <T> self, TTarget target, Expression <Func <TTarget, TProperty> > propertySelector, Func <T, TProperty> convert, TProperty propertyFallbackValue)
        {
            var propertyName = default(string);

            return(self
                   .Subscribe(value =>
            {
                var setter = AccessorCache <TTarget> .LookupSet(propertySelector, out propertyName);
                try
                {
                    setter(target, convert(value));
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    setter(target, propertyFallbackValue);
                }
            }));
        }
Пример #6
0
        /// <summary>Update by object's PropertyName.</summary>
        /// <param name="tableName">Target database's table.</param>
        /// <param name="updateItem">Table's column name extracted from PropertyName.</param>
        /// <param name="whereCondition">Where condition extracted from PropertyName.</param>
        /// <returns>Rows affected.</returns>
        public int Update(string tableName, object updateItem, object whereCondition)
        {
            Contract.Requires <ArgumentException>(!String.IsNullOrEmpty(tableName));
            Contract.Requires <ArgumentNullException>(whereCondition != null);
            Contract.Requires <ArgumentNullException>(updateItem != null);

            var update = string.Join(", ", AccessorCache.Lookup(updateItem.GetType())
                                     .Where(p => p.IsReadable)
                                     .Select(p => p.Name + " = " + parameterSymbol + p.Name));

            var where = string.Join(" and ", AccessorCache.Lookup(whereCondition.GetType())
                                    .Select(p => p.Name + " = " + parameterSymbol + "__extra__" + p.Name));

            var query = string.Format("update {0} set {1} where {2}", tableName, update, where);

            Contract.Assume(query.Length > 0);
            using (var command = PrepareExecute(query, CommandType.Text, updateItem, whereCondition))
            {
                return(command.ExecuteNonQuery());
            }
        }
Пример #7
0
        public void StructTest()
        {
            var accessors = AccessorCache.Lookup(typeof(TestMockStruct))
                            .OrderBy(x => x.Name)
                            .ToArray();

            accessors.Length.Is(10);
            accessors.All(a => a.DeclaringType == typeof(TestMockStruct));
            accessors.Take(8).All(a => a.IsReadable);
            accessors.Take(8).All(a => a.IsWritable);
            accessors.Select(a => a.Name).Is("Field1", "Field2", "Property1", "Property2", "Property3", "Property4", "Property5", "Property6", "PropertyReadOnly", "PropertySetOnly");

            object target = new TestMockStruct();

            accessors[0].SetValue(target, "a");
            accessors[2].SetValue(target, "b");
            accessors[4].SetValue(target, "c");
            accessors[6].IsWritable.Is(false);
            accessors[1].SetValue(target, 1);
            accessors[3].SetValue(target, 2);
            accessors[5].SetValue(target, 3);
            accessors[7].IsWritable.Is(false);
            accessors.Where(a => a.IsReadable).Select(a => a.GetValue(target))
            .Is("a", 1, "b", 2, null, 0, null);
            Enumerable.Repeat((TestMockStruct)target, 1)
            .SelectMany(m => new object[] { m.Field1, m.Field2, m.Property1, m.Property2, m.Property5, m.Property6 })
            .Is("a", 1, "b", 2, null, 0);

            var read = accessors[8];

            read.IsReadable.Is(true);
            read.IsWritable.Is(false);

            var write = accessors[9];

            write.IsReadable.Is(false);
            write.IsWritable.Is(true);
            write.SetValue(target, "test");
            Assert.AreEqual("test", ((TestMockStruct)target).AsDynamic().hiddenField);
        }
Пример #8
0
        /// <summary>
        /// InsertAndGetするためのパラメーターを生成します。
        /// </summary>
        /// <typeparam name="T">テーブルにマッピングされた型</typeparam>
        /// <param name="data">挿入するデータ</param>
        /// <returns>パラメーター</returns>
        private Tuple <DbCommand, DbParameter> CreateInsertAndGetParameter <T>(T data)
        {
            //--- command
            var     factory = DbProvider.GetFactory(this.DbKind);
            dynamic command = factory.CreateCommand();

            command.BindByName = true;
            command.Connection = (dynamic)this.Connection;
            if (this.Timeout.HasValue)
            {
                command.CommandTimeout = this.Timeout.Value;
            }

            //--- parameters
            DbParameter output = null;

            foreach (var x in TableMappingInfo.Create <T>().Columns)
            {
                dynamic parameter = factory.CreateParameter();
                parameter.ParameterName = x.PropertyName;
                parameter.DbType        = x.ColumnType;
                if (x.IsPrimaryKey)
                {
                    parameter.Direction = ParameterDirection.Output;
                    output = parameter;
                    command.CommandText =
                        $@"{PrimitiveSql.CreateInsert<T>(this.DbKind)}
returning {x.ColumnName} into :{x.PropertyName}";
                }
                else
                {
                    parameter.Direction = ParameterDirection.Input;
                    parameter.Value     = AccessorCache <T> .LookupGet(x.PropertyName)(data);
                }
                command.Parameters.Add(parameter);
            }

            //--- ok
            return(Tuple.Create((DbCommand)command, output));
        }
Пример #9
0
        /// <summary>
        /// バルク方式での挿入処理の準備を行います。
        /// </summary>
        /// <typeparam name="T">テーブルにマッピングされた型</typeparam>
        /// <param name="executor">バルク処理実行機能</param>
        /// <param name="data">挿入する生データ</param>
        /// <returns>挿入するデータ</returns>
        private DataTable SetupBulkInsert <T>(SqlBulkCopy executor, IEnumerable <T> data)
        {
            //--- タイムアウト
            if (this.Timeout.HasValue)
            {
                executor.BulkCopyTimeout = this.Timeout.Value;
            }

            //--- 対象テーブル名
            var info = TableMappingInfo.Create <T>();

            executor.DestinationTableName = info.FullName;

            //--- 列のマップ
            var table   = new DataTable();
            var getters = new List <Func <T, object> >();

            foreach (var x in info.Columns)
            {
                executor.ColumnMappings.Add(x.PropertyName, x.ColumnName);
                table.Columns.Add(new DataColumn {
                    ColumnName  = x.PropertyName,
                    DataType    = x.IsNullable ? Nullable.GetUnderlyingType(x.PropertyType) : x.PropertyType,
                    AllowDBNull = x.IsNullable
                });
                getters.Add(AccessorCache <T> .LookupGet(x.PropertyName));
            }

            //--- データ生成
            foreach (var x in data)
            {
                var row = table.NewRow();
                for (int i = 0; i < getters.Count; i++)
                {
                    row[i] = getters[i](x);
                }
                table.Rows.Add(row);
            }
            return(table);
        }
        private static IDisposable CreateOneWayToSourceBinding <T, TTarget, TProperty>(IReactiveProperty <T> self, TTarget target, Expression <Func <TTarget, TProperty> > propertySelector, Func <TProperty, T> convertBack, IObservable <Unit> targetUpdateTrigger, T sourceFallbackValue)
        {
            var propertyName = default(string);

            if (targetUpdateTrigger == null)
            {
                throw new NotSupportedException("OneWayToSource binding required targetUpdateTrigger parameter.");
            }
            return(targetUpdateTrigger
                   .Subscribe(_ =>
            {
                try
                {
                    self.Value = convertBack(AccessorCache <TTarget> .LookupGet(propertySelector, out propertyName)(target));
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    self.Value = sourceFallbackValue;
                }
            }));
        }
Пример #11
0
        /// <summary>
        /// Data binding method.
        /// </summary>
        /// <typeparam name="TView">View type</typeparam>
        /// <typeparam name="TProperty">Property type</typeparam>
        /// <param name="self">View</param>
        /// <param name="propertySelector">Target property selector</param>
        /// <param name="source">Source property</param>
        /// <param name="updateSourceTrigger">Update source trigger</param>
        /// <returns>Data binding token</returns>
        public static IDisposable SetBinding <TView, TProperty>(
            this TView self,
            Expression <Func <TView, TProperty> > propertySelector,
            ReactiveProperty <TProperty> source, Func <TView, IObservable <Unit> > updateSourceTrigger = null)
            where TView : UIBarItem
        {
            var d = new CompositeDisposable();

            bool   isUpdating = false;
            string propertyName;
            var    setter = AccessorCache <TView> .LookupSet(propertySelector, out propertyName);

            source
            .Where(_ => !isUpdating)
            .Subscribe(x => setter(self, x))
            .AddTo(d);
            if (updateSourceTrigger != null)
            {
                var getter = AccessorCache <TView> .LookupGet(propertySelector, out propertyName);

                updateSourceTrigger(self).Subscribe(_ =>
                {
                    isUpdating = true;
                    try
                    {
                        source.Value = getter(self);
                    }
                    finally
                    {
                        isUpdating = false;
                    }
                }).AddTo(d);
            }

            return(d);
        }
Пример #12
0
 public static IEnumerable <dynamic> OrderBy <T>(IEnumerable <dynamic> source, string property, bool isDescending)
 {
     return(isDescending ? source.OrderByDescending(AccessorCache.GetAccessor <dynamic>(property)) : source.OrderBy(AccessorCache.GetAccessor <dynamic>(property)));
 }
Пример #13
0
 public static IDisposable OneWayBind <TType, TProperty>(this TType type,
                                                         Expression <Func <TType, Action <TProperty> > > selector, IObservable <TProperty> observable)
 {
     return(observable.ObserveOnUIDispatcher()
            .Subscribe(x => { AccessorCache <TType> .LookupMethod(selector).Invoke(type).Invoke(x); }));
 }
Пример #14
0
 public AccessorCacheTests(ITestOutputHelper output)
 {
     this.output = output;
     AccessorCache <Person> .Clear();
 }
Пример #15
0
 public static IOrderedEnumerable <dynamic> ThenByDescending(this IOrderedEnumerable <dynamic> source, string property)
 {
     return(Enumerable.ThenByDescending <dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer <object> .Default));
 }
Пример #16
0
 public static IOrderedEnumerable <dynamic> OrderBy(this IEnumerable <dynamic> source, string property)
 {
     return(Enumerable.OrderBy <dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer <object> .Default));
 }
 public static Func <dynamic, object> PropertyAccessor(dynamic source, string property)
 {
     return(AccessorCache.GetAccessor(property));
 }
 public static object PropertyValue(dynamic source, string property)
 {
     return(AccessorCache.GetAccessor(property)(source));
 }
Пример #19
0
        public IRuleBuilderInitial <T, TType> RuleForProp <TType>(Expression <Func <T, ValidatableProperty <TType> > > expression)
        {
            var propName = expression.Body.ToString().Split(new char[] { '.' })[1];

            var param = Expression.Parameter(typeof(T), "a");

            var navigationProperty = typeof(T).GetRuntimeProperty(propName);

            var name = typeof(ValidatableProperty <TType>).GetRuntimeProperty("Value");

            var navigationPropertyAccess = Expression.MakeMemberAccess(param, navigationProperty);

            var nameAccess = Expression.MakeMemberAccess(navigationPropertyAccess, name);

            var lambdaAccess = Expression.Lambda <Func <T, TType> >(nameAccess, new List <ParameterExpression>()
            {
                param
            });

            var member = lambdaAccess.GetMember();

            var compiled = member == null || ValidatorOptions.DisableAccessorCache ? lambdaAccess.Compile() : AccessorCache <T> .GetCachedAccessor(member, lambdaAccess);

            var rule = new PropertyRule(member, compiled.CoerceToNonGeneric(), lambdaAccess, () => CascadeMode.Continue, typeof(TType), typeof(T));

            AddRule(rule);

            IRuleBuilderOptions <T, TType> ruleBuilder = new RuleBuilder <T, TType>(rule);

            ruleBuilder = ruleBuilder.WithName(propName);

            return((IRuleBuilderInitial <T, TType>)ruleBuilder);
        }
Пример #20
0
        /// <summary>
        /// When using the ValidatableProperty type, use this method to avoid needing to supply the ".Value"
        /// which is needed when using RuleForProp.
        /// </summary>
        /// <typeparam name="TType"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public IRuleBuilderInitial <T, TType> RuleForProp <TType>(Expression <Func <T, ValidatableProperty <TType> > > expression, CascadeMode cascadeMode = CascadeMode.Continue)
        {
            var lambdaExpression = (MemberExpression)expression.Body;

            var propName = lambdaExpression.Member.Name;

            var originalPropertyType = typeof(T).GetRuntimeProperty(propName);

            var actualPropertyToValidate = typeof(ValidatableProperty <TType>).GetRuntimeProperty("Value");

            var generatedExpression = Expression.Parameter(typeof(T), "a");

            var navigationPropertyAccess = Expression.MakeMemberAccess(generatedExpression, originalPropertyType);

            var lambdaNameMemberAccess = Expression.MakeMemberAccess(navigationPropertyAccess, actualPropertyToValidate);

            var lambdaAccess = Expression.Lambda <Func <T, TType> >(lambdaNameMemberAccess, new List <ParameterExpression>()
            {
                generatedExpression
            });

            var generatedMember = lambdaAccess.GetMember();

            var compiled = generatedMember == null || ValidatorOptions.DisableAccessorCache ? lambdaAccess.Compile() : AccessorCache <T> .GetCachedAccessor(generatedMember, lambdaAccess);

            var rule = new PropertyRule(generatedMember, compiled.CoerceToNonGeneric(), lambdaAccess, () => cascadeMode, typeof(TType), typeof(T));

            AddRule(rule);

            IRuleBuilderOptions <T, TType> ruleBuilder = new RuleBuilder <T, TType>(rule, this);

            ruleBuilder = ruleBuilder.WithName(propName);

            return((IRuleBuilderInitial <T, TType>)ruleBuilder);
        }
Пример #21
0
        /// <summary>If connection is not open then open and create command.</summary>
        /// <param name="query">SQL code.</param>
        /// <param name="commandType">Command Type.</param>
        /// <param name="parameter">PropertyName parameterized to PropertyName. if null then no use parameter.</param>
        /// <param name="extraParameter">CommandName set to __extra__PropertyName.</param>
        /// <returns>Setuped IDbCommand.</returns>
        protected IDbCommand PrepareExecute(string query, CommandType commandType, object parameter, object extraParameter = null)
        {
            Contract.Requires <ArgumentException>(!String.IsNullOrEmpty(query));
            Contract.Ensures(Contract.Result <IDbCommand>() != null);

            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }
            if (transaction == null && isUseTransaction)
            {
                transaction = connection.BeginTransaction(isolationLevel);
            }

            var command = connection.CreateCommand();

            command.CommandText = query;
            command.CommandType = commandType;

            if (parameter != null)
            {
                foreach (var p in AccessorCache.Lookup(parameter.GetType()))
                {
                    if (!p.IsReadable)
                    {
                        continue;
                    }

                    Contract.Assume(parameter != null);

                    if (p.GetValueDirect(parameter) is IDataParameter)
                    {
                        command.Parameters.Add(p.GetValueDirect(parameter));
                    }
                    else
                    {
                        var param = command.CreateParameter();
                        param.ParameterName = p.Name;
                        param.Value         = p.GetValueDirect(parameter);
                        command.Parameters.Add(param);
                    }
                }
            }
            if (extraParameter != null)
            {
                foreach (var p in AccessorCache.Lookup(extraParameter.GetType()))
                {
                    if (!p.IsReadable)
                    {
                        continue;
                    }

                    Contract.Assume(extraParameter != null);
                    var param = command.CreateParameter();
                    param.ParameterName = "__extra__" + p.Name;
                    param.Value         = p.GetValueDirect(extraParameter);
                    command.Parameters.Add(param);
                }
            }

            if (transaction != null)
            {
                command.Transaction = transaction;
            }

            return(command);
        }