jeudi 14 novembre 2019

Load same assembly second time with clean static variables

I have a .dll library, which I cannot modify, with classes which uses many static variables and singleton instances. Now I need a second instance of all these classes and I need some solution which would isolate static variables between instances of some class without altering any other properties of the assembly.

Loading the same assembly second time doesn't actually load it again, but I found that reading it to byte array and then loading it, actually solves half of the problem:

lib.dll:

namespace lib
{
    public class Class1 : ILib
    {
        private static int i;

        public int DoSth()
        {
            return i++;
        }

        public string GetPath()
        {
            return typeof(Class1).Assembly.Location;
        }
    }
}

app.exe:

namespace test
{
    public interface ILib
    {
        int DoSth();
        string GetPath();
    }

    class Program
    {
        static void Main()
        {
            var assembly1 = Assembly.LoadFile(Path.GetFullPath(".\\lib.dll"));
            var instance1 = (ILib)assembly1.CreateInstance("lib.Class1");

            Console.WriteLine(instance1.GetPath());
            Console.WriteLine(instance1.DoSth());
            Console.WriteLine(instance1.DoSth());

            var assembly2 = Assembly.LoadFile(Path.GetFullPath(".\\lib.dll"));
            var instance2 = (ILib)assembly2.CreateInstance("lib.Class1");

            Console.WriteLine(instance2.GetPath());
            Console.WriteLine(instance2.DoSth());
            Console.WriteLine(instance2.DoSth());

            var assembly3 = AppDomain.CurrentDomain.Load(File.ReadAllBytes("lib.dll"));
            var instance3 = (ILib)assembly3.CreateInstance("lib.Class1");

            Console.WriteLine(instance3.GetPath());
            Console.WriteLine(instance3.DoSth());
            Console.WriteLine(instance3.DoSth());

            Console.Read();
        }
    }
}

this returns:

C:\bin\lib.dll
0
1
C:\bin\lib.dll
2
3

0
1

Static variables got restarted but unfortunately the next problem is that assembly location which is used within the library is empty.

I would like to avoid loading the library to different AppDomain because it creates too many problems with cross domain code; some classes are not serializable.

I would like to avoid physically copying the library on disk.

I would like to avoid IL weaving and using Mono.Cecil or similar because it's an overkill.





Aucun commentaire:

Enregistrer un commentaire