lundi 8 juillet 2019

Replace existing class definition at runtime with newly created type

Demorepo:

https://github.com/gabbersepp/csharp-dynamic-replace-class

How to use:

  1. Checkout
  2. Compile
  3. Delete TestLib.dll & TestLib.pdb from console/bin/Debug
  4. Execute console.exe through cmd

Read first:

I have something in mind I want to achieve at work and I think that this would be the best solution. So please do not discuss if I can solve this with another way. If I would like to discuss about this, I will create a new SO post.

Given:

A class in a lib:

namespace Test.TestLib
{
    public class Class1
    {
    }
}

And a second class which creates an instance of it:

namespace console
{
    public class AnotherClass
    {
        public void Create()
        {
            new Class1();
        }
    }
}

And a console app that calls create:

    static void Main(string[] args)
    {
        //...
        new AnotherClass().Create();
    }

Please keep in mind that only Class1 is in an extra lib. The other two classes are in the same.

What I want to do:

Replace the Type Class1 at runtime:

        AssemblyName dynamicAssemblyName = new AssemblyName("TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
        dynamicAssembly =
            AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, AssemblyBuilderAccess.Run);
        var dynamicModule = dynamicAssembly.DefineDynamicModule("TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
        var modelType = dynamicModule.DefineType("Test.TestLib.Class1", TypeAttributes.Class).CreateType();

This works. If i am using the Activator: Activator.CreateInstance(modelType); I get a new instance of this type.

But:

When the line with new Class1 is reached, an exception is thrown:

Unbehandelte Ausnahme: System.MethodAccessException: Fehler beim Versuch der Methode "console.AnotherClass.Create()", auf Methode "Test.TestLib.Class1..ctor()" zuzugreifen. bei console.AnotherClass.Create()

Something like:

Unhandled exception: System.MethodAccessException: An error occurred while trying to access the method "console.AnotherClass.Create ()" method "Test.TestLib.Class1..ctor ()".     at console.AnotherClass.Create ()

Question:

Is this possible?

Sidenote: The deletion of the TestLib files from the /debug folder is required because otherwise the AsemblyResolve Event (please see the repo for a full example) is not raised





Aucun commentaire:

Enregistrer un commentaire