在Visual Studio中,您可以创建至少3种不同类型的类库:
虽然第一个是我们多年来一直使用的,但我遇到的一个主要问题是何时使用.NET Standard和.NET Core类库类型.最近,当我尝试多目标不同的框架版本并创建一个单元测试项目时,我一直被这种做法所困扰.
那么,类库(.NET标准版)和类库(.NET Core)之间有什么区别,为什么两者都存在,什么时候应该使用另一个呢?
我已经了解了.NET Standard和.NET Core之间的区别,但我真的不知道区别是什么,或者何时选择.NET标准库项目以及何时选择.NET Core库项目.
我已经读过.NET Standard是为了确保一组API始终可用,无论使用哪个平台(只要该平台与我选择的.NET标准版本兼容).如果我没有弄错的话,这意味着我可以创建一个.NET Standard类库,然后在任何与我选择的.NET Standard版本兼容的平台上使用它.
使用.NET Core,我已经读过它也是为了跨平台使用,所以如果我选择一个.NET Core库,我似乎也可以在许多平台上使用它,就像.NET Standard一样.
所以最后,我没有看到差异.我什么时候应该使用哪个?他们之间有什么区别?
我目前正在使用最新的Visual Studio 2017 Release Candidate来创建.Net Standard 1.6库.我正在使用xUnit对我的代码进行单元测试,并且想知道你是否仍然可以在VS2017中测试内部方法.
我记得你可以在VS2015中使用一行AssemblyInfo.cs类来使指定的项目能够看到内部方法
[assembly:InternalsVisibleTo("MyTests")]
Run Code Online (Sandbox Code Playgroud)
由于VS2017 .Net标准项目中没有AssemblyInfo.cs类,我想知道您是否还可以对内部方法进行单元测试?
我有一个从我的配置文件中读取设置的方法,如下所示:
var value = ConfigurationManager.AppSettings[key];
Run Code Online (Sandbox Code Playgroud)
只针对.NET Standard 2.0时,它编译得很好.
现在我需要多个目标,所以我用以下内容更新了我的项目文件:
<TargetFrameworks>netcoreapp2.0;net461;netstandard2.0</TargetFrameworks>
Run Code Online (Sandbox Code Playgroud)
但现在,编译失败netcoreapp2.0
,出现以下错误消息:
Error CS0103 The name 'ConfigurationManager' does not exist in the current context (netcoreapp2.0)
Run Code Online (Sandbox Code Playgroud)
另外,我创建了一个新的.NET Core 2.0控制台应用程序(这次仅针对.NET Core 2.0),但同样ConfigurationManager
在命名空间下似乎没有System.Configuration
.
我很困惑,因为它可以在.NET Standard 2.0下使用,所以我希望它可以在.NET Core 2.0中使用,因为.NET Core 2.0符合.NET Standard 2.0.
我错过了什么?
假设我有一个类库,我想以netstandard1.3为目标,但也使用BigInteger
.这是一个简单的例子 - 唯一的源文件是Adder.cs
:
using System;
using System.Numerics;
namespace Calculator
{
public class Adder
{
public static BigInteger Add(int x, int y)
=> new BigInteger(x) + new BigInteger(y);
}
}
Run Code Online (Sandbox Code Playgroud)
回到这个世界project.json
,我将netstandard1.3
在该frameworks
部分中进行定位,并且明确依赖于System.Runtime.Numerics
版本4.0.1.我创建的nuget包将列出该依赖项.
在基于csproj的dotnet工具的勇敢新世界中(我使用的是命令行工具的v1.0.1),有一个隐含的元数据包引用,用于NETStandard.Library 1.6.1
何时进行定位netstandard1.3
.这意味着我的项目文件非常小,因为它不需要显式依赖项:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
...但是生成的nuget包依赖于NETStandard.Library
,这表明为了使用我的小型库,你需要那里的一切.
事实证明我可以使用禁用该功能DisableImplicitFrameworkReferences
,然后再次手动添加依赖项:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime.Numerics" Version="4.0.1" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
现在,我的NuGet软件包确切地说明了它所依赖的内容.直观地说,这感觉就像一个"更精简"的包装.
那么我图书馆消费者的确切区别是什么?如果有人试图在UWP应用程序中使用它,第二个"修剪"形式的依赖关系是否意味着生成的应用程序会更小?
通过不清楚地记录 …
我花了几个小时的时间试图找到一种在.NETCoreApp 1.1(Visual Studio 2017)中自动增加版本的方法.
我知道AssemblyInfo.cs是在文件夹中动态创建的: obj/Debug/netcoreapp1.1/
它不接受旧的方法:
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]
如果我将项目设置为包我可以在那里设置版本,但这似乎用于构建AssemblyInfo.cs文件.
我的问题是,有没有人想出如何控制.NET Core(或.NETStandard)项目中的版本.
这可能与Passog ILogger或ILoggerFactory与AspNet Core中的构造函数有些关联?但是,这特别是关于库设计,而不是关于使用这些库的实际应用程序如何实现其日志记录.
我写一个.NET 2.0标准库将通过的NuGet安装,并允许使用图书馆的人得到一些调试信息,我根据Microsoft.Extensions.Logging.Abstractions允许标准化的记录器被注入.
但是,我看到了多个接口,Web上的示例代码有时会使用ILoggerFactory
并在类的ctor中创建一个记录器.还有ILoggerProvider
看起来像Factory的只读版本,但实现可能会也可能不会实现两个接口,所以我必须选择.(工厂似乎比提供商更常见).
我见过的一些代码使用了非泛型ILogger
接口,甚至可能共享同一个记录器的一个实例,有些代码接受ILogger<T>
他们的ctor并期望DI容器支持开放泛型类型或显式注册ILogger<T>
我的库中的每个变体使用.
现在,我确实认为这ILogger<T>
是正确的方法,也许是一个不接受该论证而只是通过Null Logger的ctor.这样,如果不需要记录,则不使用任何记录.然而,一些DI容器选择了最大的ctor,因此无论如何都会失败.
我很好奇我应该在这里做什么来为用户创造最少的头痛,同时如果需要仍然允许适当的日志记录支持.
在Visual Studio 2019 Advanced Build设置中,C#8似乎不适用于.NET Framework项目,而仅适用于.NET Core 3.0项目(如下图所示):
C#8是否支持.NET Framework?
有没有办法轻松地将面向.NET Core 2.0的类库转换为.NET Standard?
如果我理解正确的话,如果想要在针对不同.NET框架的项目中最大化类库的可重用性,例如.NET Framework,.NET Core,Xamarin等,那么以.NET Standard为目标是更好的选择 - 前提是所有必需的API都可以在.NET Standard的版本中使用.
这就是我想将我的类库从.NET Core 2.0转换为.NET Standard 1.6或.NET Standard 2.0的原因.
我一直在讨论.NET Standard项目和NuGet.我有一个工作项目并已将其上传到NuGet.org.我的项目面向.NET Standard 1.3,它应该支持 .NET Framework 4.6和.NET Core 1.0.
但是当我尝试将我的项目(通过NuGet)添加到一个新的.NET Framework 4.6项目时,依赖关系解析为47个包!它们都是系统库,似乎是Microsoft.NETCore.Platforms或NETStandard.Library 1.6.1的依赖项.(完整PM输出的要点.)
我的项目只导入using
了几个库,其中没有一个是我手工添加的; 即它们都是"随.NET标准附带"的库.这些库是:
问题是,我决定让我的项目成为.NET Standard,因为我希望它能够跨.NET Framework和.NET Core应用程序无缝地工作.我认为标准的重点是设置最低级别的兼容性.通过扩展,我想我曾(或许是错误地)假设像System.Console这样的库可以在Core或Framework中自动使用.
当我在同一个解决方案中测试我的Standard项目作为Framework和Core项目中的依赖项时,我没有注意到这样的事情,所以我怀疑这可能是一个NuGet的事情.
这里到底发生了什么?如何在没有大量依赖项的情况下在NuGet上提供我的.NET标准库?
这是我指定我的NuGet包的方式有问题吗?或者我从根本上误解了什么?
.net-standard ×10
.net-core ×7
.net ×5
c# ×5
nuget ×2
app-config ×1
c#-8.0 ×1
logging ×1
unit-testing ×1