在Visual Studio中如何在项目/解决方案之间共享代码?

263

我有两个解决方案,它们之间有一些公共代码,所以我想将其提取出来并在它们之间共享。此外,我想要能够独立发布这个库,因为它可能对其他人有用。

  • 在Visual Studio 2008中,最佳的做法是什么?
  • 一个项目可以存在于多个解决方案中吗?
  • 是否需要为不同的代码片段创建单独的解决方案?
  • 一个解决方案是否可以依赖于另一个解决方案?

Note: 格式已被保留,但由于HTML标签不可见,因此未翻译。

17
2014年,Nuget 是答案。 - Ravi
2
@Ravi 我想将我办公室开发的Visual Studio Web应用程序模块化。但是,当我尝试将Visual Studio Web应用程序模块化为不同的Web应用程序时,组件之间的循环依赖关系出现了问题。例如,我无法为每个计划中的Web应用程序模块化POCO项目,因为依赖性太大。是否有一种方法可以使用Nuget来帮助模块化? - CS Lewis
17个回答

271
你可以在两个项目之间“链接”一个代码文件。右键单击您的项目,选择添加 -> 现有项,然后单击添加按钮旁边的向下箭头:

Screengrab

根据我的经验,链接比创建库更简单。 链接的代码将生成一个带有单个版本的单个可执行文件。

9
甜的,这就是我在寻找的答案。我不想要一堆DLL文件。干杯。 - CAD bloke
73
你为什么要这样做?我们有库、封装来做这个。我不认为这样做有商业或逻辑上的意义。 - Ryan Ternier
22
此外,您的链接可能不在同一源代码控制下。这是一个非常危险的建议。 - Kugel
14
这个解决方案在某些情况下很有用。例如,在我正在开发 InfoPath 2007 的过程中,部署单独的 DLL 到 SharePoint 并不是一件简单的事情。为了在 InfoPath 表单之间共享通用功能,使用链接的类文件方法非常有用。它位于各个表单项目的上一级,并且所有内容都在根目录下进行源代码控制。 - Oliver Gray
7
另一个有用的例子是,假设你正在开发两个需要互相通信的应用程序。其中一个是64位,另一个是32位,因此你不一定希望从同一代码生成独立的dll文件以供每个项目引用。这样,你就可以模仿使用.h文件的c语言功能。 - user912447
显示剩余14条评论

81

一个项目可以被多个解决方案引用。

将你的库或核心代码放入一个项目中,然后在两个解决方案中引用该项目。


192
好的,但是怎样做呢?有些指示吗? - cja
2
这个(旧的)回答本身是不完整的,因为它会导致多个程序集:然而,当与ILMerge(尤其是内部化选项)结合使用时,它就变成了一个非常强大的解决方案。 - user2246674
3
@user2246674:为什么因为多个程序集而不完整?OP没有提到单个程序集。 - John Saunders
1
@Jfly:将那些不对外暴露的东西重命名不会影响到外部代码。将那些公开可见的东西重命名只应该在使用共同代码的所有项目以及共同代码本身都在一个解决方案中的情况下进行。您可以手动创建“主”解决方案,其中包含所有这些项目,并且仅用于此目的。 - John Saunders
1
这取决于你所说的“另一个实例”的含义。最好是提出一个新问题,并提供更多细节。 - ilivewithian
显示剩余4条评论

41

文件 > 添加 > 现有项目... 可以让您将项目添加到当前解决方案中。我之所以要提及这一点,是因为以上帖子中没有指出这一点。这使您可以在多个解决方案中包含同一项目。


1
这确实有效;但缺点是它不能将两个项目构建为一个程序集。 - Ian Boyd

25

您可以使用以下技术进行内联通配符(这是@Andomar解决方案在.csproj中保存的方式):

<Compile Include="..\MySisterProject\**\*.cs">
  <Link>_Inlined\MySisterProject\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>

输入:

    <Visible>false</Visible>

如果你想隐藏文件和/或防止通配符包含在像上面的“虚拟现有项目”文件夹中添加或删除项目时被扩展,例如MySisterProject


1
不错!这看起来像是一个不错、轻量级的解决方案,如果你能原谅我打趣的话。 - CAD bloke
2
@CAD Bloke:是的,那个很有趣。为了明确起见,我将明确说明以下内容,以帮助某些人...您可以卸载/重新加载项目以使其获取更改(Alt-P,L两次)。 VS2010问题在于.targets文件等<Import到.csproj文件中的文件会被缓存,直到您重新加载解决方案,就像您所说的那样。 - Ruben Bartelink
3
这是最新版本的通配符主题代码...<Compile Include="..\_Src\**\*.*" Exclude="..\_Src\Properties\AssemblyInfo.cs;..\_Src\bin\**\*.*;..\_Src\obj\**\*.*;..\_Src\**\*.csproj;..\_Src\**\*.user;..\_Src\**\*.vstemplate"><Link>Src%(RecursiveDir)%(Filename)%(Extension)</Link></Compile>。 - CAD bloke
@CADbloke或OP,请编辑(或回答)以显示如何添加XML引用?我是一名长期的编码人员,但对Visual Studio完全不熟悉...谢谢。 - Krista K
1
@ChrisK 这是我在 csproj 文件中编辑的一些更明确的说明... http://www.theswamp.org/index.php?topic=41850.msg472902#msg472902。我只是在 Notepad++ 中进行了编辑。当我保存后,VS会看到它已经改变并要求重新加载。在 VS 中有设置来控制这种行为。 - CAD bloke
显示剩余8条评论

25

您可以将一个项目包含在多个解决方案中。我认为一个项目并没有属于哪个解决方案的概念。不过,另一种选择是将第一个解决方案构建到某个已知位置,并引用已编译的二进制文件。这种方法的缺点是,如果您想要根据是否在发布或调试配置中进行构建来引用不同版本,则需要做一些工作。

我不认为您可以使一个解决方案依赖于另一个解决方案,但是您可以通过自定义脚本以适当的顺序执行自动化构建。基本上将常见库视为像 NUnit 等其他第三方依赖项一样处理。


该项目确实有NuGet包存储的跟踪,但这可以通过打开解决方案进行更改,这可能会在构建时导致麻烦,因此这是一个更可取的解决方案。 - Shane Courtrille

19

您只需要创建一个独立的类库项目来包含共享代码,它不需要成为使用它的任何解决方案的一部分。从需要使用共享代码的任何项目中引用该类库。

唯一需要注意的问题是,您需要使用文件引用来引用该项目,因为它不会成为引用它的解决方案的一部分。这意味着实际的输出程序集必须放置在任何构建引用它的项目的人都可以访问的位置上。例如,可以将程序集放置在共享目录中。


我猜如果我创建一个构建事件并将dll发布到引用项目中的源代码控制的_lib文件夹中,然后检入该DLL,它应该可以工作...虽然这种方法似乎有点hacky.. - hanzolo
1
如果您想对每个构建进行源代码控制,那么您可以设置一个构建目标来检出库dll文件,将其从构建输出复制到库文件夹中,然后再将dll文件检入。 - John Saunders

12

将通用代码提取到一个类库项目中,并将该类库项目添加到您的解决方案中。然后,您可以通过向该类库添加项目引用来从其他项目中添加对通用代码的引用。与二进制/程序集引用相比,具有项目引用的优势是,如果您更改构建配置为调试、发布、自定义等,则通用类库项目也会根据该配置进行构建。


9
你可以在多个解决方案中包含相同的项目,但是在某些时候你肯定会遇到问题(例如当你移动目录时,相对路径可能会失效)。
经过多年的尝试和探索,我最终想出了一个可行的解决方案,但需要你使用Subversion进行源代码控制(这并不是坏事)。
在你的解决方案目录级别上,添加一个指向你想要包含在解决方案中的项目的 svn:externals 属性。 Subversion将从存储库中提取该项目并将其存储在解决方案文件的子文件夹中。你的解决方案文件只需使用相对路径引用你的项目即可。
如果我有更多时间,我会详细解释这个过程。

在定义您的项目时,请确保仅使用相对路径... 这应该特别针对可重用的项目,解决更多不起眼的问题。 - xtofl
5
仅供参考,svn:externals 是指向另一个仓库的硬链接。当你移动仓库时,这些外部链接仍然指向旧的仓库。 - Andomar
对于 Git,您可以使用 SubTree SVN:GIT 中的 externals 等效物? - Michael Freidgeim

7
现在您可以使用“共享项目”。
“共享项目”是在多个应用程序之间共享公共代码的好方法。我们已经在Visual Studio 2013中作为Windows 8.1通用应用程序开发的一部分体验了“共享项目”类型,但是在Visual Studio 2015中,它是一个独立的新项目模板;我们可以将其与其他类型的应用程序一起使用,例如控制台、桌面、电话、商店应用等。当我们想要在单个平台上跨多个应用程序共享公共代码、逻辑以及组件时,这种类型的项目非常有帮助。这也允许访问特定于平台的API、资产等。

enter image description here

查看更多信息,请访问this


这对我来说是跨解决方案共享代码的最简单的解决方案。无需使用ILMerge和MSBuild合并多个程序集/ DLL。 - Tobi Obeck

5

涉及到的两个主要步骤如下:

1- 创建一个C++动态链接库(dll)

在Visual Studio中:

New->Project->Class Library in c++ template. Name of project here is first_dll in 
visual studio 2010. Now declare your function as public in first_dll.h file and 
write the code in first_dll.cpp file as shown below.

头文件代码

// first_dll.h

using namespace System;

namespace first_dll 
{

public ref class Class1
{
public:
    static double sum(int ,int );
    // TODO: Add your methods for this class here.
};
}

Cpp文件

//first_dll.cpp
#include "stdafx.h"

#include "first_dll.h"

namespace first_dll
{

    double Class1:: sum(int x,int y)
    {
        return x+y;
    }

 }

检查这个

**Project-> Properties -> Configuration/General -> Configuration Type** 

这个选项应该选择动态链接库(.dll),然后现在构建解决方案/项目。

first_dll.dll文件已经被创建在Debug文件夹中。

2- 在C#项目中链接它

打开C#项目

Rightclick on project name in solution explorer -> Add -> References -> Browse to path 
where first_dll.dll is created and add the file.

在C#项目中添加此行代码。
Using first_dll; 

现在可以使用下面的语句在某个函数中访问来自DLL的函数

double var = Class1.sum(4,5);

我在VS2010中创建了一个C++项目的dll,并在VS2013 C#项目中使用它。它运行良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接