コード例 #1
0
ファイル: DeepSetAction.cs プロジェクト: programatt/SpecAid
        private bool UseWhenProperty(string firstColumnName)
        {
            _info = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(
                TargetType, firstColumnName);

            if (_info != null)
            {
                return(true);
            }

            _info = PropertyInfoHelper.GetIndexerPropertyInfo(
                TargetType, firstColumnName);

            if (_info == null)
            {
                return(false);
            }

            _isIndexer = true;

            var parameterType = _info.GetIndexParameters().First().ParameterType;

            _lookUp = Convert.ChangeType(firstColumnName, parameterType);

            return(true);
        }
コード例 #2
0
        public void AssignValue(object model, string path, object value, Type type)
        {
            PropertyInfo propertyInfo = null;
            var          parentObject = PropertyInfoHelper.GetProperty(model, path, out propertyInfo);

            PropertyInfoHelper.SetPropertyValue(propertyInfo, parentObject, value, type);
        }
コード例 #3
0
        public async Task <IList <TEntity> > GetByIdsAsync(IEnumerable <object> ids, IList <SortOrderModel> sortOrders = null, params Expression <Func <TEntity, object> >[] includes)
        {
            try
            {
                var mem            = PropertyInfoHelper.ExtractMemberExpression(EntityIDSelector.Body);
                var castMethod     = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(mem.Type);
                var containsMethod = typeof(Enumerable).GetMethods().First(f => f.Name == "Contains" && f.GetParameters().Length == 2).MakeGenericMethod(mem.Type);

                var idsAsKeyType            = castMethod.Invoke(null, new [] { ids });
                var idsAsConstantExpression = Expression.Constant(idsAsKeyType);

                var eqEx         = Expression.Call(containsMethod, idsAsConstantExpression, mem);
                var efExpression = Expression.Lambda <Func <TEntity, bool> >(eqEx, EntityIDSelector.Parameters);

                var query = GetQuery(EntityDbSet.AsQueryable(), sortOrders, includes);

                var ret = await query.Where(efExpression).ToListAsync();

                return(ret);
            }
            catch (Exception ex)
            {
                Logger?.Fatal($"Error in {_entityName} GetById", ex);
                throw;
            }
        }
コード例 #4
0
        protected virtual void SaveObject(T obj, Request request, IDbConnection connection, IDbTransaction transaction)
        {
            //Create dummy object whenever request's null
            string command    = null;
            Object parameters = null;


            if (request != null)
            {
                parameters = request.Parameters;
            }

            //Check if object has a Key. Then use that as the
            PropertyList properties = PropertyInfoHelper.GetProperties(obj);

            //Create a new set of dynamic parameters
            DynamicParameters dynParam = CreateDynParameters(obj, parameters);

            //Execute

            connection.Execute(SaveCommand(command), dynParam, commandType: CommandType.StoredProcedure, transaction: transaction);

            if (properties.KeyProperty != null)
            {
                //Set the value
                properties.KeyProperty.SetValue(obj, dynParam.Get <object>(properties.KeyProperty.Name), null);
            }

            SaveSubData(obj, request, connection, transaction);
        }
コード例 #5
0
        public override bool UseWhen()
        {
            _info = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(TargetType, ColumnName);

            if (_info == null)
            {
                return(false);
            }

            if (typeof(string).IsAssignableFrom(_info.PropertyType))
            {
                return(false);
            }

            if (typeof(IList).IsAssignableFrom(_info.PropertyType))
            {
                return(true);
            }

            if (IsGenericList(_info.PropertyType))
            {
                return(true);
            }

            if (typeof(IEnumerable).IsAssignableFrom(_info.PropertyType))
            {
                return(true);
            }

            return(false);
        }
コード例 #6
0
        protected virtual void RemoveDeletedObject(T obj)
        {
            var parentProperties = PropertyInfoHelper.GetProperties(obj.GetType());

            foreach (PropertyInfo dataListProp in parentProperties.DataListProperties)
            {
                //Child object on parent that is a List
                dynamic list = dataListProp.GetValue(obj, null);

                var tmoList = new List <IData>();
                tmoList.AddRange(list);
                foreach (var listObj in tmoList.GetDeleted())
                {
                    int count = list.Count;
                    for (var ix = 0; ix < count;)
                    {
                        if (listObj == list[ix])
                        {
                            list.Remove(list[ix]);
                            count--;
                        }
                        else
                        {
                            ix++;
                        }
                    }
                }
            }
        }
コード例 #7
0
ファイル: CompareAction.cs プロジェクト: timgifford/SpecAid
        public override bool UseWhen()
        {
            Info = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(TargetType, ColumnName);

            //could not find the property on the object
            return(Info != null);
        }
コード例 #8
0
        protected TEntity DoGetById(object id, Expression <Func <TEntity, object> >[] includes = null)
        {
            try
            {
                var mem = PropertyInfoHelper.ExtractMemberExpression(EntityIDSelector.Body);

                Expression val;

                if (id.GetType() == typeof(TEntity))
                {
                    val = Expression.Constant(Convert.ChangeType(GetEntityValue((TEntity)id), mem.Type));
                }
                else
                {
                    val = Expression.Constant(Convert.ChangeType(id, mem.Type));
                }

                var eqEx         = Expression.Equal(mem, val);
                var efExpression = Expression.Lambda <Func <TEntity, bool> >(eqEx, EntityIDSelector.Parameters);

                var query = GetQuery(EntityDbSet.AsQueryable(), null, includes);

                var ret = query.FirstOrDefault(efExpression);

                return(ret);
            }
            catch (Exception ex)
            {
                Logger?.Fatal($"Error in {_entityName} GetById", ex);
                throw;
            }
        }
コード例 #9
0
ファイル: DeepSetAction.cs プロジェクト: timgifford/SpecAid
        public override bool UseWhen()
        {
            // do deep property binding
            if (!(ColumnName.Contains('.')))
            {
                return(false);
            }

            var propertyNames = ColumnName.Split('.');

            if (propertyNames.Count() <= 1)
            {
                throw new Exception(string.Format("Can not find any property represented by deep-binding syntax: \"{0}\"", ColumnName));
            }

            Info = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(TargetType, propertyNames[0]);

            var nextColumnName = string.Join(".", propertyNames.Skip(1).ToList());

            deepAction = ColumnActionFactory.GetAction <ICreatorColumnAction>(Info.PropertyType, nextColumnName);

            if (deepAction == null)
            {
                return(false);
            }

            return(deepAction.UseWhen());
        }
コード例 #10
0
        private string GenerateKey(Request request, T obj = default(T), string nameSuffix = "")
        {
            if (request == null)
            {
                request = new Request();
            }

            if (request.Key != null)
            {
                return(request.Key);
            }

            string hash = string.Empty;

            if (request.Parameters == null && obj != null)
            {
                //Create parameters based on Key attribute on Object
                var propertyList = PropertyInfoHelper.GetProperties <T>();

                request.Parameters = new { Id = propertyList.KeyProperty.GetValue(obj, null) };
            }

            if (request.Parameters == null && obj == null)
            {
                request.Key = string.Format("{0}_{1}", typeof(T).Name, nameSuffix);
                return(request.Key);
            }

            var parameterType = request.Parameters.GetType();

            if (typeof(IDictionary <string, object>).IsAssignableFrom(parameterType))
            {
                var    p       = (IDictionary <string, object>)request.Parameters;
                string strHash = string.Format(
                    "{0}_{1}",
                    string.Join("_", p.Keys.OrderBy(k => k)),
                    string.Join("_", p.Values.OrderBy(v => Convert.ToString(v))
                                ));

                hash = strHash.ToLower();
            }
            else
            {
                hash = request.Parameters.GetHashCode().ToString();
            }

            var    type    = typeof(T);
            string typeKey = type.Name;

            if (type.IsGenericType)
            {
                var types = type.GetGenericArguments();
                typeKey = "Generic[" + string.Join("_", types.Select(t => t.Name)) + "]";
            }

            request.Key = string.Format("{0}{1}_{2}", typeKey, nameSuffix, hash);

            return(request.Key);
        }
コード例 #11
0
        private PropertyInfo GetPropertyInfo <TProperty>(Expression <Func <TObject, TProperty> > propertySelector)
        {
            var propertyInfo = PropertyInfoHelper.GetPropertyInfo(propertySelector);

            return(propertyInfo.GetValue(() => throw new CanNotBuildException <TBuilder>(
                                             $"Could not extract property from given propertySelector '{propertySelector}'."
                                             )));
        }
コード例 #12
0
 protected IPossible <TValue> GetValue <TValue>(
     Expression <Func <TObject, TValue> > propertySelector
     ) => HasValues() && IsPropertySet(propertySelector)
         ? _values
 .Where(kvp => kvp.Key.Name == PropertyInfoHelper.GetPropertyNameOrEmptyString(propertySelector))
 .Select(kvp => (TValue)kvp.Value)
 .FirstOrNoValue()
         : Possible.NoValue <TValue>();
コード例 #13
0
 private static IList <SwaggerModelPropertyData> GetPropertiesFromType(Type type)
 {
     return(type.GetTypeInfo().GetProperties()
            .Select(property => new SwaggerModelPropertyData
     {
         ExibitionName = PropertyInfoHelper.GetNameConsideringNewtonsoft(property, SwaggerConfig.JsonSerializerSettings),
         Name = property.Name,
         Type = property.PropertyType
     }).ToList());
 }
コード例 #14
0
        public new T Get(Request request)
        {
            var obj = default(T);

            if (request == null)
            {
                throw new ArgumentNullException("request", "Parameter can't be null");
            }

            if (request.LockForEdit)
            {
                EditModel <T> editObject;

                editObject = base.Get(CreateEditRequest(request));

                if (editObject != null)
                {
                    if (editObject.EditUser.Id == request.LockBy.Id)
                    {
                        obj = editObject.EditObject;
                    }
                    else
                    {
                        //TODO use better object names?
                        ThrowLockedBy(editObject.EditUser);
                    }
                }
                else
                {
                    //Only when negative ids.
                    try
                    {
                        Type           t    = request.Parameters.GetType();
                        PropertyInfo[] pi   = t.GetProperties();
                        var            prop = pi.FirstOrDefault(p => p.Name == "Id");

                        if (prop != null && ((int)(prop.GetValue(request.Parameters, null)) <= -1))
                        {
                            //Create default object. Uses user id as a way to get a unique way to save the object based on Id
                            obj = default(T);
                            var propertyList = PropertyInfoHelper.GetProperties <T>();
                            propertyList.KeyProperty.SetValue(obj, request.LockBy.Id * -1);
                            editObject.EditObject = obj;
                            base.Save(editObject, CreateEditRequest(request));
                        }
                    }
                    catch (Exception exp)
                    {
                        Logger.Error("Trying to find id when getting default object.", exp);
                    }
                }
            }

            return(obj);
        }
コード例 #15
0
        protected bool IsPropertySet <TValue>(Expression <Func <TObject, TValue> > propertySelector)
        {
            if (!HasValues())
            {
                return(false);
            }
            var propertyName = PropertyInfoHelper.GetPropertyNameOrEmptyString(propertySelector);

            return(_values.Keys
                   .Any(pi => pi.Name == propertyName));
        }
コード例 #16
0
        protected BaseRepository(ProfileLocationContext context, Expression <Func <TEntity, object> > idSelector)
        {
            if (context == null)
            {
                throw new ArgumentNullException("DbContext cannot be null");
            }

            _entityName = typeof(TEntity).Name;

            ProfileLocationContext = context;

            var prop = PropertyInfoHelper.GetPropertyInfo <TEntity>(idSelector);

            EntityIDSelector = idSelector;

            GetEntityValue = entity => prop.GetValue(entity);

            var key = context.Model.FindEntityType(typeof(TEntity)).FindPrimaryKey();

            if (key.Properties.Count != 1)
            {
                throw new NotSupportedException($"Model {_entityName} missing primary key or has composite key");
            }
            _isAutoGenerated = key.Properties.First().ValueGenerated != ValueGenerated.Never;

            if (_mapper == null)
            {
                _mapper = new MapperConfiguration(cfg =>
                {
                    //TODO Investigate Nested Classes with automapper
                    cfg.ShouldMapProperty = p => !((p.GetGetMethod().IsVirtual) || (p.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition())));

                    var mapper = cfg.CreateMap <TEntity, TEntity>();
                    mapper.ForAllMembers(opts => opts.Condition((src, dest, srcmember, o, rc) =>
                    {
                        if (srcmember == null)
                        {
                            return(false);
                        }

                        var defaultVal = srcmember.GetType().IsValueType ? Activator.CreateInstance(srcmember.GetType()) : null;
                        if (srcmember.Equals(defaultVal))
                        {
                            return(false);
                        }

                        return(true);
                    }));
                })
                          .CreateMapper();
            }

            Debug.WriteLine($"DBContext: {context.GetHashCode()} - {_entityName}Repository");
        }
コード例 #17
0
        public override bool UseWhen()
        {
            Info = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(TargetType, ColumnName);

            if (Info == null)
            {
                return(false);
            }

            var assignable = (typeof(IList).IsAssignableFrom(Info.PropertyType));

            return(assignable);
        }
コード例 #18
0
        private IEnumerable <SwaggerModelPropertyData> GetPropertiesFromType(Type type)
        {
            List <SwaggerModelPropertyData> models = new List <SwaggerModelPropertyData>();

            var properties = type.GetProperties()
                             .Select(property => new SwaggerModelPropertyData
            {
                Name          = property.Name,
                ExibitionName = PropertyInfoHelper.GetNameConsideringNewtonsoft(property, SwaggerConfig.JsonSerializerSettings),
                Type          = property.PropertyType
            });

            return(properties);
        }
コード例 #19
0
        public override bool UseWhen()
        {
            _info = PropertyInfoHelper.GetIndexerPropertyInfo(TargetType, ColumnName);

            if (_info == null)
            {
                return(false);
            }

            var parameterType = _info.GetIndexParameters().First().ParameterType;

            _lookUp = Convert.ChangeType(ColumnName, parameterType);

            return(true);
        }
コード例 #20
0
        protected DynamicParameters CreateDynParameters(object obj, Object parameters)
        {
            DynamicParameters dynParam;
            PropertyList      properties = PropertyInfoHelper.GetProperties(obj);

            //Custom parameters
            if (parameters != null)
            {
                dynParam = new DynamicParameters(parameters);
            }
            else if (properties.Any() && properties.KeyProperty != null)
            {
                dynParam = new DynamicParameters();
                foreach (PropertyInfo dataProp in properties.DataProperties)
                {
                    dynParam.Add(dataProp.Name, dataProp.GetValue(obj, null));
                }

                foreach (PropertyInfo dataObjProp in properties.DataObjectProperties)
                {
                    dynamic dataObj = dataObjProp.GetValue(obj, null);
                    if (dataObj != null)
                    {
                        PropertyList propObjproperties = PropertyInfoHelper.GetProperties(dataObj);

                        if (propObjproperties.KeyProperty != null)
                        {
                            dynParam.Add(string.Format("{0}{1}", propObjproperties.KeyProperty.ReflectedType.Name, propObjproperties.KeyProperty.Name), propObjproperties.KeyProperty.GetValue(dataObj, null));
                        }
                    }
                }
            }
            else
            {
                //Fallback, use all properties from the object as parameters.
                dynParam = new DynamicParameters(obj);
            }

            //Get key field on object

            if (properties.KeyProperty != null)
            {
                //Looked in Dapper source to see that it overwrites existing parameters =)
                dynParam.Add(properties.KeyProperty.Name, properties.KeyProperty.GetValue(obj, null), direction: ParameterDirection.InputOutput);
            }

            return(dynParam);
        }
コード例 #21
0
        private static bool OrderBy <T>(ref ITypeSearch <T> query, object item) where T : ProductContent
        {
            var searchSort = item as SortItem;

            if (searchSort == null)
            {
                return(false);
            }

            var expression = PropertyInfoHelper.GetLamdaExpression <T>(searchSort.Field);

            query = (searchSort.Ascending
                ? TypeSearchExtensions.OrderBy(query, expression)
                : TypeSearchExtensions.OrderByDescending(query, expression));

            return(true);
        }
コード例 #22
0
        public object Do(PropertyInfo info, string tableValue)
        {
            // get the link from recallaid
            // then traverse the object getting each property until the last one
            // then return it's value

            var splits = tableValue.Split('.').ToList();
            var tag    = splits[0];

            if (!RecallAid.It.ContainsKey(tag))
            {
                throw new Exception("Could not find tag/link: " + tag);
            }

            var recalledValue = RecallAid.It[tag];

            if (recalledValue == null)
            {
                throw new Exception("Could not find tag/link: " + tableValue);
            }

            object propertyValue        = recalledValue;
            string previousPropertyName = tag;

            foreach (var propertyName in splits.Skip(1))
            {
                if (propertyValue == null)
                {
                    throw new Exception(string.Format("Property is null \"{0}\" in tag \"{1}\"", previousPropertyName, tableValue));
                }

                var targetProperty = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(propertyValue.GetType(), propertyName);

                if (targetProperty == null)
                {
                    throw new Exception(string.Format("Could not find property \"{0}\" in tag \"{1}\"", propertyName, tableValue));
                }

                propertyValue        = targetProperty.GetValue(propertyValue, null);
                previousPropertyName = propertyName;
            }

            return(propertyValue);
        }
コード例 #23
0
        /// <summary>
        /// Save aditional data availabel on the object. Looks for DataObjAttribute
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="request"></param>
        /// <param name="connection"></param>
        /// <param name="transaction"></param>
        protected virtual void SaveSubData(T obj, Request request, IDbConnection connection, IDbTransaction transaction)
        {
            var parentProperties = PropertyInfoHelper.GetProperties(obj.GetType());

            foreach (PropertyInfo dataListProp in parentProperties.DataListProperties)
            {
                //Child object on parent that is a List
                dynamic list = dataListProp.GetValue(obj, null);

                var tmoList = new List <IData>();
                tmoList.AddRange(list);

                foreach (var listObj in tmoList.GetDeleted())
                {
                    var listObjSqlParameters = new DynamicParameters();

                    //Add the parent key id format [ClassName] + [Key property name]
                    listObjSqlParameters.Add(parentProperties.KeyProperty.Name, parentProperties.KeyProperty.GetValue(listObj, null));
                    string deleteSp = GetDeleteCommandFromType(listObj.GetType());

                    connection.Execute(deleteSp, listObjSqlParameters, transaction, commandType: CommandType.StoredProcedure);
                }

                foreach (var listObj in tmoList.GetNonDeleted())
                {
                    //Get props for an ovj in the List
                    PropertyList listObjProperties = PropertyInfoHelper.GetProperties(listObj);

                    DynamicParameters listObjSqlParameters = CreateDynParameters(listObj, null);

                    //Add the parent key id format [ClassName] + [Key property name]
                    listObjSqlParameters.Add(parentProperties.KeyProperty.ReflectedType.Name + parentProperties.KeyProperty.Name, parentProperties.KeyProperty.GetValue(obj, null));
                    string saveSp = GetSaveCommandFromType(listObj.GetType());

                    connection.Execute(saveSp, listObjSqlParameters, transaction, commandType: CommandType.StoredProcedure);

                    if (listObjProperties.KeyProperty != null)
                    {
                        //Set the value
                        listObjProperties.KeyProperty.SetValue(listObj, listObjSqlParameters.Get <object>(listObjProperties.KeyProperty.Name), null);
                    }
                }
            }
        }
コード例 #24
0
        protected async Task <TEntity> DoGetByIdAsync(object id, Expression <Func <TEntity, object> >[] includes = null)
        {
            try
            {
                var val          = Expression.Constant(id);
                var mem          = PropertyInfoHelper.ExtractMemberExpression(EntityIDSelector.Body);
                var eqEx         = Expression.Equal(mem, val);
                var efExpression = Expression.Lambda <Func <TEntity, bool> >(eqEx, EntityIDSelector.Parameters);

                var query = GetQuery(EntityDbSet.AsQueryable(), null, includes);

                return(await query.FirstOrDefaultAsync(efExpression));
            }
            catch (Exception ex)
            {
                Logger?.Fatal($"Error in {_entityName} GetByIDAsync", ex);
                throw;
            }
        }
コード例 #25
0
        /// <summary>
        ///   Used to create a Lambda Member Lookup based on Type and Specflow Table.
        ///   Resulting CustomComparer can be used in Collection Comparer and Fancy Printers
        /// </summary>
        private static CustomComparer <T> ComparerCreator <T>(Table table)
        {
            var contentComparer = CustomComparer <T> .CreateNew();

            for (var i = 0; i < table.Header.Count(); i++)
            {
                var propertyInfo = PropertyInfoHelper.GetCaseInsensitivePropertyInfo(typeof(T), table.Header.ElementAt(i));

                if (propertyInfo != null)
                {
                    // One dynamic property on the fly
                    var entityParam          = Expression.Parameter(typeof(T), "e");
                    var memberExpressionReal = Expression.MakeMemberAccess(entityParam, propertyInfo);
                    var memberExpressionObj  = Expression.Convert(memberExpressionReal, typeof(object));
                    var exp = Expression.Lambda <Func <T, object> >(memberExpressionObj, entityParam);

                    contentComparer.Add(exp);
                }
            }

            return(contentComparer);
        }
コード例 #26
0
        private SwaggerModelPropertyData CreateSwaggerModelPropertyData(PropertyInfo pi, JsonSerializerSettings jsonSerializerSettings)
        {
            var modelProperty = new SwaggerModelPropertyData
            {
                Type          = pi.PropertyType,
                Name          = pi.Name,
                ExibitionName = PropertyInfoHelper.GetNameConsideringNewtonsoft(pi, jsonSerializerSettings),
            };

            foreach (var attr in pi.GetCustomAttributes <ModelPropertyAttribute>())
            {
                modelProperty.Name          = attr.Name ?? modelProperty.Name;
                modelProperty.ExibitionName = modelProperty.Name;
                modelProperty.Description   = attr.Description ?? modelProperty.Description;
                modelProperty.Minimum       = attr.GetNullableMinimum() ?? modelProperty.Minimum;
                modelProperty.Maximum       = attr.GetNullableMaximum() ?? modelProperty.Maximum;
                modelProperty.Required      = attr.GetNullableRequired() ?? modelProperty.Required;
                modelProperty.UniqueItems   = attr.GetNullableUniqueItems() ?? modelProperty.UniqueItems;
                modelProperty.Enum          = attr.Enum ?? modelProperty.Enum;
            }

            return(modelProperty);
        }
コード例 #27
0
 /// <summary>
 /// Returns whether the view has the specified property.
 /// </summary>
 /// <param name="name">Property name.</param>
 /// <returns>True if the view has the property.</returns>
 public virtual bool HasProperty(string name) => PropertyInfoHelper.Find(_view, name) != null;
コード例 #28
0
        /// <summary>
        /// Returns the value of a property.
        /// </summary>
        /// <typeparam name="T">Property type.</typeparam>
        /// <param name="name">Property name.</param>
        /// <returns>Property value.</returns>
        public virtual T Get <T>(string name)
        {
            var propInfo = PropertyInfoHelper.Find(_view, name);

            return((T)propInfo?.GetValue(_view));
        }
コード例 #29
0
 /// <summary>
 /// Returns the <see cref="PropertyInfo"/> using a lambda selector.
 /// </summary>
 /// <typeparam name="TObject">The type of the object the property comes from.</typeparam>
 /// <param name="object">The object the property is retrieved from.</param>
 /// <param name="propertySelector">The lambda expression selecting the property.</param>
 public static string GetPropertyName <TObject, TResult>(
     this TObject @object,
     Expression <Func <TObject, TResult> > propertySelector
     )
 => PropertyInfoHelper.GetPropertyName(@object, propertySelector);
コード例 #30
0
        public void Test_getter_performance()
        {
            var test = new TestClass()
            {
                Value = "Hallo"
            };

            var    stopwatch = new Stopwatch();
            object a;

            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                var accessor = (typeof(TestClass).GetProperty("Value"));

                a = accessor.GetValue(test);//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - propertyinfo");

            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                var accessor = PropertyInfoHelper.GetAccessor(typeof(TestClass).GetProperty("Value"));

                a = accessor.GetValue(test);//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - accessor");

            var cachedAccessor = PropertyInfoHelper.GetAccessor(typeof(TestClass).GetProperty("Value"));
            var accessorCache  = new Dictionary <string, IPropertyAccessor>()
            {
                { "Value", cachedAccessor }
            };

            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                var accessor = accessorCache["Value"];

                a = accessor.GetValue(test);//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - cached accessor");

            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                var accessor = TypeHelpers.GetPropertyAccessor(typeof(TestClass), "Value");

                a = accessor.GetValue(test);//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - typehelper");


            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                a = test.Value;//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - direct");

            stopwatch.Restart();
            for (var i = 0; i < 100000; i++)
            {
                var accessor = FastMember.TypeAccessor.Create(typeof(TestClass));

                a = accessor[test, "Value"];//.Should().Be("Hallo");
            }

            stopwatch.Stop();
            Debug.WriteLine($"{stopwatch.ElapsedMilliseconds}ms - fastmember");
        }