我遇到了NuGet预发行套餐的问题,并想知道其他人在这种情况下做了什么。 NuGet功能似乎与Maven中的预期行为完全不同,坦率地说,很奇怪。举一个简单的例子,假设我们有FooAssembly和BarAssembly组件,其类定义如下:
富:
namespace Foo {
class FooClass {
public void TestA(){
}
}
}
栏:
namespace Bar {
class BarClass {
public static void Main(string[] args){
FooClass foo = new FooClass();
foo.TestA();
}
}
}
当我构建Foo时,它的版本化使得它生成Foo-1.0.0-SNAPSHOT.nupkg。当我将它添加为依赖项时,NuGet会将其安装到Bar中,将其放在%APPDATA%下的本地缓存和源代码树中的packages文件夹中。现在,如果我将方法TestB()添加到Foo并重建,它还会生成Foo-1.0.0-SNAPSHOT.nupkg。我的构建将这个新的nupkg文件按预期放入我的%APPDATA%缓存中。但是,当我尝试重建Bar时,NuGet没有检测到我的%APPDATA%中的nupkg已经更改,因此没有新的TestB方法可用。我必须手动删除src / packages文件夹(或至少包中的Foo子目录),以便从我的缓存中重新获取包。
在Maven中,如果我在添加TestB方法的情况下重建Foo,它会在我的.m2缓存中放置Foo-1.0.0-SNAPSHOT,而Bar会链接到新版本的jar并且会知道TestB
我的问题是,首先,我是否遗漏了NuGet的内容?其次,如果我不是,那么人们为解决这个缺点做了什么?添加MSBuild预构建步骤以清除项目包缓存?将构建号附加到SNAPSHOT的末尾(例如SNAPSHOT42 ......这似乎对项目中的多个开发人员来说会有问题)?
任何见解都表示赞赏。感谢。
答案 0 :(得分:2)
截至2018年,此答案已过期 - 请参阅我的other answer了解最新信息。
NuGet并不真正支持像Maven那样的SNAPSHOT依赖关系,尽管有open issue来实现类似的东西,discussion关于这样的功能。
建议的可能性是写一个脚本:
或者当我处理自己的项目时,我总是从源代码构建和引用Foo
。然后,一旦Foo
项目变得足够稳定以至于我不再更新它,我就开始停止通过源引用Foo
,而是构建它并作为nuget包引用。
答案 1 :(得分:0)
如果您在新的csproj文件格式中使用public class Item
{
public int Id { get; }
public int Size { get; }
public Item(int id, int size)
{
Id = id;
size = size;
}
}
public class Partition
{
public int Index { get; }
public ImmutableList<Item> Items { get; } = ImmutableList<Item>.Empty;
public int Sum { get; }
public Partition(int index)
{
Index = index;
}
private Partition(int index, ImmutableList<Item> items, int sum)
{
Index = index;
Item = items;
Sum = sum;
}
public Partition Add(Item item) => new Partition(Index, Items.Add(item), Sum + item.Size);
public static double AverageDifference(ImmutableList<Partition> partitions)
{
var differences = new List<int>();
for (var i = 0; i < partitions.Count; i++)
{
var partition = partitions[i];
var otherPartitions = partitions.RemoveAt(i);
foreach (var otherPartition in otherPartitions)
{
differences.Add(Math.Abs(partition.Sum - otherPartition.Sum));
}
}
return differences.Average();
}
}
public class Node
{
public Item Item { get; set; }
public int Partition { get; set; }
public Node[] Children { get; set; }
}
private (Node tree, int totalSum) InitTree(IEnumerable<Item> items)
{
var root = new Node();
var totalSum = 0;
Node[] previousLevel = {root};
foreach (var item in items.OrderByDescending(i => i.Size))
{
totalSum += item.Size;
var currentLevel = new Node[_numPartitions];
for (var i = 0; i < _numPartitions; i++)
{
currentLevel[i] = new Node
{
Item = item,
Partition = i
};
}
foreach (var node in previousLevel)
{
node.Children = currentLevel;
}
previousLevel = currentLevel;
}
return (root, totalSum);
}
private ImmutableList<Partition> GetPartitions(Node tree, int totalSum)
{
var partitions = ImmutableList<Partition>.Empty;
for (var i = 0; i < _numPartitions; i++)
{
partitions = partitions.Add(new Partition(i));
}
return TraverseTree(tree, partitions, totalSum, double.MaxValue, ImmutableList<Partition>.Empty);
}
private ImmutableList<Partition> TraverseTree(Node node, ImmutableList<Partition> partitions, int totalSum, double bestDifference, ImmutableList<Partition> bestPartitions)
{
var currentPartitions = partitions;
if (node.Item != null) // skip root
{
// place item into its partition
var updatedPartition = currentPartitions[node.Partition].Add(node.Item);
currentPartitions = currentPartitions.SetItem(node.Partition, updatedPartition);
}
// if this is a leaf, partition is complete
if (node.Children == null)
{
return currentPartitions;
}
// terminate path if partition is sufficiently bad
var largestSum = currentPartitions.Max(p => p.Sum);
if (largestSum - (totalSum - largestSum) / (_numPartitions - 1) >= bestDifference)
{
return null;
}
// contintue to traverse tree in ascending partition size order
foreach (var partition in currentPartitions.OrderBy(p => p.Sum))
{
var nextNode = node.Children[partition.Index];
var nextPartitions = TraverseTree(nextNode, currentPartitions, totalSum, bestDifference, bestPartitions);
if (nextPartitions == null) // path was terminated
{
continue;
}
// if we hit a perfect parition set, return it
var nextDifference = Partition.AverageDifference(nextPartitions);
if (nextDifference <= 1)
{
return nextPartitions;
}
// hold on to the best partition
if (nextDifference < bestDifference)
{
bestDifference = nextDifference;
bestPartitions = nextPartitions;
}
}
return bestPartitions;
}
_numPartitions = 4
var items = GetItems()
var (tree, totalSum) = InitTree(items);
var partitions = GetPartitions(tree, totalSum);
元素,则现在可以使用floating versions。
对于来自Visual Studio的构建,您需要explicitly rebuild来进行更改。对于非Visual Studio构建,您需要an issue discussing open versions and updates中所述的PackageReference
更新。