Je souhaite que ma bibliothèque fonctionne avec une gamme de versions d'un package NuGet avec des modifications radicales de l'API entre les modifications. Je n'ai pas étudié plus avant, mais ce chemin semble prometteur:
Bien que cela puisse paraître compliqué, cela présente de nombreux avantages par rapport à une approche plus simple consistant à prendre en charge chaque version dans une assemblée distincte:
Cependant, il n'est pas clair si c'est possible du tout. Même avant de passer aux mandataires et de détecter la version actuelle, je suis coincé avec les bases.
Je ne peux même pas ajouter plusieurs nœuds PackageReference
à mon .csproj, une seule référence fonctionne réellement. Il existe un solution de contournement pour l'ajout d'alias externes } qui ne sont pas directement pris en charge par NuGet, mais je ne peux pas en arriver là, car je ne peux pas obtenir deux références. Et si j'en ai deux, je ne pourrai pas les distinguer.
Je travaille sur la bibliothèque CsConsoleFormat pour formater la sortie de la console. Je souhaite prendre en charge directement toutes les versions pertinentes des packages de ligne de commande les plus utilisés, afin de pouvoir ajouter de jolies aides de ligne de commande et ce genre de choses, pratiquement sans codage, quelle que soit la bibliothèque utilisée pour l'analyse de ligne de commande.
J'imagine que déclarer "je ne supporte que la dernière version" est un peu acceptable dans mon cas, mais je préférerais un support plus large même si c'est plus compliqué. Idéalement, je veux un paquet NuGet qui déclare sa dépendance à la version la plus basse supportée, mais supporte tout jusqu'à la dernière version .
Je l'ai un peu fait fonctionner, mais avec de nombreux problèmes. Voir numéro sur GitHub NuGet Home } pour plus de détails.
Si vous insistez sur les alias externes - vous pouvez ajouter plusieurs références de version directement, sous forme de fichier dll, et non sous forme de package Nuget.
Supposons que je veuille créer une dépendance vis-à-vis du paquet Newtonsoft.Json version 10.0.3 +. Toutefois, si l’utilisateur dispose de la version 11, je souhaite utiliser la classe générique JsonConverter<T>
disponible uniquement dans cette version (11). Ensuite, mon csproj pourrait ressembler à ceci:
<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>
Ensuite, j'ai une interface proxy:
public interface ISerializer {
string Serialize<T>(T obj);
}
Et deux implémentations, v10 (utilise un espace de noms global sans alias):
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);
}
}
}
Et 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);
}
}
}
Et enfin l’usine qui crée un sérialiseur en fonction de la version actuelle de 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();
}
}
Maintenant, si je mets ceci comme nuget - il aura une dépendance unique sur Newtonsoft.Json
version 10.0.3
et c'est tout. Toutefois, si l'utilisateur installe Newtonsoft.Json
de la version 11, il utilisera les fonctionnalités disponibles dans cette version.
Désavantages:
Visual Studio\Resharper intellisense n'aime pas cette approche parfois et montre des erreurs intellisense alors qu'en réalité, tout compile parfaitement.
Vous pourriez avoir des avertissements de "conflit de version" lors de la compilation.
NuGet ne résout que les versions à un seul paquet.
Si vous déclarez une dépendance à la version minimale prise en charge, tout projet de référencement peut mettre à niveau la dépendance vers une version plus récente.
Tant que les auteurs du paquet dépendant n'introduisent pas de changements radicaux, cela devrait fonctionner.
Même si vous utilisez la réflexion pour examiner les versions actuelles de Assembly utilisées, vous constaterez que de nombreux auteurs de packages ne modifient pas la version de Assembly entre les versions. Cela évite d'avoir à rediriger les liens dans les projets .NET Framework classiques, car toutes les versions sont identiques et NuGet sélectionne le bon DLL en fonction de la version du package utilisé qui a été résolue. Encore une fois, c'est bon tant qu'il n'y a pas de changements radicaux.
Un modèle que vous pouvez utiliser pour prendre en charge différents packages consiste à fournir de nombreux packages "plate-forme" parmi lesquels le consommateur peut choisir. Le paquet spécifique à la plate-forme ferait alors référence à un paquet commun avec une logique partageable.
La "plateforme" serait alors par exemple "MyLogic.XUnit" ou "MyLogic.NUnit" (en supposant que les aides de test soient un exemple) faisant référence à "MyLogic.Common"
Ce n'est pas une réponse complète, mais j'ai remarqué sur votre page de problème GitHub que vous faites référence à la fois aux bibliothèques .NET Standard et .NET Framework de votre projet. Ceci est connu pour ne pas fonctionner correctement.
Citation de annonce de l'équipe .NET Standard ,
.. Un autre symptôme est les avertissements au moment de la construction concernant les versions d'Assembly ..
qui peut être ce que vous rencontrez.