[英]Supporting multiple versions of NuGet package in one library / NuGet package
我希望我的庫能夠使用一系列版本的 NuGet 包,並在這些更改之間對 API 進行重大更改。 我沒有進一步調查,但這條路看起來很有希望:
雖然這看起來很復雜,但與在單獨的程序集中支持每個版本的更直接的方法相比,它有很多好處:
但是,目前尚不清楚這是否可能。 甚至在使用代理和檢測當前版本之前,我都堅持使用基礎知識。
我什至無法將多個PackageReference
節點添加到 my.csproj,實際上只有一個引用有效。 有一種解決方法可以添加 NuGet 不直接支持的外部別名,但我無法做到這一點,因為我無法獲得兩個引用。 如果我以某種方式得到兩個,我將無法區分它們。
我正在使用 CsConsoleFormat 庫來格式化控制台輸出。 我想直接支持流行的命令行包的所有相關版本,這樣漂亮的命令行幫助和類似的東西幾乎不需要編碼就可以添加,不管使用什么命令行解析庫。
我想聲明“我只支持最新版本”在我的情況下是可以接受的,但我寧願得到更廣泛的支持,即使它更復雜。 理想情況下,我想要一個 NuGet 包,它聲明對最低支持版本的依賴,但支持最新版本的所有內容。
我有點讓它工作,但有很多問題。 有關詳細信息,請參閱GitHub NuGet 主頁上的問題。
如果您堅持使用外部別名 - 您可以直接添加多個版本引用,作為 dll 文件,而不是作為 nuget 包。
假設我想依賴 Newtonsoft.Json 包版本 10.0.3+。 但是,如果用戶安裝了版本 11 - 我想使用僅在此版本 (11) 中可用的通用JsonConverter<T>
類。 然后我的 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>
然后我有代理接口:
public interface ISerializer {
string Serialize<T>(T obj);
}
還有兩個實現,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);
}
}
}
和 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);
}
}
}
最后是根據當前可用的 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();
}
}
現在,如果我將其打包為 nuget - 它將對Newtonsoft.Json
版本10.0.3
具有單一依賴性,僅此而已。 但是,如果用戶安裝版本 11 的Newtonsoft.Json
- 它將使用此版本中可用的功能。
缺點:
Visual Studio \ Resharper intellisense 有時不喜歡這種方法,並且在實際上一切都編譯得很好時顯示 intellisense 錯誤。
您可能會在編譯時收到“版本沖突”警告。
NuGet 僅解析單個包版本。
如果你聲明對最低支持版本的依賴,任何引用項目都可以將依賴升級到更新的版本。
只要依賴包的作者不引入重大更改,它就應該可以找到。
即使您使用反射查看實際使用的程序集版本,您也會發現許多包作者不會在發布之間更改程序集版本。 這是為了避免在經典 .NET Framework 項目中綁定重定向的需要,因為所有版本都相同,並且 NuGet 將根據使用項目的已解析包版本選擇正確的 DLL。 同樣,只要沒有重大變化,這就很好。
您可以用來支持不同包的模式是提供許多消費者可以從中選擇的“平台”包。 然后,特定於平台的包將引用具有可共享邏輯的通用包。
“平台”將是例如“MyLogic.XUnit”或“MyLogic.NUnit”(假設以測試助手為例)引用“MyLogic.Common”
這不是一個完整的答案,但我在您的GitHub 問題頁面上注意到您在項目中引用了 .NET Standard 和 .NET Framework 庫。 已知這無法正常工作。
引用 .NET Standard 團隊的公告,
.. 另一個症狀是在構建時關於程序集版本的警告..
這可能是你遇到的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.