mercredi 11 octobre 2023

How can I dynamically register DbSets into DbContext and add a row to the table?

I have too many entities and registering everyone of them is giving me a headache not to mention the load to instantiate the dbcontext. so I tried to dynamically register the dbsets.

To dynamically register DbSets into DbContext I used the article in this link: text I added an extension as a file:

public static class ModelBuilderExtensions
{
    public static void RegisterAllEntities<BaseModel>(this ModelBuilder modelBuilder, params Assembly[] assemblies)
    {
        IEnumerable<Type> types = assemblies.SelectMany(a => a.GetExportedTypes()).Where(c => c.IsClass && !c.IsAbstract && c.IsPublic &&
          typeof(BaseModel).IsAssignableFrom(c));
        foreach (Type type in types)
            modelBuilder.Entity(type);
    }
}

then I made an abstract class called BaseEntity that all my entities implimented.

and inside the ApplicationDbContext I overrode the OnModelCreating method:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            var entitiesAssemblyInt = typeof(BaseEntity<int>).Assembly;
            var entitiesAssemblyGuid = typeof(BaseEntity<Guid>).Assembly;
            modelBuilder.RegisterAllEntities<BaseEntity<int>>(entitiesAssemblyInt);
            modelBuilder.RegisterAllEntities<BaseEntity<Guid>>(entitiesAssemblyGuid);
        }

it works perfectly in migration but when I want to use the dbcontext in my commandHandler to add a row to my table named client I don't know how to call client from context.

context.Client.Add(client);

doesn't work because I didn't register the dbsets directly into dbcontext and there is no Client in the context.





Can i force a Type loaded in the default AssemblyLoadContext to return a type loaded in my plugin AssemblyLoadContext?

I am migrating an testing application from .NET Framework to .NET. The main purpose was to start another application and run tests on that application with nunit. For the sake of running multiple Test classes in succession, the application lived isolated in a dedicated AppDomain. In .NET this approach no longer works as there is only ever one AppDomain.

This approach was mainly used to make sure that everything was cleanly initialized (especially in regards to static members).

I am trying to rebuild this isolation with AssemblyLoadContext, by creating a new AssemblyLoadContext and loading all needed assemblies of the application into it and creating the TestSuite within that AssemblyLoadContext.

        private IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo, IPreFilter filter)
        {
            foreach (var suite in m_source.BuildFrom(typeInfo, filter))
            {
                m_context = new AssemblyLoadContext(suite.Name, true);
                var assembly = m_context.LoadFromAssemblyPath(typeof(PlatformTestSuite).Assembly.Location);
                m_context.LoadFromAssemblyPath(typeof(TestPlatform).Assembly.Location);
                m_context.LoadFromAssemblyPath(typeof(ServiceManager).Assembly.Location);
                m_context.LoadFromAssemblyPath(typeof(UserInterface).Assembly.Location);

                yield return (TestSuite)assembly.CreateInstance(typeof(PlatformTestSuite).FullName, false, BindingFlags.Default, null, new object[]{suite, m_context}, CultureInfo.CurrentCulture,  null);
            }
        }

This should ensure that all types used in the constructor are loaded from my newly created context. This works for most types, except the following:

var converter = TypeDescriptor.GetConverter(typeof(InformationViewModel));

Here, TypeDescriptor is loaded from the Default AssemblyLoadContext, as it is intended as a shared dependency. InformationViewModel is loaded from my custom context. The resulting type "InformationViewModelConverter" is also loaded from my custom context. However, the resulting converter is of type "InformationViewModelConverter", which is loaded from the Default AssemblyLoadContext. The converter in turn then uses only types loaded from the Default AssemblyLoadContext and cannot convert my types, as they are loaded from a different context.

My question

Is there a way to keep TypeDescriptor in the Default Context as a shared dependency and still make sure that created converter are of the type loaded from my custom context? If possible, this should happen without the programmer needing to think about it when using TypeDescriptor.GetConverter().





mardi 10 octobre 2023

Copy values from php object to eloquent entity

I am creating an API using laravel 10 and eloquent and I want to copy values from an object read from the http request to anoter object that is a laravel entity, I have an object with a lot of properties and I would like to copy automatically all the properties to another object so I can save the changes to the DB without copying values from request to model using $obj1->name = $request->name for each property in my object.

Let me explain:

I have this class:

class Usuarios extends Model
{
    protected $table = 'usuarios';
    protected $primaryKey = 'id';
    protected $fillable = [... a lot of properties]
}

I have this method in my controller:

function save(Request $request){
    $data = $request->all();
    $user = new Usuario($data);
    $userFromDB = Usuarios::find($data->id);
    // is there a way to do this? I just want to copy properties 
    // without creating a new object, or is there another way to do this? 
    // using reflection or something like that? or does laravel have 
    // any other way to do this without copying each value??
    copy_values($user,$userFromDB);  //????????????
    $userFromDB->save();
}

is this possible?

Thanks





Debugging Enumerators and Coroutines: Use Reflection to get the current line of an iterator block

I am building a Coroutine wrapper system. I would like users to be able to jump to the Coroutine's last yield statement, or "state".

The wrapper is implemented as an Enumerator wrapper, that is passed to StartCoroutine. I have access to the iterator object, its current value and the source MonoBehaviour.

Here's the gist of it

    public static CoroutineWrapper StartCoroutineWrapped(this MonoBehaviour component, IEnumerator coroutineEnumerator)
    {
      CoroutineWrapper wrapper = new(component, coroutineEnumerator);
      component.StartCoroutine(wrapper);
      return wrapper;
    }

public class CoroutineWrapper: IEnumerator
  {
    public readonly MonoBehaviour Source;

    public readonly IEnumerator Child;

    internal CoroutineWrapper(MonoBehaviour source, IEnumerator coroutine)
    {
      Source = source;
      Child = coroutine;
    }

    public bool MoveNext() => Child.MoveNext();

    public object Current => Child.Current;
  }

Currently, the only ways I have found to be able to do this:

  1. force the user to wrap their return value inside an object. In Debug mode, that object stores a stack trace in its constructor, which can be recovered.
yield return new YieldWrapper(null);
yield return new YieldWrapper(new WaitForEndOfFrame());
//etc

In Current or MoveNext, I check for the type of the yielded value, and store the frame if it is a YieldWrapper.

object Current {
  get {
    object current = Child.Current
    if (current is not YieldWrapper wrapper) return current;
    Trace = wrapper.Trace;
    return wrapper.Value;
  }
}
  1. allow the user to set a flag on the coroutine that will break on the next MoveNext call. Users can then move into the MoveNext call to see the current state.

  2. display the hidden "<>1__state" value of the iterator, which gives a rough idea of the state of the coroutine, but cannot be mapped to any line code.

Obviously they all have drawbacks

  1. Any yield statement that's not wrapped cannot be jumped to. Lots of needless allocations even in Release mode. Otherwise the best hope for a solution.

  2. Cannot see current state, only next one. Useless if a "WaitWhile" instruction is blocked and you want to find which one.

  3. Cannot actually be used as is, only by comparing it to others. Can tell you if a coroutine is actually changing state, or staying in the same one.

Potential ideas:

  • Find some way to get the stacktrace of a method before or after calling the method. If that were possible, I could easily do this with MoveNext and get a file name and line.

  • Find some hidden reflection magic to turn that "<>1__state" into a file position. Current research tells me "<>1__state" is not documented, not guaranteed to exist and might kill my dog if I rely on it in any way shape or form.

  • Instead of displaying said state, store it over multiple iterations to build a map of the iterator. But since I can never get a guaranteed stack trace inside the user coroutine, not actually that helpful. Could be used to infer that some states yield to more stalling maybe.

  • Simply use UniRx instead





jeudi 5 octobre 2023

How to find out type args of a superclass?

I have

trait Foo[T]
class Bar extends Foo[String]

If I do typeOf[Foo[String]].typeArgs, I get String back.

But typeOf[Bar].baseClasses.flatMap(_.typeArgs) is empty.

Is it impossible to find the actual complete super-type and a given type? (If it helps, I am actually writing a macro, so all the compile-time info should still be there ... though I don't think it actually matters, because I am only looking at types here, not actual objects) ...





mardi 3 octobre 2023

Scala/Java reflection array type

I am trying to instantiate case classes using reflection. I am using this reference code: https://gist.github.com/ConnorDoyle/7002426


import scala.reflect.runtime.universe._

object ReflectionHelpers extends ReflectionHelpers

trait ReflectionHelpers {

  protected val classLoaderMirror = runtimeMirror(getClass.getClassLoader)

  /**
    * Encapsulates functionality to reflectively invoke the constructor
    * for a given case class type `T`.
    *
    * @tparam T the type of the case class this factory builds
    */
  class CaseClassFactory[T: TypeTag] {

    val tpe = typeOf[T]
    val classSymbol = tpe.typeSymbol.asClass

    if (!(tpe <:< typeOf[Product] && classSymbol.isCaseClass))
      throw new IllegalArgumentException(
        "CaseClassFactory only applies to case classes!"
      )

    val classMirror = classLoaderMirror reflectClass classSymbol

    val constructorSymbol = tpe.declaration(nme.CONSTRUCTOR)

    val defaultConstructor =
      if (constructorSymbol.isMethod) constructorSymbol.asMethod
      else {
        val ctors = constructorSymbol.asTerm.alternatives
        ctors.map { _.asMethod }.find { _.isPrimaryConstructor }.get
      }

    val constructorMethod = classMirror reflectConstructor defaultConstructor

    /**
      * Attempts to create a new instance of the specified type by calling the
      * constructor method with the supplied arguments.
      *
      * @param args the arguments to supply to the constructor method
      */
    def buildWith(args: Seq[_]): T = constructorMethod(args: _*).asInstanceOf[T]

  }
}

Everything works great for most types of fields in the case class. My only issue is when trying to populate array fields.

Basically it boils down to this issue:

case class MyClass(arr: Array[String])

object Main {
  def main(args: Array[String]): Unit = {
    val f = new CaseClassFactory[MyClass]
    f.buildWith(Seq(Array[String]("1","2","3"))) //This works
    f.buildWith(Seq(Array[Object]("1","2","3"))) //This does not work
  }
}

Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaVanillaMethodMirror1.jinvokeraw(JavaMirrors.scala:415)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaMethodMirror.jinvoke(JavaMirrors.scala:380)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaVanillaMethodMirror.apply(JavaMirrors.scala:396)

In my use case the array is being created using reflection as well as an Array[Object]. I have the scala.reflect.api.Types#Type of the array field of the case class. I need to somehow convert the existing array to one with the correct type I understand the internal implementation of arrays causes the issue. How can I convert the array to the needed type at runtime. I tried to use Arrays.copyOf but did not get it to work





How to use Reflection in Java to dynamically create classes?

Im sorry if this will sound confusing but I will try best. I have a question about dynamically creating classes using reflection.

I have a holding class, that only has member attributes of 'subclasses', all the holding class's attributes are the same subclass type but just have different variable names.

The holding class will receive a json object with attributes like idNo, some text, and an identifier, this identifier will point to the specific subclass that will have its attributes created.

So three parts here

  1. Holding class with attributes of sub classes
  2. JSON Array
  3. HashMap that contains identier to the name of the subclass like

HashMap

    dictionary.put("blue", "two");
    dictionary.put("black", "one");
    dictionary.put("red", "three");
    dictionary.put("green", "four");

Json Array is something like

"[{\"identifier\":\"blue\",\"invoId\":1,\"questNo\":1,\"seqId\":\"1a\","answerText\":1},{\"identifier\":\"red\",\"invoId\":1,\"questNo\":2,\"seqId\":\"2a\",\"answerText\":0},{\"identifier\":\"green\",\"invoId\":1,\"questNo\":3,\"seqId\":\"3a\",\"answerText\":1},{\"identifier\":\"black\",\"invoId\":1,\"questNo\":4,\"seqId\":\"4a\"}.\"answerText\":0]"

As you can see, the JSONARRAY has a colour, the HashMap has a colour to a number, and that number specifies which subclass to construct.

HOLDING CLASS
`public class HoldingClass {
    private SubClass one;
    private SubClass two;
    private SubClass three;
    private SubClass four;`
    



SUBCLASS
'public class SubClass<T> {
    private String identifier;
    private String seqId;
    private int questNo;
    boolean answerText;
    private int invoId = 1;'

The part I cannot figure out, is how to use reflection such that, it points to a specific subclass attribute in the holding class, then construct's that subclass of the specific array element's info.

Any help would be greatly appreciated!