jeudi 3 novembre 2022

MakeGenericMethod For Max Is Not Working In .Net 6

So we recently migrated our project from .net framework 4.7.2 to .net 6 and we are testing the code for any issues , while testing i found out that the following method for Max is not working in .net 6

var maxOfStringMethod = (from method in typeof(Enumerable).GetMethods()
                                   where method.Name == "Max"
                        && method.GetParameters().Length == 2 &&
                        method.GetParameters()[1].ParameterType.GenericTypeArguments[1].IsGenericParameter
                                   select method).First().MakeGenericMethod(new Type[] { typeof(SomeViewModel), typeof(string) });

Above code method is for "TResult Max[TSource,TResult](System.Collections.Generic.IEnumerable1[TSource], System.Func2[TSource,TResult])".
It was working fine in .net framework 4.7.2 , but while testing the migrated code in .net 6 it throws "ArrayOutOfBoundsException" So i tried changing the above code to following for getting same result from Enumerable methods in .Net 6

  var maxOfStringMethod = (from method in typeof(Enumerable).GetMethods()
                where method.Name == "Max"
                      && method.GetParameters().Length == 2 &&
                      method.GetParameters()[0].ParameterType.GenericTypeArguments[0].IsGenericParameter
                select method).ElementAt(1).MakeGenericMethod(new Type[] { typeof(SomeViewModel), typeof(string) });

Now it's throwing "System.ArgumentException: 'The type or method has 1 generic parameter(s), but 2 generic argument(s) were provided. A generic argument must be provided for each generic parameter.' " I dont know what to do to solve this next , any help will be much appreciated





How get class by name with generic or how correct realize this problem?

I want dinamycally load catalogs to DevExpress grid and repositories. Some columns reference to other tables. I want to realize without "if-else, switch" methods, solve with generic for example. My project consists of entity framework, unitofwork etc.

RepositoryItemLookUpEdit repositoryItemLookUpEdit = new RepositoryItemLookUpEdit()
{
  ValueMember = repositoryItem.ValueMember,
  DisplayMember = repositoryItem.DisplayMember
;
// var objectType = GetTypeByName(repositoryItem.FinalTable);
if (repositoryItem.FinalTable=="DeviceTypes")
{
  objectList = GetObjectList<DeviceTypes>();
}
else if (repositoryItem.FinalTable == "DeviceKinds")
{
objectList = GetObjectList<DeviceKinds>();
}
 repositoryItemLookUpEdit.DataSource = objectList;
 bandedGridColumn.ColumnEdit = repositoryItemLookUpEdit;
---
private IEnumerable<T> GetObjectList <T>() where T : Entity
{
  IEnumerable<T> objectList=Enumerable.Empty<T>();
  using (var unitOfWork = new UnitOfWork(new ApplicationDbContext(optionsBuilder.Options)))
  {
     objectList = unitOfWork.GetRepository<T>().GetAll();
  }
  return objectList;
}
---
private T GetTypeByName<T>(string typeName) where T:Entity
{
   foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Reverse())
   {
      var type = assembly.GetType(typeName);
      if (type != null)
      {
         return type as T;
      }
   }
return null;
}




mercredi 2 novembre 2022

Check if a value of a property is null or default from reflected properties of a model [duplicate]

I want to perform some action if a value of a property is default or null by reflection. The following code gives "is a variable but is used like a type error" on default(t).

foreach(var p in dummyModel.GetType().GetProperties())
{
  var value = p.GetValue(dummyModel,null);
  var t = p.PropertyType;
  if(value != default(t)
  {
    //some action here
  }

}





mardi 1 novembre 2022

Using reflection is it possible to get a collection of types by namespace then use them in a generic system?

To be clear, I'm not looking for "How do you get a type from an object", I'm asking how to use a generic Type to also create a generic class.

Using the below code I'm looking to reference my classes within the "Foo" namespace and be able to use them again in my generic system:

var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => String.Equals(t.Namespace, "Foo", StringComparison.Ordinal)).ToArray();

What I would like to be able to do, is:

public class Bar<T>
{
   ...
}

... 

foreach (Type T in types)
{
    //Create a generic Bar with T
    //Something like new Bar<T>();
}

Is the current way I'm going about it the proper way and if so what would be the best way to handle Bar in this case?





In Java, detect if an Object is a Kotlin array

Sorry if this is very specific...

I am looking at Javapoet's implementation of AnnotationSpec.get(Annotation). It recursively clones an annotation so that you can copy it to another element. In my case, I am trying to copy an @OpenApi annotation from one method to another.

The issue is caused by the annotations being written in kotlin. Anywhere the annotation needs a class, it is using KClass<*>. Javapoet only handles Java types, like Class<?>. From Java, I can say if (o instanceof Class || o instance of KClass) no problem.

However, there's also code that says o.getClass().isArray() but, from what I can tell, kotlin annotations use Array<*> for arrays, so that check is failing. The actual type appears to be com.sun.proxy.$Proxy54 when I inspect it, but I have no idea what that is.

How do you detect if an object is an kotlin array from Java? Can this be converted to a Java array? Is there some universal way to make kotlin annotations appear as java annotations using Class and built-in arrays and so on?





How do I add java files at runtime and compile them during runtime?

I have to check whether a method exists or not in a java class but this java file is not present in the current classpath.

for example

I am running a java code then I have to check presence of java method which is not present in current project(i.e those java files are not compiled) those java files are present at a different location.

My Approach:

1. Adding those files to class path

2. compling each java file

3. then checking the presence of methods in a class specified

Codes:

public static void setClassPath(String path) {
    String cp = System.getProperty("java.class.path");
    cp = cp.replace(";.;", "");
    System.out.println("Before >>>>>>>>>>>>>>>>" + cp);
    String newcp = cp + System.getProperty("path.separator") + path;
    System.setProperty("java.class.path", newcp);
    System.out.println("After>>>>>>>>>>>>>>>>" + System.getProperty("java.class.path"));

}

public static void compileJavaFile() {
     // Compile source file.
        for (File f : javaFiles) {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            compiler.run(null, null, null, f.getAbsolutePath());
        }
    }




 public static boolean isMethodExist(String className, String methodName) {
        Class<?> classToCheck = null;
        try {
            classToCheck = Class.forName(className);
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
            return false;
        }
        try {

            Method[] declaredMethods = classToCheck.getDeclaredMethods();

            for (Method method : declaredMethods) {
                if (method.getName().equals(methodName)) {
                    return true;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return false;
    }




C# EF Core reflection order

I would kindly ask you for help.

When I have queryable such as

var query = dbSet.AsQueryable();

and I would like to dynamicly set orderBy using reflection

var orderBy = "School.Name"
query = query.OrderBy("School.Name");
var data = await query.ToListAsync()

I do have extension to support order like this using reflection as following:

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return source.OrderBy(ToLambda<T>(propertyName));
}

private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{    
    var parameter = Expression.Parameter(typeof(T));
    var property = Expression.Property(parameter, propertyName);
    var propAsObject = Expression.Convert(property, typeof(object));

    return Expression.Lambda<Func<T, object>>(propAsObject, parameter);
}

Problem is to create lambda for inner object property such as School.Name. This solution works for Name attribute on Dbset object, but not on joinned.

Goal is to modify ToLambda method to support joinned or inners properties.

using

query.OrderBy("School.Name"); 
// instead of 
query.OrderBy(m => m.School.Name );

Thanks for your help.