Moving existing code to a PCL

Hi,

Below is a piece of code that I've used quite a number of times on droid and iOS without a hitch but for a new project, could do with having it in a PCL. While most of it will work fine, the likes of GetMethod, GetProperties,GetCustomAttributes, IgnoreAttribute and Length aren't available in the PCL version of System.Type.

Any suggestions on how to move this across? I know I could refactor all of the Get[*] calls to use DI, but I'm guessing that I would need to make the calls to be async to ensure the flow continues correctly which will have a performance hit.

I've seen the likes of SHA256 brought to PCL by Microsoft (PCLCrypto is on nuget and has a MS shared code licence). Is there a way to do the same but for my example?

public string GetInsertQuery(Object entity)
        {
            var type = entity.GetType();
            if (!queryBuilders.ContainsKey(type))
            {
                var param = Expression.Parameter(typeof(Object), "entity");
                var typedObject = Expression.Variable(type, "obj");
                var stringBuilder = Expression.Variable(typeof(StringBuilder), "sb");
                var appendString = typeof(StringBuilder).GetMethod("Append", new[] { typeof(String) });
                var objectToString = typeof(Object).GetMethod("ToString");
                var code = new List<Expression>();
                code.Add(Expression.Assign(typedObject, Expression.Convert(param, type)));
                code.Add(Expression.Assign(stringBuilder, Expression.New(typeof(StringBuilder)))); 
                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(string.Format("INSERT INTO {0} (", type.Name))));

                var properties = type.GetProperties();
                for (int i = 0; i < properties.Length - 1; ++i)
                {
                    if (properties[i].GetCustomAttributes(typeof(IgnoreAttribute), 
                            false).Length > 0)
                        next;
                    code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(properties[i].Name)));
                    code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(", ")));
                }
                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(properties[properties.Length - 1].Name)));

                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(") VALUES (")));

                for (int i = 0; i < properties.Length - 1; ++i)
                {
                    code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant("'")));
                    code.Add(Expression.Call(stringBuilder, appendString, Expression.Call(Expression.Property(typedObject, properties[i]), objectToString)));
                    code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant("', ")));
                }

                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant("'")));
                code.Add(Expression.Call(stringBuilder, appendString, Expression.Call(Expression.Property(typedObject, properties[properties.Length - 1]), objectToString)));
                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant("', ")));

                code.Add(Expression.Call(stringBuilder, appendString, Expression.Constant(");")));

                code.Add(Expression.Call(stringBuilder, "ToString", new Type[] { }));

                var expression = Expression.Lambda<Func<Object, String>>(Expression.Block(new[] { typedObject, stringBuilder }, code), param);
                queryBuilders[type] = expression.Compile();
            }

            string f = queryBuilders[type](entity);
            return f;
        }

Thanks

Paul

Best Answer

Answers

  • That's cool - thanks and yes, I do use the async version of sqllite :)

Sign In or Register to comment.