NuGet缓存和版本控制问题

时间:2014-11-10 00:52:41

标签: c# visual-studio maven nuget

我遇到了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 ......这似乎对项目中的多个开发人员来说会有问题)?

任何见解都表示赞赏。感谢。

2 个答案:

答案 0 :(得分:2)

警告:过时

截至2018年,此答案已过期 - 请参阅我的other answer了解最新信息。

没有Nuven等效的maven SNAPSHOTs

NuGet并不真正支持像Maven那样的SNAPSHOT依赖关系,尽管有open issue来实现类似的东西,discussion关于这样的功能。

建议的可能性是写一个脚本:

  • 生成具有不同版本的新Foo包
  • 更新栏以引用最新版本的Foo

另类方法

或者当我处理自己的项目时,我总是从源代码构建和引用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更新。