Passing a type created in runtime to a static method

1

EDIT

My problem is this.

I need to generate a lambda expression that is of a type that I will only know at the time of execution, ie the type to be used will be passed in the classType parameter of the controller below. But the type I create in the runtime method is not compatible with the expression I need to create.

NOTE: The WhereEqualsNonTyped method recognizes the generated context type, but when using typeof () it returns the type 'System.object'.

Below the controller that calls the method to get the class type dynamically:

 [Route ("{classtype} / {id} / {key}")]
    public string GetObter (int id, string key, string classtype)
    {
        var attach = servico.ObterDinamico (classtype, id, includes);
        return attach.RetrieveFiles (key);
    }
}

Method that creates the context from the past type:

public object ObterDinamico(string typeName, int id, string [] includes = null)
    {
        Type tableEntity = Type.GetType ("My_Domain." + TypeName + ", My_Domain");

        IEnumerable <dynamic> dbObject = (IEnumerable <dynamic>)
                            typeof (DbContext) .GetMethod ("Set", Type.EmptyTypes)
                            .MakeGenericMethod (tableEntity)
                            .Invoke (bd, null);
        IQueryable <dynamic> result = dbObject.AsQueryable ();
        if (includes! = null)
            foreach (string i in includes)
                result = result.Include (i);
        return result.WhereEqualsNonTyped ("id", id, typeName);
    }

Lambda method that does not recognize type T in this case, so it does not generate the expression as accurate:

public static IQueryable <T> WhereEqualsNonTyped <T> (this IQueryable <T> query, string propertyName, dynamic value, string typeName)
{
    try
    {
        //sem essa instancia do Type para gerar o tipo dinâmico que preciso 
        //o método sempre dá erro assim que chega na linha 
        //MemberExpression
        var type = Type.GetType ("My_Domain." + typeName + ", My_Domain");
        ParameterExpression parameter = Expression.Parameter (type, "type");
        MemberExpression property = Expression.Property (parameter, propertyName);
        BinaryExpression expression = Expression.Equal (property, Expression.Constant (value, value.GetType ()));
        Expression <Func <T, bool >> predicate = Expression.Lambda <Func <T, bool >> (expression, parameter);
        return query.Where (predicate);
    }
    catch (Exception e)
    {
        return query;
    }
}

Currently the error that is generated is:

  

ParameterExpression of type 'My_Domain.my_object' can not be used   to delegate the parameter of type 'System.Object'

    
asked by anonymous 23.02.2018 / 19:28

1 answer

0

PROBLEM SOLVED

I was able to solve my problem in a very simple way, after some extensive research I saw that my problem was actually passing a dynamic type generated in runtime to a static method. And I managed to resolve this through reflection.

Below is my problem solved:

Controller que chama o método obterDinamico:
        [Route("{classtype}/{id}/{key}")]
        public string GetObter(int id, string key, string classtype)
        {
            var attach = servico.ObterDinamico(classtype, id, includes);
            return attach.RetrieveFiles(key);
        }

The problem solving was done in the method getType:

       public object ObterDinamico(string typeName, int id, string[] includes = null)
        {
            Type tableEntity = Type.GetType("My_Domain." + typeName + ", My_Domain");
            IQueryable<dynamic> dbObject = (IQueryable<dynamic>)
                                typeof(DbContext).GetMethod("Set", Type.EmptyTypes)
                                .MakeGenericMethod(tableEntity)
                                .Invoke(bd, null);
            IQueryable<dynamic> result = dbObject.AsQueryable();
//Chamo os metodos que preciso através da reflexão e com isso ele é instanciado com o tipo do objeto que é criado em runtime. Com isso meu problema foi resolvido
            MethodInfo notExcludeMethodInfo = typeof(ReflectionHelper).GetMethod("NaoExcluidos", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(tableEntity);
            MethodInfo whereEqualsMethodInfo = typeof(ReflectionHelper).GetMethod("WhereEquals", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(tableEntity);
            if (includes != null)
                foreach (string i in includes)
                    result = result.Include(i);
            result = (IQueryable<dynamic>)notExcludeMethodInfo.Invoke(null, new object[] { result });
            result = (IQueryable<dynamic>)whereEqualsMethodInfo.Invoke(null, new object[] { result, "id", id });
            return result.FirstOrDefault();
        }

One of the methods that are instantiated through reflection:

public static IQueryable<T> WhereEquals<T>(this IQueryable<T> query, string propertyName, dynamic value)
        {
            try
            {
                ParameterExpression parameter = Expression.Parameter(typeof(T), "type");
                MemberExpression property = Expression.Property(parameter, propertyName);
                BinaryExpression expressao = Expression.Equal(property, Expression.Constant(value, value.GetType()));
                Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(expressao, parameter);
                return query.Where(predicate);
            }
            catch (Exception e)
            {
                return query;
            }
        }
    
28.02.2018 / 20:05