lundi 2 mars 2020

Add event handler using reflection

I have a .json file with so-called commands:

"Commands":[{
   "EventName": "MouseLeftButtonUp",
   "MethodToExecute": "NextJson",
   "Args": "Next.json"
},{
   "EventName": "MouseRightButtonUp",
   "MethodToExecute": "CloseApp"
}

I deserialize this json to this class:

    public class Command
    {
        [JsonPropertyName("EventName")]
        public string EventName { get; set; }

        [JsonPropertyName("MethodToExecute")]
        public string MethodToExecute { get; set; }

        [JsonPropertyName("Args")]
        public string Args { get; set; }

        /*Methods*/
    }

EventName is a name of UIElement class events. MethodToExecute is a name of method to call, when event triggered. Args are the args, passed to the MethodToExecute.

I don't want my users to be able to call any method in the application, so I don't use reflection to get MethodInfo, instead I create Dictionary: Dictionary<string, Delegate> MethodsDictionary. The key in this dictionary is the name of method (MethodToExecute from Command class), and the value is something like this:

MethodsDictionary.Add(nameof(CloseApp), new Action(CloseApp));
MethodsDictionary.Add(nameof(NextJson), new Action<string>(NextJson));

Without using reflection, I'd added the event handler like this: button.MouseLeftButtonUp += (sender, args) => MethodsDictionary[command.MethodToExecute].DynamicInvoke(command.Args);, but I'd like to make a dynamic binding of events. Well, of course I can make it through ugly switch-case on command.Name property, but I still would like to try the solution with reflection. The solutuion, as I see it, should looke something like:

foreach (var command in commands)
{
    command.Bind(uielement, MethodsDictionary[command.MethodToExecute]);
}

//And command.Bind method is like:

public void Bind(UIElement uielement, Delegate methodToExecute)
{
    //I know there's no such method like GetEventHandler, just an example
    var handler = uielement.GetEventHandler(EventName);
    handler += methodToExecute.DynamicInvoke(Args);
}

I searched through several pretty similar questions:

Subscribe to an event with Reflection

https://social.msdn.microsoft.com/Forums/vstudio/en-US/d7f184f1-0964-412a-8659-6759a0e2db83/c-reflection-problem-subscribing-to-event?forum=netfxbcl

https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-hook-up-a-delegate-using-reflection

AddEventHandler using reflection

Add Event Handler using Reflection ? / Get object of type?

But these doesn't help me to solve the problem the way I want to. I tried some of the solutions above, but they didn't work out for me, failing with different exceptions.





Is it possible to get a correct sequence of declared methods in a class?

I need to get the correct declared annotaion-method name mapping because I am currently developing a system where the method declaration's relative orders matter.

Every test case in this system has a presetting annotation and postsetting annotation, so I need the actual delaration order to correctly execute everything in the presetting-test-postsetting sequence. I checked getMethods(), it returned methods with a random order in JDK13. Are there ways to achieve that rather than parsing code?

Anything is appreciated. Thanks.





How to create case class dynamically from list of parameters

I need to create case class run time as there can be a list of parameter changes each time, I run the program.Please can you provide example for the same.

Can we load case classes at run time in the scala application, if yes please provide the simple example.





Validate annotation on field when it changed

I have to validate the field when it is changed (both throw setter and reflection) in POJO. And I want to write an annotation to the field. The following code doesn't work:

    public class PriceValidator implements ConstraintValidator<Price, BigDecimal> {
    @Override
    public void initialize(Price contactNumber) {
    }
    @Override
    public boolean isValid(BigDecimal value, ConstraintValidatorContext cxt) {
        if (smtng) {
            {
                //do smtng
            }
        }
        return true;
    }
}

How it can be realized this validator? How I should write the annotation correctly?





How to use reflection set a customer field value in go?

Is there have any way use reflection to set a customer filed value. My code below.

type Credential{
Client *credentialClient
}

// Reflection
s := &Credential{}
a := reflect.ValueOf(s)
a = a.Elem()

// get the client filed I want to set
client := a.FieldByName("Client")

// c is the value I want to set to client
c := newCredentialClient(&result{})

// Here I want to set client value as c.
// But got error: cannot use c (variable of type *credentialClient) as reflect.Value value in argument to // client.Set
client.Set(c)

Is there have any way can let me set this client value as I expected? And I can make sure this client can be set since client.canSet() value is true. thanks in advance.





dimanche 1 mars 2020

How use reflect instance in go

Got a problem when trying ues reflect a instance to mock unit tests in go. Code below

type Credential struct{
client credentialClient
}

// This instance what would be test object.
func NewCredential() *Credential{
var client newCredentialClient(nil)
return &NewCredential(client:client)
}

// Below part code is NewCredential's execute logic.
// and I try to reflect newCredentialClient with different parameters "provide", so that I can do unit 
// tests.
type provider interface{
method() 
}

type credentialClient struct{
provid provider
}

// I want to reflect this instance to test.
type newCredentialClient(provid provider) *credentialClient{
if provid == nil{
provid = &a Sturct to execute real logic{}
}

return &credentialClient(provid: provid)
}

My question is that it seems we can reflect a struct, not a instance in go, correct? Or do your have any good suggestion can let me finish this test with reflection? I got this quetion from a go reflect example.

// Student a a
type Student struct {
    Name string
    Age  int
}

// SetName aa
func (c *Student) SetName(name string) {
    c.Name = name
    fmt.Printf("set name %s\n", c.Name)
}

func main() {
    stud1 := &Student{Name: "Geralt", Age: 22}
    val := reflect.ValueOf(stud1)
    val.MethodByName("String").Call(nil)

    fmt.Println(stud1.Name, stud1.Age)
}




::/lambda alternative: get Method safely in java 1.7

The code is wanted to be compatible with most devices, so it is written in java 1.7.

similar interfaces are used in code for an event system as "listeners"

interface
Updatable
{
  void
  update();
}

Events are called → call all "listeners"

spot(Method, Object... event);

for Updatable for example spotting an update is simple in java 1.8

spot(Updatable::update);
//or
spot(s->System.out.print(s), "Easy. Now let's save our planet!");

Attempts. Because this option is unavailable, two options are to consider. Both are using reflection (unsafe) to find out the Method to call

//util methods
static public @Nullable Method
method(Class<?> of, String name, Class... args)
{
  try { return of.getDeclaredMethod(name, args); }
  catch(Exception e)
  {
    Log.v(of.getSimpleName(),
          "method "+ name + Arrays.toString(args)
          +" does not exist in "+ of.getName(), e);
    return null;
  }
}

static @NotNull Class<?>[]
classes(@NotNull Object[] of)
{
  Class<?>[] type=new Class[of.length];
  for(int i=0; i<type.length; ++i)
  {
    type[i]= of[i].getClass();
  }
  return type;
}

0] finding out the Method by name each time

void
spot(Class<?> spotted_class, String name,
     Object... event)
{
  spot(method(spatted_class, name, classes(signal)),
       signal);
}

//usage
spot(Updatable.class, "update");

1] creating a constant for every method

static final Method
UPDATE= method(Updatable.class, "update");

//usage
spot(UPDATE);

Questions. Is there a

  1. safer
  2. simpler

way to implement my goal?