NET Standard/Core中配置使用TargetFrameworks输出多版本类库及测试

来源:互联网 发布:反向传播算法 电路图 编辑:程序博客网 时间:2024/06/07 11:44

在core之前,要使一个项目支持多个Frame版本,那么可行的办法就是创建多个版本的项目,然后以一个项目为主体,其它版本以添加--现有项--添加为链接的方式将代码文件添加到对应版本中,如果代码不同,则需要使用#if标签,而在core之后,如果需要发布多版本,可以不再需要创建多个项目,这里以VS2017为例

首先我们创建一个项目,可以是Standard类库,也可以是Core应用,这里我选择创建一个Standard类库,新建后的项目大致如下


在VS的解决方案管理器中选择项目,然后右键,点击 编辑StandardMultiTargetsDemo.csproj


这时可以打开csproj的编辑界面,默认信息如下

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <TargetFramework>netstandard2.0</TargetFramework>  </PropertyGroup></Project>

可以看到当前类库默认为netstandard2.0,而此时其xml标签为TargetFramework,比我们标题中的单词少了个s,表示当前项目只支持netstandard2.0,而我们现在稍作调整,将csproj文件的配置信息改为如下,表示支持netstandard2.0以及net40,注意现在是TargetFrameworks

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <TargetFrameworks>netstandard2.0;net40</TargetFrameworks>  </PropertyGroup></Project>
改完后,切记点击保存按钮,这时会跳出一个确定对话框


点击“全部重载”,VS会自动关闭csproj编辑界面,然后手快眼快的话,可以看到项目依赖项那里会有感叹号,再稍等一个会,感叹号会消失,这时在“解决方案管理器”中点开依赖项,可以看到当前项目以及支持多版本


此时生成项目,我们就可以在对应目录下看到有多个版本输出


好了目前我们已经可以多版本输出,但实际情况下,我们还需要解决以下问题

1、条件编译符

2、引用

3、Nuget

4、XML文档输出

5、DEBUG

这时我们再打开csproj编辑界面,添加如下语句

  <PropertyGroup Condition=" '$(TargetFramework)' == 'net40' ">    <DefineConstants>NETFULL</DefineConstants>  </PropertyGroup>
这表示在net40中,我定义了一个自定的条件编译符NETFULL,当然默认的条件编译符NET40还是有效的,如果你还需要定义其它条件编译符,切记多个条件编译符需以冒号(;)分割

下面我们开始添加引用,点击项目,然后添加引用,这时如果你完全按照前面的步骤,那么会打开如下界面


这是netstandard2.0时的引用界面,当然这时你点击项目属性时,打开的也都是netstandard2.0相关的配置信息,那要如何才能添加net40的引用呢?据说有个版本切换的选项,但我没找到,所以我采用下面的笨方式

回到csproj编辑界面,我们将TargetFrameworks里的版本先后顺序调整下,调整后的配置如下(记得保存)

  <PropertyGroup>    <TargetFrameworks>net40;netstandard2.0;</TargetFrameworks>  </PropertyGroup>
这时我们再打开添加引用的界面

此时新打开的界面就是net4.0的引用界面,这里我们选择System.Net这个dll,点击“确定”后,此时注意依赖项部分,可以看到出现了一个感叹号,展开会看到在netstandard2.0上出现了感叹号,表示netstandard2.0并不知道System.Net是什么东东,这时我们继续回到csproj界面,这时我们会看到配置文件里多了如下配置

  <ItemGroup>    <Reference Include="System.Net" />  </ItemGroup>
这样表示net40和netstand2.0都需要System.Net引用,而实际只有net40才需要该引用,所以这里我们要使用Condition
  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">    <Reference Include="System.Net" />  </ItemGroup>
这表示只有net40才符合条件,保存后你会发现依赖项那边的感叹号消失了

好了上面是添加程序集引用,本地引用的方式与程序集方式类同,这里就不再描述,下面是通过nuget添加引用

首先我们先下载一个多版本都支持的类库,NLog(好吧,我终于发现NLog最新对netstandard2.0支持的dll已经是RC3版本了),在地址栏中打开https://www.nuget.org/packages/NLog/4.5.0-rc03#,选择你喜欢的方式进行引用的添加,这里我选择PM方式,添加完后csproj会多出如下配置

  <ItemGroup>    <PackageReference Include="NLog" Version="4.5.0-rc03" />  </ItemGroup>
注意这里是PackageReference,而之前程序集的是Reference,而且我们也会发现在VS解决方案管理器中并没有出现packages.config文件,好吧,这是core开始nuget的新的管理方式,不再像以前默认在sln文件的同级创建一个packages文件夹,而是将dll下载到了C:\Users\当前登录用户\.nuget目录下,与java的Maven类似


注意图中.m2即为maven的默认配置下载位置

好了下面我们再添加一个netstandard专有的nuget引用https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection/,添加完后csproj会多出如下配置

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">    <PackageReference Include="Microsoft.Extensions.DependencyInjection">      <Version>2.0.0</Version>    </PackageReference>  </ItemGroup>

好吧nuget很智能,自动帮你把Condition给加好了,而默认加的配置其实可以调整下,Version可以是Attribute方式添加,这在我们手动修改配置时会方便很多

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />  </ItemGroup>


下面我们开始设置XML文件输出,选择项目,点击 属性--生成,勾选 “XML 文档文件”


保存后csproj会自动多出如下配置

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">    <DocumentationFile>bin\Debug\netstandard2.0\StandardMultiTargetsDemo.xml</DocumentationFile>  </PropertyGroup>
这表示netstandard2.0会生成xml文件,将该配置信息复制一份,然后修改Platform以及输出路径为net40
  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net40|AnyCPU'">    <DocumentationFile>bin\Debug\net40\StandardMultiTargetsDemo.xml</DocumentationFile>  </PropertyGroup>
这样net40也可以生成xml文件,当然这里可能也有其它更方便的设置方式,但目前我还不知道……

好了,最后是我们的重头戏,DEBUG,毕竟任何编码都离不开DEBUG,我们先在Class1(希望你还没删掉它……)文件中添加如下语句

#if NETFULL        int number;#else        string number;#endif
因为我们目前默认是netstandard2.0,所以你会在编辑界面看到如下效果


好吧,另几个参数是在添加引用时做测试的,上面忘记说了,反正也不是什么大事,不是么……

那如何测试net40呢,其实跟前面添加程序集引用时的步骤一样,将net40写到最前面即可,但VS中有个不靠谱的地方(不知道是不是bug),那就是虽然你目前是net40,但在VS编辑界面中,你看到的还是上图那样,NETFULL这个net40标签内的代码还是灰色的,而且你任何操作也不会有智能感知,这明显是很糟的用户体验,所以在这里告诉大家最后一个大招,再设置TargetFramework,注意没s后缀!!!修改后的配置如下

  <PropertyGroup>    <!--<TargetFrameworks>net40;netstandard2.0;net46;</TargetFrameworks>-->    <TargetFramework>net40</TargetFramework>  </PropertyGroup>
保存并重新加载后,再打开Class1,这是你会看到下图效果


好了,从如何配置到最后的如何DEBUG这里都已经讲完了,剩下的就是各位实际操作一次实验下了。

最后完整的配置文件如下

<Project Sdk="Microsoft.NET.Sdk">  <PropertyGroup>    <!--<TargetFrameworks>net40;netstandard2.0;net46;</TargetFrameworks>-->    <TargetFramework>net40</TargetFramework>  </PropertyGroup>  <PropertyGroup Condition=" '$(TargetFramework)' == 'net40' OR '$(TargetFramework)' == 'net46'">    <DefineConstants>NETFULL;NET</DefineConstants>  </PropertyGroup>  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">    <DocumentationFile>bin\Debug\netstandard2.0\StandardMultiTargetsDemo.xml</DocumentationFile>  </PropertyGroup>  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net40|AnyCPU'">    <DocumentationFile>bin\Debug\net40\StandardMultiTargetsDemo.xml</DocumentationFile>  </PropertyGroup>  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">    <Reference Include="System.Net" />  </ItemGroup>  <ItemGroup>    <PackageReference Include="NLog" Version="4.5.0-rc03" />  </ItemGroup>  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />  </ItemGroup></Project>

好吧,这里还隐藏了最后一样东西,各位自己注意吧,不过找出了可没奖品 :P
阅读全文
0 0