一个很奇怪的命名空间问题,请大神解题!

圣殿骑士18 2016-06-23 10:46:52
昨天晚上在编译初步开发好的程序时,发现一个复杂的机制造成的问题,最终问题确定的原因,
就是和await async的支持库有关,但其本质原因是什么?就是想不明白,想请高手们解解题。

首先因为我的应用服务端使用了WebApi2.0,客户端使用WinForm进行http访问,为了达到较好的用户体验,客户端采用了await async异步。
同时为了支持Winxp,类库只能使用到Net4.0,而Net4.0不支持await async异步。

解决这个问题,通过的是微软开发的附加支持包,我使用Nuget安装的。首先我只将支持包安装到主应用程序项目(A项目)下。
安装的支持包通过控制台安装:
Install-Package Microsoft.Bcl.Async
Install-Package Microsoft.Net.Http

上述都是前提。

下面问题来了,现在我的另外一个周边项目(B项目)也需要用到await async,这次我没有用Nuget来安装,我尝试自己将A项目下的dll引用,
一模一样的引用配置到B项目上。
请相信我是正确的全部的引用了所有的dll,也就是上面两个包目录下的所有dll,而且我也作了对比,确认无误。唯一不同的是,我没有在
B项目下增加Nuget会自动生成的packages.config,和对App.config的修改部分(我一直认为这个东西是Nuget同步用的,并不是必要)。


我有两个基础型项目C项目和D项目,他们的命名空间具有父子级别关系,
C项目:BL.Core.WF
D项目:BL.Core.WF.AccessClient
而且每个项目内,都只有一个命名空间,没有子级的命名空间,这是我的习惯。

最终出现的问题可以描述为:B项目,它引用了D项目(并没有引用C项目)。引用方式当然就是:
using BL.Core;
using BL.Core.WF.Dev;
using BL.Core.WF.AccessClient; //这里是D项目引用

然而在编译B项目时,系统会提示错误:

命名空间“BL.Core.WF”中不存在类型或命名空间名称“AccessClient”(是否缺少程序集引用?)

这错误,似乎只能理解为我B项目里,引用了C项目,而C项目的命名空间是BL.Core.WF,是D项目命名空间的前面部分,所以产生了冲突。
但这个说法我认为是不成立的:
1、首先B项目并没有引用C项目
2、即使我在B项目中,同时引用了C项目和D项目,也并不应该产生命名空间冲突,因为我using的是BL.Core.WF.AccessClient,不是BL.Core.WF

接下去我做了众多测试,我修改项目命名空间,避免层级关系,没用。我把相关项目全部修改为x86模式编译,没用。
最后,我还是在B项目上,使用Nuget来安装Microsoft.Bcl.Async和Microsoft.Net.Http,却把问题解决了!!

为什么我手工引用这两个包会出现这么奇怪的难以解释的命名空间冲突,而使用Nuget安装却没有问题?

我可以贴出我手工加入引用,和使用Nuget安装的区别,就是没有修改配置文件。两个配置文件的内容是:
packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.0.0" targetFramework="net40" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net40" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net40" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net40" />
<package id="System.Data.SQLite" version="1.0.101.0" targetFramework="net40" />
<package id="System.Data.SQLite.Core" version="1.0.101.0" targetFramework="net40" />
<package id="System.Data.SQLite.EF6" version="1.0.101.0" targetFramework="net40" />
<package id="System.Data.SQLite.Linq" version="1.0.101.0" targetFramework="net40" />
</packages>


App.config
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.29.0" newVersion="2.2.29.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>


请大神们分析!
...全文
514 点赞 收藏 6
写回复
6 条回复
正怒月神 2016年07月13日
以前也遇到过这个问题。 后来还是用nuget安装的。 我一直认为就是config的问题。
回复 点赞
Poopaye 2016年07月13日
你说了这么多,和命名空间一点关系都没有 重点就这句: 命名空间“BL.Core.WF”中不存在类型或命名空间名称“AccessClient”(是否缺少程序集引用?) 换句话,意思就是D项目没能(正确的)加载,可能是 .net版本不兼容 D项目本身有问题 D项目的依赖项目没能加载 。。。
回复 点赞
bidisty 2016年07月13日
不能引用“AccessClient”,应该是D项目和B项目的.net版本不是一样的。 <dependentAssembly> <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.2.29.0" newVersion="2.2.29.0" /> </dependentAssembly> 用配置中的重定向来兼容 <bindingRedirect oldVersion="0.0.0.0-2.2.29.0" newVersion="2.2.29.0" />
回复 点赞
圣殿骑士18 2016年06月23日
sp1234大神来踩踩
回复 点赞
圣殿骑士18 2016年06月23日
大神也不明觉厉吗
回复 点赞
娃都会打酱油了 2016年06月23日
不明觉厉……好吧……
回复 点赞
发动态
发帖子
.NET Framework
创建于2007-09-28

1.6w+

社区成员

2.4w+

社区内容

.NET技术 .NET Framework
社区公告
暂无公告