Ath*_*ari 8 .net c# msbuild nuget
我希望我的库能够使用各种版本的NuGet包,并在更改之间对API进行重大更改.我没有进一步调查,但这条路看起来很有希望:
虽然这可能看起来很复杂,但它比在单独的程序集中支持每个版本的更直接的方法有许多好处:
但是,目前还不清楚它是否可能.甚至在获得代理和检测当前版本之前,我就坚持了基础知识.
我甚PackageReference至无法向我的.csproj 添加多个节点,只有一个参考实际上有效.有一个解决方法来添加 NuGet不直接支持的外部别名,但我无法达到这一点,因为我无法获得两个引用.如果我以某种方式得到两个,我将无法区分它们.
我正在使用CsConsoleFormat库来格式化控制台输出.我希望直接支持流行的命令行软件包的所有相关版本,这样无论使用什么命令行解析库,都可以添加几乎没有编码的漂亮命令行帮助和类似的东西.
我想在我的案例中声称"我只支持最新版本"在某种程度上是可以接受的,但即使它更复杂,我也宁愿得到更广泛的支持.理想情况下,我想要一个NuGet包,它声明对最低支持版本的依赖,但支持最新版本的所有内容.
我有点工作,但有很多问题.有关详细信息,请参阅GitHub NuGet Home上的问题.
如果您坚持使用外部别名-您可以直接将多个版本引用添加为dll文件,而不是nuget包。
假设我想依赖于Newtonsoft.Json软件包10.0.3+版本。但是,如果用户安装了版本11-我想使用JsonConverter<T>仅在该版本(11)中可用的通用类。然后我的csproj可能看起来像这样:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.0.4</Version>
</PropertyGroup>
<ItemGroup>
<!-- Nuget reference -->
<!-- Only this one will be included as dependency to the packed nuget -->
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
<ItemGroup>
<!-- Direct reference to the specific version -->
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
<!-- Path to v11 dll -->
<HintPath>Newtonsoft.Json.v11.dll</HintPath>
<Aliases>js11</Aliases>
<SpecificVersion>true</SpecificVersion>
</Reference>
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
然后我有代理接口:
public interface ISerializer {
string Serialize<T>(T obj);
}
Run Code Online (Sandbox Code Playgroud)
还有两个实现,v10(使用全局非别名名称空间):
using System;
using global::Newtonsoft.Json;
namespace NugetRefMain {
internal class Js10Serializer : ISerializer
{
public string Serialize<T>(T obj)
{
Console.WriteLine(typeof(JsonConvert));
return JsonConvert.SerializeObject(obj);
}
}
}
Run Code Online (Sandbox Code Playgroud)
和v11
extern alias js11;
using System;
using js11::Newtonsoft.Json;
namespace NugetRefMain {
internal class Js11Serializer : ISerializer {
public string Serialize<T>(T obj) {
// using JsonConverter<T>, only available in v11
Console.WriteLine(typeof(JsonConverter<T>));
return JsonConvert.SerializeObject(obj);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后是工厂,它根据当前可用的json.net版本创建序列化程序:
public static class Serializers {
public static ISerializer Create() {
var version = typeof(JsonConvert).Assembly.GetName().Version;
if (version.Major == 10)
return new Js10Serializer();
return new Js11Serializer();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我将其打包为nuget,它将对Newtonsoft.Json版本具有单一依赖性,仅此而已10.0.3。但是,如果用户安装Newtonsoft.Json版本11,它将使用该版本中可用的功能。
缺点:
Visual Studio \ Resharper intellisense有时不喜欢这种方法,并且在实际一切都可以编译的情况下显示intellisense错误。
您可能在编译时有“版本冲突”警告。
NuGet 仅解析单个包版本。
如果您声明对最低支持版本的依赖项,则任何引用项目都可以将该依赖项升级到较新的版本。
只要依赖包的作者不引入重大更改,find 就应该可以工作。
即使您使用反射来查看实际使用的程序集版本,您也会发现许多包作者不会在发布之间更改程序集版本。这是为了避免在经典 .NET Framework 项目中绑定重定向的需要,因为所有版本都相同,并且 NuGet 将根据使用项目的已解析包版本选择正确的 DLL。同样,只要没有重大变化,这就是好事。
您可以用来支持不同软件包的一种模式是提供许多“平台”软件包供消费者选择。然后,特定于平台的包将引用具有可共享逻辑的公共包。
那么“平台”将是例如引用“MyLogic.Common”的“MyLogic.XUnit”或“MyLogic.NUnit”(假设测试助手作为示例)