Home > Net >  Create a new type based on other type, just changing the name
Create a new type based on other type, just changing the name

Time:09-21

The question is straightforward.

I have a type and want to create a new type, based on this type and just want to change the name.

Example:

        var oldType = someObject.GetType();

        var type = CreateNewType(oldType, "newType");

Please let me explain myself:

I'm creating several databases dynamically (by adding the model on an EF Core context). This works great but only on the first try but not on the second one because he keeps the previous tables as singleton contexts (attached to the type for what I have seen).

Thank you,

CodePudding user response:

The only way to build a new type at run-time is to use some heavy-duty reflection to create IL code on the fly:

That having been said, unless you have very specific need for that, this smells like an XY problem. I suggest that you create a new question describing the specific problem you are facing with EF core (including a minimal reproducible example) and let the EF specialists suggest an alternative solution.

CodePudding user response:

Just here to answer the question itself, even though is the best solution:

Can be adapted from here:

Creating dynamic type from TypeBuilder with a base class and additional fields generates an exception

Code:

public class ClassBuilder
{
    readonly AssemblyName _assemblyName;

    public ClassBuilder(string className)
    {
        _assemblyName = new AssemblyName(className);
    }

    public Type CopyType(Type type, string name)
    {
        var assemblyBuilder =
            AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");

        TypeBuilder typeBuilder = moduleBuilder.DefineType(_assemblyName.FullName
            , TypeAttributes.Public |
              TypeAttributes.Class |
              TypeAttributes.AutoClass |
              TypeAttributes.AnsiClass |
              TypeAttributes.BeforeFieldInit |
              TypeAttributes.AutoLayout
            , type);

        typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName |
                                             MethodAttributes.RTSpecialName);

        return typeBuilder.CreateType();
    }
}
  • Related