예제 #1
0
        public void Update_an_object_using_precompiled_accessors()
        {
            var bingo = new Bingo
            {
                X = 3,
                Y = 4
            };

            var x = CompiledAccessors.CompiledGetter(typeof(Bingo), "X")(bingo);

            Assert.AreEqual(3, x);

            CompiledAccessors.CompiledSetter(typeof(Bingo), "X")(bingo, 4);
            x = CompiledAccessors.CompiledGetter(typeof(Bingo), "X")(bingo);
            Assert.AreEqual(4, x);

            var smartSetter = CompiledAccessors.CompiledSmartSetter(typeof(Bingo), "Message");

            Assert.IsNotNull(smartSetter);

            // a smart setter sets the property only if value is different
            var changed = smartSetter(bingo, "test");

            Assert.IsTrue(changed);

            changed = smartSetter(bingo, "test");
            Assert.IsFalse(changed);

            changed = smartSetter(bingo, "different");
            Assert.IsTrue(changed);
        }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="root">the root (entry point) of the object graph</param>
        /// <param name="parent">the owner of the property</param>
        /// <param name="value"></param>
        /// <returns></returns>
        public ICollection <string> SetProperty(string propertyName, object root, object parent, object value)
        {
            var modified = new HashSet <string>();

            var smartSetter = CompiledAccessors.CompiledSmartSetter(parent.GetType(), propertyName);

            var hasChanged = smartSetter(parent, value);

            if (hasChanged)
            {
                modified.Add(propertyName);
                Cascade(propertyName, root, modified, 1);
            }

            return(modified);
        }
        /// <summary>
        ///     Intercept calls to property getters. Let the invocation being done normally for now
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            try
            {
                var getter       = CompiledAccessors.CompiledGetter(_wrappedObject.GetType(), binder.Name);
                var getterResult = getter(_wrappedObject);

                result = IsComplexType(getterResult.GetType())
                    ? new DynamicWrapper <T>(_root, getterResult, _businessRules)
                    : getterResult;

                return(true);
            }
            catch
            {
                result = null;
                return(false);
            }
        }
예제 #4
0
        public void Precompiled_accessors_are_much_faster_then_reflexion_based_ones()
        {
            var property = typeof(Bingo).GetProperty("X");

            var getter      = CompiledAccessors.CompiledGetter(typeof(Bingo), "X");
            var setter      = CompiledAccessors.CompiledSetter(typeof(Bingo), "X");
            var smartSetter = CompiledAccessors.CompiledSmartSetter(typeof(Bingo), "X");

            var bingo = new Bingo
            {
                X = 3,
                Y = 4
            };

            var time0 = TimeInMilliseconds(i =>
            {
                var before = (int)getter(bingo);
                setter(bingo, before + 1);
            }, 1000000);

            Console.WriteLine("Compiled took {0} ms", time0);

            var time1 = TimeInMilliseconds(i =>
            {
                var before = (int)property.GetValue(bingo);
                property.SetValue(bingo, before + 1);
            }, 1000000);

            Console.WriteLine("Reflexion-based took {0} ms", time1);

            var time2 = TimeInMilliseconds(i => smartSetter(bingo, i), 1000000);

            Console.WriteLine("Compiled smart seter took {0} ms", time2);

            Assert.Less(time2 * 5, time1); // compiled smart setters should be faster
            Assert.Less(time0 * 5, time1); // compiled accessors should be much faster than reflexion based ones
        }