我正在为log4net做一个appender,我遇到了如何管理我的类库构建的log4net版本的依赖关系与网站上部署的实际版本的问题。我的类库必须引用log4net dll,因此它与我在构建时引用的版本绑定。但是,将部署此组件的站点将具有各种log4net版本,一些比我的旧,一些将更新。我该如何处理这个问题?我不想为每个log4net新版本发布我的appender的新版本,并且要在我的用户上正确匹配它们。我也不想让我的appender用户做复杂的并排清单技巧。我只是想将我的appender简单地复制到最终用户位置,并开始使用任何log4net版本。
这可以实现吗?我错过了一些明显的东西吗?
更新:
唯一可行的解决方案是使用清单。我使用两个“自制”log4net版本进行测试,并添加以下配置部分解决了我的问题:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net"
publicKeyToken="..."
culture="neutral" />
<bindingRedirect oldVersion="1.2.10.0"
newVersion="..."/>
</dependentAssembly>
</assemblyBinding>
</runtime>
其中publicKeyToken是真正的log4net程序集的实际密钥令牌,1.2.10是我的appender构建版本,newVersion是现场部署的版本。该部分可以添加到已部署的appconfig或webconfig中(也可以在机器配置中完成,但我不建议使用...)。
答案 0 :(得分:2)
许多项目都有与您刚才描述的问题相同的问题。据我所知,这不是你作为出版商可以控制的东西。您可以设置publisher policy,允许您自动指定在引用旧版本的程序集时应使用某个版本的程序集,但是无法为不能控制的程序集指定此版本(像log4net)。
在您的用户方面,管理员可以通过assembly redirect指定对较旧版本的log4net(您的程序集可能引用的)的请求重定向到特定版本。
答案 1 :(得分:2)
您可以处理AssemblyResolve事件:
AppDomain current = AppDomain.CurrentDomain;
current.AssemblyResolve += current_AssemblyResolve;
然后,您可以在Name属性(来自ResolveEventArgs)上使用字符串操作来删除版本号并加载程序集而不指定其版本。
答案 2 :(得分:0)
编辑:以下建议不起作用:在编译时应用特定版本,而不是执行时间
在Visual Studio中选择对Log4Net的引用(假设您使用的是Visual Studio!)并显示属性。将“特定版本”设置为“假”,我认为你应该没问题。你有没有尝试过并遇到过问题?
答案 3 :(得分:0)
根据您使用的接口,您可以使用实际为您实例化所需类的IoC容器(例如Castle,Spring.net等),如配置文件(或代码段) 这样,您只使用接口,并且具体类的实际绑定由容器(框架)完成。如果您使用dependency injection(参见Fowler's article有关它),这是(特别)可实现的。 只要您使用的接口保持不变,就会对代码进行“后期绑定”。
答案 4 :(得分:0)
简单而愚蠢的解决方案是使用在vb.net上编写的代理库。
在尝试为MS OFFICE构建工具时,我遇到了类似的问题。
使用VB,我并不担心安装了什么版本的办公室。
答案 5 :(得分:0)
我倾向于强烈不喜欢依赖于“基础架构”库的库,例如单元测试框架,日志框架和代码生成工具,当它们的主要目的没有明确要求时。
如果您依赖于可以安装在GAC中的库,那么您可以依赖它并立即激活库的多个版本,但无论如何这可能不适合使用log4net(给定共享配置)常用的状态模型)并且使用你的库增加了很大的复杂性。
可以指出,许多图书馆不应该输出任何类型的日志,因为他们无法很好地预测用户的需求。 log4net的运行时可配置性确实在某种程度上缓解了这种情况。如果转移到使用框架内置的跟踪API,您的代码会更好吗?结果代码在依赖性方面变得更加轻量级,并且仍然允许在编译后进行一些复杂的调优。
答案 6 :(得分:0)
我的另一个答案的替代方案。 Hacky,可能会有并发症但是:
将log4net代码构建到您的dll中 由于它是开源的,并且在reasonably permissive licence下,您可以编辑文件(注意到您所做的)以更改可见性(以及可选的名称空间),以便它可用于您的代码并且不会干扰消费者。 / p>
您可能希望添加一些代码以尝试从与应用程序其余部分相同的位置配置库,或者(更容易处理)允许从完全独立的文件/配置部分配置库日志。
答案 7 :(得分:0)
对于CAD / CAM应用程序,我不得不面对这个问题,我们必须支持第三方机器的一些支持库。我做了什么我创建了两个程序集,一个链接到一个版本,另一个链接到另一个版本。我把它们放在同一个界面后面。
然后在我们的设置对话框中,您可以指定要使用的版本。当然,如果使用的版本不正确,则会发生错误。
诀窍是创建界面,以便两个程序集都可以无缝地工作。可能无法包装像Microsoft Office这样的复杂API。在这种情况下,您需要回溯使用API并查看最少使用的调用次数,并在此时构建您的界面。
在我的情况下,当我不得不将一张材料倾倒到机器上时。所以我创建了一个接口,它有一个例程,用于该机器的设置对话框和一个带有我的工作表对象的例程。一切都在那个班级里。
在你的情况下,你需要查看你在Log4net中使用的内容,看看你是否可以构建一个接口。
这样做的一个优点是您不再需要焊接到Log4Net。正确设计界面然后您可以重新实现使用不同的包。此外,创建界面将精确定义应用程序与Log4net的交互方式。最后,如果Log4Net实现了突破性更改,那么您将有一条路径来处理它。
答案 8 :(得分:0)