是否可以在单个Windows服务上使用多个版本的protobuf-net?

时间:2016-03-02 20:18:16

标签: c# mef protobuf-net multiple-versions assembly-loading

我们的应用程序使用了一个相当新的protobuf-net(版本2.0.0.668),我正在尝试使用旧版本的protobuf-net(版本1.0.0.282)集成到另一个具有客户端库的系统。是否可以在同一个Windows服务上使用程序集解析器并排使用这些库?据我所知,这些版本在序列化程序和谷歌之间存在重大变化,并且版本之间有单独的protobuf协议中断更改。

我尝试使用程序集解析器方法,因为我们希望通过停止进程并通过线路为每个客户端调用来减少调用此客户端库的开销。我想让它并肩工作。

即使装配解析器到位(详情如下)。我打电话给一个Assembly.Load在需要旧protobuf的库上似乎得到了新版本。即使我没有绑定重定向。此外,我在项目文件中特别指定禁用自动生成绑定重定向。

为什么完全隔离的项目默认为新版本的protobuf,即使我指定了项目的特定版本引用以使用版本1.0.0.282?最终结果是我无法在需要版本1.0.0.282版本的protobuf.net的库上成功序列化protobuf消息。

我有不使用GAC的限制,也没有创建另一个服务来将调用包装到另一个服务上的旧版本客户端库,这使得它成为一个非常昂贵的调用,因为它已经过时了。

我的项目结构如下

  

解      | _WindowsService - 引用DLL LibraryA和DLLLibraryB      | _DLL_LibraryA - 引用protobuf 2.0.0.668和DLL_LibraryB      | _DLL_LibraryB - 引用protobuf 1.0.0.282和DLL_ThirdpartyClient

DLL_LibraryA和DLL_LibraryB项目设置时引用protobuf.net以使用特定版本而不复制本地版本。

我在WindowsService项目上创建了一个构建事件,用于复制protobuf-net文件 bin-> ThirdParty-> protobuf-net-> {version}文件夹,当触发appdomain resolveassembly事件时,程序集加载程序将发现这些文件夹。

即使我完全隔离了程序集并将项目配置设置为禁用自动生成绑定重定向(Disable automatic binding redirects)。我的程序集加载程序仅在2.0.0.668版本中调用。

有一件事是我们的解决方案是利用MEF进行合成和依赖注入。我想知道它是否有任何影响。同样基于我的解决方案的结构,DLL_LibraryA依赖于protobuf-net 2.0.0.668,并且通过DLL_LibraryB的依赖性与protobuf-net 1.0.0.282无关。 clr在这种情况下做了什么?有没有办法成功地做到这一点,而不会失去进程?是不是因为CLR总是决定让我加载最新版本的依赖性混合?

非常感谢任何信息。

详细信息:

  1. 创建版本解析程序 - 使用程序集解析器Using Side-by-Side assemblies to load the x64 or x32 version of a DLL

        public static Assembly VersionResolver(object sender, ResolveEventArgs args){
         var assemblyName = new AssemblyName(args.Name);
                var name = assemblyName.Name;
                var version = assemblyName.Version.ToString();
                string versionedAssemblyProbingPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
                                                   string.Format(@"{0}\{1}\{2}", THIRD_PARTY_FOLDER, name, version),
                                                   string.Format("{0}.dll", name));Assembly returnAssembly = null;
            if (File.Exists(versionedAssemblyProbingPath))
            {
                returnAssembly = Assembly.LoadFile(versionedAssemblyProbingPath);
            }
            else
            {
                //Log here and return null
            }
            return returnAssembly;
    }
    
  2. 在Windows服务程序中调用解析程序 -

    静态程序()     {         AppDomain.CurrentDomain.AssemblyResolve + = VersionResolver;     }

0 个答案:

没有答案