使用版本化的 .Net 程序集
在我们的处理软件中,我们正在从外部组件的一个版本转向更新的版本。 虽然程序集执行的总体任务是相同的,但 API 却截然不同,并且没有保持向后兼容性。 API 负责从外部站提取数据,这些外部站可能运行着匹配的新的或旧的 API(也没有向后兼容性)。 我们无法控制外部组件或外部站上的软件。 外部程序集没有强签名,并且程序集中的模块对于两个版本具有相同的名称。
我们不想维护处理软件的两个版本,而是希望动态地改进它,并让它根据要联系的外部站使用旧版本或新版本的外部组件。 我们能够确定外部站是否支持新版本,因此“版本”的选择可以或多或少明确。
因此,我们的设置是有一个外部程序集 ComLib.dll,有两个版本。 我们可以引用同一程序集/项目中的两个版本吗?在确定类型等时如何区分这两个程序集?
假设上述操作无法在单个程序集/项目中完成,我们可以实现特定于版本的“适配器”程序集,每个版本的外部程序集都有一个(我认为我们已经为此准备了足够的接口和抽象),但是我们应该注意哪些注意事项或一些特定设置以避免运行时类型/版本混淆(程序集解析/加载等)? .NET 运行时是否对此设置有足够的“并行”支持?
更新:这个问题的进一步扭曲只是为了让事情变得更有趣。 似乎外部程序集加载了其他程序集并使用外部配置文件。 由于不同的版本需要不同的配置文件和不同的附加程序集,因此每个版本都需要以某种方式加载与其版本匹配的附加程序集。
在我看来,我们想要的是每个版本的程序集在包含其配置文件和附加程序集的单独文件夹中使用“根”加载。 使用标准程序集解析器/加载器是否可以做到这一点,或者我们必须做一些魔术,也许手动加载程序集(在单独的AppDomains中?)以强制执行“根”文件夹?
In our processing software we are moving from one version of an external assembly to a newer version. While the overall task that the assembly performs are the same, the API is radically different and no backwards compatibility have been maintained. The API is responsible for extracting data from external stations which may be running with a matching new or the old API(also no backwards compatibility). We have no control of the software in the external assembly or on the external stations. The external assembly is not strongly signed and the module in the assembly have the same name for both versions.
Instead of maintaining two versions of our processing software we would like to evolve it dynamically and have it use either the old version or the new version of the external assembly dependent upon the external station to contact. We are able to determine if an external station supports the new version, so the choice of "version" can be more or less explicit.
So the setup is we have an external assembly ComLib.dll in two versions. Can we reference the two versions from the same assembly/project and how can we distinguish between the two assemblies when determining types etc?
Assuming that the above cannot be done from within a single assembly/project, we could implement version specific "adapter" assemblies, one for each version of the external assembly (I think we already have sufficient interfaces and abstractions in place for this) but are there caveats we should be looking out for or some specific settings to avoid type/version confusion at runtime (assembly resolving/loading etc.)? Are there sufficient "side-by-side" support in the .NET runtime for this setup?
UPDATE: A further twist to this question is added just to make things more interesting. Seems that the external assembly loads additional assemblies and uses external config files. Since the different versions needs different config files and different additional assemblies each version needs to somehow load the additional assemblies that match their version as well.
Seems to me that what we want is the assemblies from each version to be load with a "root" in a seperate folder that contains their config file and additional assemblies. Is this even possible with the standard assembly resolver/loader or would we have to do some magic and perhaps load assemblies manually (in seperate AppDomains?) to enforce "root" folders?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以在这里找到有关此选项的好文章:
http://kevin-berridge。 blogspot.com/2008/01/two-versions-of-same-shared- assembly.html
A good post about the options for this can be found here:
http://kevin-berridge.blogspot.com/2008/01/two-versions-of-same-shared-assembly.html
你说这个代码是用来和外站通信的。 为什么不使用与外部站通信的代码来制作服务呢? 该服务将从您当前的程序中调用。
这将允许您运行两个版本的服务 - 一种用于旧 API,另一种用于新 API。 每个服务都位于它自己的进程(或者可能是 AppDomain)中,因此可以加载它喜欢的程序集版本。 在你的主程序从一个站切换到另一个站的过程中,随着API版本的变化,你会从一种服务切换到另一种服务。
这样做的另一个好处是,可以将您与创建不向后兼容前两个版本的 API 的第三版本的外部供应商隔离开来。
该解决方案的性能可能非常高,因为您的主程序可以通过命名管道甚至内存中传输与服务进行通信。 WCF 可以在传输(绑定)之间切换,在大多数情况下无需更改代码。
You say that this code is used to communicate with external stations. Why not make a service out of the code that communicates with the external stations? That service would be called from your current program.
This would allow you to have two versions of the service running - one for the old API and one for the new. Each service would be in it's own process (or maybe AppDomain), so could load the versions of the assemblies that it likes. In the process of your main program switching from one station to another, you would switch from one service to another as the API version changes.
This would have the additional benefit of isolating you from your external vendor creating a third version of the API that is not backwards compatible with the first two.
The performance of this solution could be quite high, as your main program could communicate with the services over named pipes, or even an in-memory transport. WCF can switch between transports (bindings), in most cases with no change to your code.
您可以使用 ILMerge,然后使用此技术< /a> 从同一项目引用它们。
You could sign the assemblies yourself using ILMerge and then use this technique to reference them from the same project.