使用干净的静态变量第二次加载相同的程序集

问题描述 投票:0回答:1

我有一个无法修改的.dll库,它带有使用许多静态变量和单例实例的类。现在,我需要所有这些类的第二个实例,并且需要一些解决方案,该解决方案可以在某个类的实例之间隔离静态变量,而无需更改程序集的任何其他属性。

第二次加载相同的程序集实际上并没有再次加载,但是我发现将其读取到字节数组然后加载,实际上解决了一半问题:

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();
        }
    }
}

此返回:

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

0
1

静态变量已重新启动,但不幸的是,下一个问题是库中使用的程序集位置为空。

我想避免将库加载到其他AppDomain,因为它会给跨域代码带来太多问题;有些类无法序列化。

我想避免物理上将库复制到磁盘上。

我想避免IL编织并使用Mono.Cecil或类似方法,因为这太过分了。

c# .net reflection static .net-assembly
1个回答
0
投票

将程序集加载到单独的AppDomain或单独的进程中只是您的明智选择。处理跨域/跨进程的通信,或者获取没有遇到问题的库版本。

© www.soinside.com 2019 - 2024. All rights reserved.