加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 18:10:45 所属栏目:百科 来源:网络整理
导读:我正在开发一个类库(MyClassLibrary). 我依赖于第三方类库(ThirdPartyClassLibrary). 我需要使用与用户相同版本的ThirdPartyClassLibrary.例如,如果我在ThirdPartyClassLibrary中设置静态值,则用户需要看到该更改. 我的类的用户可能取决于ThirdPartyClassLib
>我正在开发一个类库(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将不会触发.那么使用中会有两种不同的版本.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读