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

前端之家收集整理的这篇文章主要介绍了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将不会触发.那么使用中会有两种不同的版本.

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

猜你在找的C#相关文章