C# 托管类库中与版本无关的引用依赖项

C# 托管类库中与版本无关的引用依赖项,c#,reflection,reference,log4net,C#,Reflection,Reference,Log4net,我正在为log4net开发一个appender,我面临着如何管理对log4net版本的依赖性的问题。我的类库是根据log4net版本构建的,而不是站点上部署的实际版本。我的类库必须引用log4net DLL,因此它与我在构建时引用的版本相关联。但是,该组件将部署的站点将有各种log4net版本,有些比我的版本旧,有些则更新。我应该如何处理这个问题?我不想为每个log4net新版本发布appender的新版本,并将正确匹配它们的负担放在我的用户身上。我也不想让appender用户执行复杂的并行清单

我正在为log4net开发一个appender,我面临着如何管理对log4net版本的依赖性的问题。我的类库是根据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构建时使用的版本,新版本是现场当前部署的版本。该部分可以添加到已部署的appconfig或webconfig中(也可以在机器配置中完成,但我不建议…。

很多项目都有您刚才描述的问题。据我所知,这不是你作为出版商所能控制的。您可以设置一个允许您在引用较旧版本的程序集时自动指定应使用程序集的某个版本,但无法为您不控制的程序集(如log4net)指定该版本


在您的用户端,管理员可以通过以下方法指定对旧版本log4net(您的程序集可能会引用)的请求:通过重新定向到特定版本。

编辑:以下建议无效:特定版本在编译时应用,而不是在执行时应用

在VisualStudio中选择对Log4Net的引用(假设您使用的是VisualStudio!),并显示属性。将“特定版本”设置为“false”,我认为您应该没事。您是否已经尝试过这个方法并遇到了问题?

您可以使用一个容器(例如,等等),根据您使用的接口,按照配置文件(或代码段)中的定义,为您实际实例化所需的类。
这样,您只能使用接口,而与具体类的实际绑定是由容器(框架)完成的。如果您与合作,这(尤其)是可以实现的(另请参见相关内容)。

只要使用的接口保持不变,代码就会“延迟绑定”。

您可以处理AssemblyResolve事件:

AppDomain current = AppDomain.CurrentDomain;
current.AssemblyResolve += current_AssemblyResolve;

然后,您可以对Name属性(从ResolveEventArgs)使用字符串操作来删除版本号并加载程序集,而无需指定其版本。

简单而愚蠢的解决方案是使用vb.net上编写的代理库

我在尝试为MS OFFICE构建工具时遇到了类似的问题


对于VB,我并不担心安装了什么版本的office。

我倾向于非常不喜欢依赖于“基础设施”库的库,如单元测试框架、日志框架和代码生成工具,而它们的主要用途并不明确要求它

若您要依赖一个可以安装在GAC中的库,那个么您可以依赖它,同时激活多个版本的库,但这可能不会很好地使用log4net(考虑到常用的共享配置状态模型),并且会增加使用库的复杂性


可以指出,许多库不应该输出任何类型的日志,因为它们无法充分预测用户的需求。不过,log4net的运行时可配置性在一定程度上缓解了这一问题。如果您的代码转而使用框架中内置的跟踪api,您的代码会更好吗?由此产生的代码在依赖性方面变得更加轻量级,并且仍然允许在编译后进行一些复杂的调优。

我的另一个答案的替代方案。哈奇,可能会有并发症,但:

将log4net代码构建到dll中。
因为它是开源的,并且是在一个框架下,所以您可以编辑文件(注意您已经编辑了)来改变可见性(以及可选的名称空间),这样它就可以用于您的代码,并且不会干扰使用者


您可能希望添加一些代码,尝试从与应用程序其余部分相同的位置配置库,或者(而且更易于处理)允许从完全独立的文件/配置部分配置您的库日志。

对于CAD/CAM应用程序,我不得不面对这个问题,我们必须支持第三方机器的一些支持库。我创建了两个程序集,一个链接到一个版本,另一个链接到另一个版本。我把它们放在同一个界面后面

然后在我们的设置对话框中,您可以指定要使用的版本。当然,如果使用的版本不正确,则会发生错误

诀窍是创建接口,以便两个程序集可以无缝地工作。可能无法像Microsoft Office那样包装复杂的API。在这种情况下,您需要回溯您对API的使用,并查看在哪里使用了最小数量的调用,并在该点上构建您的接口

在我的例子中,关键是我必须把一片材料倒进机器里。所以我创建了一个接口