jeudi 2 mai 2019

NestJS: Get current method name using reflect, via reflect DI data?

I think it maybe possible to get the current method name while inside nestjs. I don't really mean in an interceptor but using reflect.getMetaData or something similar.

What am I trying to do ?

Well in each method where i need a logger I am executing the following line of code

  createTerminusOptions(): TerminusModuleOptions {
    const logger = this.loggerFactoryService.getLogger({ category: `${TerminusOptionsService.name}::createTerminusOptions` })

As you can see, the TerminusOptionsService.name is strongly typed so if I refactor the name then it would break and be caught by the compiler. The method name is createterminusOptions but I am placing this inside a string. I would like to try and get this programmatically or strongly typed so that if I refactor then it either automatically changes OR it would throw an error as the name of the method has changed.

I know it was possible to use arguments.callee but this is banned in strict mode.

I think there is some metadata saved in the nestjs type system so I was hoping to be able to use something here ?

Of course, this would be classed as reflection so I don't want to add a large overhead - if this is possible, do you think its a bad idea because it would of a performance hit ?

Any ideas really appreciated

Thanks





mercredi 1 mai 2019

Generic parameters that are interfaces and classes via instance reflection

I am trying to implement the a class in Java with a generic type parameter E. Within this class I have a method that enables the passing in of a Method object that I perform operations with later. This Method, as I intend to use it, is supposed to accept two arguments, both of which are supposed to be E. Thus, when the Method is passed in, I would like to check that its parameters match expectations, and throw an exceptions if not. However, since I know of no way to check get E's runtime class directly, I have the constructor accept an object of type E as an example, and use this to create a Class object, which I then use for comparison. However, this idea breaks down when E is an interface or an abstract class because there is no longer a possible way to pass in an immediate instance of E, and all parameter type checking will now revolve around this subclass/implementing class. Is there a good way around this issue?

Here are the relevant sections of code:

public abstract class DataStructure<E>
{
    ...
    private Method method;
    protected final Class<?> ex;

    protected DataStructure(E example)
    {
    ...
    ex = example.getClass();
        method = null;
    }

    ...

    public void setModificationMethod(Method m)
    {
    Class<?>[] needed = new Class<?>[] {ex, ex};
    Class<?>[] given = m.getParameterTypes();
    if(given.length != needed.length)
    {
    throw new IllegalArgumentException("Invalid method.");
    }
    for(int i = 0; i < needed.length; i++)
    {
    if(!given[i].isAssignableFrom(needed[i]))
    {
        throw new IllegalArgumentException("Invalid method.");
    }
    }
    if(!Modifier.isStatic(m.getModifiers()))
    {
        throw new IllegalArgumentException("Non-static methods must also pass in an instance to use.");
    }
    method = m;
    }
    ...

    protected void modify(E presentData, E newData) throws ReflectiveOperationException
    {
        method.setAccessible(true);

            ...

            //after making sure that preconditions are met and that there is a method to call
            method.invoke(null, presentData, newData);
            method.setAccessible(false);
    }
}

I also handle the case where the method is an instance method, but that code is mostly redundant and irrelevant to my question, so it has been omitted.

Additionally, if there are any noticeable errors in my code, I would appreciate comments pointing them out. I am new to reflection as a whole and am still learning how to use it.





Someone help me with loading this dll with reflection and powershell?

I am trying to load a C# DLL into Powershell. I have searched and searched and tried a lot of different examples and I think I am just doing this wrong. I am trying to call a DLL, and have the DLL give me a string.

DLL

namespace Decrypt
{
    public class Class1
    {
        public void Decrypt(out string dsn)
        {
            //Console.Write("test");
            dsn = "test";
        }
    }
}


$assembly = [System.Reflection.Assembly]::ReflectionOnlyLoadFrom('c:\users\justin\desktop\decrypt.dll');
[Decrypt.Class1]::Decrypt.ToString();

MemberType          : Method
OverloadDefinitions : {string ToString()}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : string ToString()
Name                : ToString
IsInstance          : True





How to use a custom annotations validator POCO without any framework (no asp.net, no mvc, no ORM)

I have a custom validation class

using System;
using System.Collections.Generic;
using System.Reflection;

 internal class RequiredAttribute1 : Attribute
{
    public RequiredAttribute1()
    {
    }

    public void Validate(object o, MemberInfo info, List<string> errors)
    {
        object value;

        switch (info.MemberType)
        {
            case MemberTypes.Field:
                value = ((FieldInfo)info).GetValue(o);
                break;

            case MemberTypes.Property:
                value = ((PropertyInfo)info).GetValue(o, null);
                break;

            default:
                throw new NotImplementedException();
        }

        if (value is string && string.IsNullOrEmpty(value as string))
        {
            string error = string.Format("{0} is required", info.Name);

            errors.Add(error);
        }
    }
}

I am using it on the following object:-

class Fruit
{
 [RequiredAttribute1]
 public string Name {get; set;}

 [RequiredAttribute1]
 public string Description {get; set;}
}

Now, I want to run the validation rules on a list of fruits, to print to a string
All I can think of is :-

  1. Iterate through fruits
  2. For each fruit, iterate through its properties
  3. For each property, iterate through custom validators (only 1 here...)
  4. Call the Validate function
  5. Collect and print validator errors

Is there something easier than this and more built-in, for reading these annotations, without having to add framework dlls like (ASP.net / MVC /etc...) ?
This is just for a simple Console application.





Get type member's MemberInfo without iteration of all type members

I have written some version of the following method in a dozen different solutions:

//Get the string specified in the "Description" attribute of an enum value
public static string GetDescription<T>(this T enumVal) where T : Enum
{
    var type = enumVal.GetType();
    var member = type.GetMember(enumVal.ToString()).First();
    var attrib = member.GetCustomAttribute<DescriptionAttribute>();
    return attrib?.Description ?? null;
}

Given this enum:

public enum MyEnum
{
    [Description("The First")]  TheFirst,
    [Description("The Second")] TheSecond
}

I am then able to write the following code:

MyEnum.TheFirst.GetDescription()
>> "The First"

This method works and it's the only way I've seen people do it. Here's my question:

How can I get the MemberInfo without using Type.GetMember() to iterate the type members to match a string? If the input (MyEnum.TheFirst) is already a strongly qualified member, why does reflection require me to abandon that and essentially search for the member as a string?

The code I want to write is:

public static string GetDescription<T>(this T enumVal) where T : Enum
{
    var member = enumVal.GetMember(); //gets the fully qualified MemberInfo object
    var attrib = member.GetCustomAttribute<DescriptionAttribute>();
    return attrib?.Description ?? null;
}

I'm aware that I could write an extension method to do this, but it wouldn't solve the fundamental issue: that I have to use a string search (again, via the System.Reflection.GetMember(string name) method) just to get information that should already be readily available.

Please let me know if I'm thinking about this the wrong way, or if there's another, simpler approach to this.





Set interface field value with reflection

I wanna set field of a class. This field is an interface and i know only type at runtime not compile time. So i can't cast directly. I tried to get value and set i couldn't do.

I tried to Class.forname but when i call newIntsance getting error bcs interface don't have an constructor.

I tried to cast to child class but this time i got cast exception.

field.setAccessible(true);
Object obj = field.get(field.getType().newInstance());
Caused by: java.lang.NoSuchMethodException: com.bank.accounting.dao.DenemeDao.<init> ()


Object obj = annotatedFieldModel.getField().get(childclass.newInstance());


java.lang.IllegalArgumentException: Can not set com.bank.accounting.dao.DenemeDao field com.bank.accounting.service.MoneyTransferService.denemeDao to com.bank.accounting.dao.impl.DenemeDaoImpl
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)





Creating structs programmatically at runtime - possible?

Is it possible in Go to create a struct type programmatically (i.e. not in the compiled source code)?

We have a particular use case where a type will be created via user-defined metadata (so the schema/types are not known in advance) and will vary for every customer. We would then need to auto-generate REST services for those and persist them in a NoSQL backend. We would also need to define different dynamic validators per field (e.g. mandatory, regex, max/min size, max/min value, a reference to another type instance, etc.)

I was wondering if something similar is possible in the Go?