c# – 我可以让我的程序集参考任何版本的另一个程序集吗?

>我正在开发一个类库(MyClassLibrary).
>我依赖于第三方类库(ThirdPartyClassLibrary).
>我需要使用与用户相同版本的ThirdPartyClassLibrary.例如,如果我在ThirdPartyClassLibrary中设置静态值,则用户需要看到该更改.
>我的类的用户可能取决于ThirdPartyClassLibrary的4个不同版本中的任何一个.
> ThirdPartyClassLibrary很大,我不想用我的软件分发它.
>我已经反映了所有4个版本的ThirdPartyClassLibrary,并验证我将要做的事情与所有版本兼容(接口是一样的,方法签名是一样的).
>我需要调用ThirdPartyClassLibrary来执行性能!每当我需要打电话时,我都无法反思一切.
> MyClassLibrary将在运行时被加载,所以我不能指望用户混淆程序集绑定重定向其他开发时间设置(或任何设置,我的用户都拒绝做任何事情).
>我希望从编译时检查我的代码中受益,所以理想的是没有反思.

如何编写MyClassLibrary,以便在加载进程时,用户加载的ThirdPartyClassLibrary的任何版本都能正常工作?

解决方法

一个解决办法是在运行时使用 AppDomain.AssemblyResolve 事件.每当装配体的分辨率失败时,都会触发.您可以使用它将不同版本的程序集加载到CLR尝试加载的程序集.

我在GitHub上添加一个非常简单的演示:

https://github.com/danmalcolm/AssemblyResolutionDemo

这个设置如下:

>主要应用程序App.exe直接引用程序集ThirdPartyLibrary.dll 2.0.0.0版.
>它还引用了MyLibrary,它引用了旧版本的ThirdPartyLibrary 1.0.0.0版本.
> AppDomain.AssemblyResolve事件用于重定向到版本1.0.0.0无法加载时应用程序使用的版本

AssemblyResolve的处理方式如下:

public static void Initialise()
{
    AppDomain.CurrentDomain.AssemblyResolve += ResolveThirdPartyLibrary;
}

private static Assembly ResolveThirdPartyLibrary(object sender,ResolveEventArgs args)
{
    // Check that CLR is loading the version of ThirdPartyLibrary referenced by MyLibrary
    if (args.Name.Equals("ThirdPartyLibrary,Version=1.0.0.0,Culture=neutral,PublicKeyToken=fbcbfac3e44fefed"))
    {
        try
        {
            // Load from application's base directory. Alternative logic might be needed if you need to 
            // load from GAC etc. However,note that calling certain overloads of Assembly.Load will result
            // in the AssemblyResolve event from firing recursively - see recommendations in
            // http://msdn.microsoft.com/en-us/library/ff527268.aspx for further info
            var assembly = Assembly.LoadFrom("ThirdPartyLibrary.dll");
            return assembly;
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }
    return null;
}

我们需要绑定到在加载ThirdPartyLibrary之前的事件,因此显式的Initialise方法.

还要注意,事件只有在组件的分辨率失败时才会触发.如果MyClassLibrary(1.0.0.0)引用的ThirdPartyLibrary的版本在GAC中可用,那么它将被成功加载,而AssemblyResolve将不会触发.那么使用中会有两种不同的版本.

在这里展示这种机制可以使用,我不是说这是一个好主意.您需要根据应用程序运行的环境及其设置/安装/维护等方式考虑几件事情.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...