结构化项目及在C#的WinForms大型应用程序的依赖性(Structuring projects

2019-07-20 23:22发布

更新:
这是我的访问量最大的一个问题,但我还没有真正找到了我的项目一个满意的解决方案。 我在回答另一个问题读一个想法是创建一个工具,它可以“随时”为您从列表中选择项目,构建解决方案。 我还没有尝试,虽然。


你如何构建一个非常大的应用程序?

  • 在一个大的解决方案多个短小的项目/组件?
  • 一些大的项目?
  • 每个项目的一个解决方案?

你如何在你没有一个解决方案的情况下,管理依赖性。 注:我根据经验找的建议,你在谷歌找到答案不是(我可以做我自己)。

我目前正在在具有向上的80个dll文件,每个都在它自己的解决方案的应用程序。 管理的依赖几乎是一个全职工作。 有一个定制的内部“源代码控制”与所有的地方复制依赖的DLL附加功能。 似乎是一个次优的解决方案给我,但有没有更好的办法? 与80个项目的解决方案会工作在实践中相当粗糙,我害怕。

(背景:的WinForms,不是web)

编辑:(如果你认为这是一个不同的问题,给我留个评论)

在我看来,有间有相互依存关系:

  • 项目/解决方案结构为应用程序
  • 文件夹/文件结构
  • 分支结构的源代码控制(如果您使用的分支)

但是,我有很大的困难,这些分离出来单独考虑他们,如果这甚至有可能。

我问另一个相关的问题在这里 。

Answer 1:

源代码控制

我们有20个或30个项目正在建设成4个或5个分立式解决方案。 我们使用Subversion的SCM。

1)我们有一个树包含由命名空间和项目名称逻辑组织的所有项目SVN。 有一个在,将建立它们所有的根的.sln,但不是必需的。

2)对于每一个实际的解决方案,我们在SVN SVN的新干线文件夹:将所有必需的项目,使他们得到从主树下它们的位置更新外部引用。

3)在各溶液是.sln文件加上其他一些所需的文件,加上所独有的是溶液和跨解决方案不共享任何代码。

有许多较小的项目在时间有点痛(例如TortoiseSVN的更新消息会导致混乱与所有这些外部链接),但确实有依赖关系不允许是圆形的巨大优势,所以我们的UI项目取决于BO项目,但BO项目不能引用UI(他们也不应该!)。

架构我们已经完全切换到使用MS SCSF和CAB企业模式来管理我们的各个项目结合,相互作用的一个双赢表格界面的方式。 我不确定,如果你有同样的问题(多个模块需要在一个常见的形式环境共享空间),但如果这样做,那么这可能也带来一些理智,并约定你如何建筑师和组装您的解决方案。

我提到,因为SCSF往往合并BO和UI型功能集成到同一个模块,而以前我们保持了严格的3级策略:

FW - 框架代码。 代码,其功能涉及到软件的关注。 BO - Business Objects公司。 代码,其功能涉及到的问题域的担忧。 UI - 代码它涉及到用户界面。

在这种情况下的依赖关系是严格的UI - > BO - > FW

我们已经发现,我们甚至可以在使用SCSF生成模块,因此所有在世界上好的:-)维护结构



Answer 2:

要管理的依赖,不管你有集/命名空间/项目的数量,你可以在工具一目了然NDepend的 。

Personnaly,如果需要的话我培养一个或几个解决方案中的几个大项目。 我写了一篇关于我的动机所以这里做: 受益于C#和VB.NET编译器PERF



Answer 3:

我认为你有一个包含所有80个项目的解决方案是非常重要的,即使大多数开发人员使用的大部分时间其他的解决方案。 根据我的经验,我倾向于用一个大的解决方案的工作,但要避免重建所有每个我打了F5的时候,我去Solution Explorer中的项目,右键单击我不感兴趣的项目,现在的痛苦,并做“卸载项目”。 这样一来,该项目停留在解决方案,但它不花费我什么。

话虽如此,80是个大数目。 这取决于如何以及那些80分解成dicrete子系统,我还可以创建其他的解决方案文件都包含一个有意义的子集。 这将节省我很多右键/卸载操作的努力。 然而,事实上,你就会有一个大的解决方案意味着总有他们的相互依存关系的明确观点。

在所有的,我曾经使用过的源代码控制系统,其整合VS选择把源代码管理中的.sln文件, 除非该.sln文件是在源代码管理很多不正常工作。 我觉得有趣,因为.sln文件曾经被认为是个人的事情,而不是一个项目范围内的事情。 我认为唯一的一种.sln文件那绝对值得源头控制是“一大解决方案”包含所有项目。 为了自动生成,例如,你可以使用它。 正如我所说的,人可能为了方便创建自己的解决方案,我不反对那些进入源代码控制,但他们更有意义的个人,而不是该项目。



Answer 4:

我认为最好的办法是打破它更小的解决方案。 在公司我目前的工作,我们有同样的问题; 80个项目++在溶液中。 我们所做的,就是要分裂成几个较小的解决方案与项目属于一起。 从其他项目相关的DLL的是建立在对项目挂钩,并与项目一起签入到源代码控制系统。 它使用更多的磁盘空间,但磁盘很便宜。 这样做,这样,我们就可以留在一个项目的第一版本,直到升级到1.5版本,是绝对必要的。 你仍然有决定升级到DLL的其他版本,虽然在添加DLL的工作。 有一个叫谷歌代码项目树蛙 ,显示如何构建解决方案,并开发树。 它不包含玉米粥文档,但我猜你可以得到如何通过看结构做一个想法。



Answer 5:

我见过的工作做好的方法是有一个大的解决方案,它包含了所有的项目,允许项目范围构建进行测试(没有人真正用这个,虽然基础上,因为它太大了。),然后有规模较小的项目开发者使用其中有组合在一起的各种相关项目。

这些都对其他项目depencies但是,除非接口改变,或者他们需要更新他们使用,他们可以继续使用较小的项目,而不必担心一切的dll的版本。 因此,他们可以办理入住手续的项目,同时,他们对他们的工作,然后固定这些(变化的版本号后),当其他用户应该开始使用它们。

最后一次或每周两次或更加频繁整个解决方案是重建只使用固定代码,从而检查是否集成了正常工作,并给予测试好身材再次进行测试。

我们经常发现,庞大的代码段没有变化频繁,所以这是没有意义的装载它所有的时间。 (当你的工作在较小的项目。)

使用这种方法的另一个优点是在某些情况下,我们有功能件历时个月完成,使用上述方法意味着这可能会继续,而不会中断其他工作流。

我想这其中的一个关键标准是不是有很多交叉的依赖在你的解决方案,如果你这样做,这种做法可能并不合适,但是,如果依赖关系是比较有限的,那么这可能是要走的路。



Answer 6:

一对夫妇的系统上,我们有不同的部件不同的解决方案,我的工作。 每个解决方案有一个共同的输出文件夹(与调试和释放子文件夹)

我们用它们之间的解决方案和文件引用内项目引用。 每个项目都采用了参考路径找到其他解决方案的组件。 我们不得不手动编辑.csproj.user文件到$(配置)的MSBuild变量添加到参考路径,VS上验证路径坚持。

对于外界建立的VS我写的MSBuild脚本,递归识别项目的依赖,从颠覆获取他们建立他们。



Answer 7:

我放弃了在项目引用(虽然你的声音宏妙),原因如下:

  • 这是不容易的地方有时依赖项目存在,有时甚至没有不同的解决方案之间切换。
  • 需要的是能够通过自身打开项目并构建它,以及从其他项目单独部署。 如果有项目引用建成,这有时会导致问题进行部署,因为一个项目引用导致它寻找一个特定版本或更高版本,或者类似的东西。 它仅限于换入或换出不同版本的依赖关系的混搭能力。
  • 另外,我有指向不同版本的.NET Framework的项目,所以真正的项目引用并不总是反正发生。

(仅供参考,一切我都做的是,VB.NET,所以不知道如果行为C#任何细微的差别)

所以我:

  • 我反对建任何项目,是在开放式的解决方案,这些都没有,从全球的文件夹,如C:\ GlobalAssemblies
  • 我的持续集成服务器保持这个最新的网络共享,我有一个批处理文件同步任何新的东西,以我的本地文件夹。
  • 我还有一个本地文件夹,如C:\ GlobalAssembliesDebug其中每个项目都有一个后生成的步骤,其复制bin文件夹中的内容到这个debug文件夹中,只有在调试模式。
  • 每个项目都有添加到他们的参考路径这两个全球性的文件夹。 (初在C:\ GlobalAssembliesDebug,然后C:\ GlobalAssemblies)。 我有这个引用路径手动添加到.vbproj文件,因为Visual Studio的UI他们就将此到.vbprojuser文件,而不是。
  • 我有一个预生成步骤,如果在释放模式,由C删除内容:\ GlobalAssembliesDebug。
  • 在作为主体项目,如果有,我需要复制(输出到,我需要其他项目的bin文件夹中的文本文件)非DLL的任何项目,然后我把该项目将它们复制到主机项目预生成的一步。
  • 我在溶液性质手动指定项目的依赖,让他们建立正确的顺序。

那么,这样做是:

  • 允许我使用项目的任何解决方案,而瞎搞与项目引用。
  • Visual Studio中仍然让我踏进了在该解决方案开放的依赖项目。
  • 在调试模式下,它建立对开放加载的项目。 因此,首先它看起来到C:\ GlobalAssembliesDebug,那么如果不存在,到C:\ GlobalAssemblies
  • 在发布模式,因为它会删除一切从C:\ GlobalAssembliesDebug,它只是看起来C:\ GlobalAssemblies。 我想这样做的原因是,发布版本是不反对任何在我的解决方案中暂时改变建。
  • 这是很容易装载和卸载的项目毫不费力。

当然,它并不完美。 调试经验不是像你一样的项目引用。 (不能做的事情一样“去定义”,并将它的工作权利),以及其他一些有点古怪的东西。

不管怎么说,这就是我对我试图让事情对我们最好的地方工作。



Answer 8:

我们对源代码控制一个巨大的解决方案,在主分支。

但是,每个开发者/团队对项目的小部分工作,有自己的分支,它包含与只需要几个项目的解决方案。 这样一来,该解决方案是足够小,可以很容易地maintenaced,而不要在大型​​解决方案的其他项目/ dll的影响。

然而,就是这个一个条件:不应该有解决方案中过多的相互关联的项目。



Answer 9:

OK, having digested this information, and also answers to this question about project references, I'm currently working with this configuration, which seems to 'work for me':

  • One big solution, containing the application project and all the dependency assembly projects
  • I've kept all project references, with some extra tweaking of manual dependencies (right click on project) for some dynamically instantiated assemblies.
  • I've got three Solution folders (_Working, Synchronised and Xternal) - given that my source control isn't integrated with VS (sob), this allows me to quickly drag and drop projects between _Working and Synchronised so I don't lose track of changes. The XTernal folder is for assemblies that 'belong' to colleagues.
  • I've created myself a 'WorkingSetOnly' configuration (last option in Debug/Release drop-down), which allows me to limit the projects which are rebuilt on F5/F6.
  • As far as disk is concerned, I have all my projects folders in just one of a few folders (so just one level of categorisation above projects)
  • All projects build (dll, pdb & xml) to the same output folder, and have the same folder as a reference path. (And all references are set to Don't copy) - this leaves me the choice of dropping a project from my solution and easily switching to file reference (I've got a macro for that).
  • At the same level as my 'Projects' folder, I have a 'Solutions' folder, where I maintain individual solutions for some assemblies - together with Test code (for example) and documentation/design etc specific to the assembly.

This configuration seems to be working ok for me at the moment, but the big test will be trying to sell it to my colleagues, and seeing if it will fly as a team setup.

Currently unresolved drawbacks:

  • I still have a problem with the individual assembly solutions, as I don't always want to include all the dependent projects. This creates a conflict with the 'master' solution. I've worked around this with (again) a macro which converts broken project references to file references, and restores file references to project references if the project is added back.
  • There's unfortunately no way (that I've found so far) of linking Build Configuration to Solution Folders - it would be useful to be able to say 'build everything in this folder' - as it stands, I have to update this by hand (painful, and easy to forget). (You can right click on a Solution Folder to build, but that doesn't handle the F5 scenario)
  • There is a (minor) bug in the Solution folder implementation which means that when you re-open a solution, the projects are shown in the order they were added, and not in alphabetical order. (I've opened a bug with MS, apparently now corrected, but I guess for VS2010)
  • I had to uninstall the CodeRushXPress add-in, because it was choking on all that code, but this was before having modified the build config, so I'm going to give it another try.

Summary - things I didn't know before asking this question which have proved useful:

  1. Use of solution folders to organise solutions without messing with disk
  2. Creation of build configurations to exclude some projects
  3. Being able to manually define dependencies between projects, even if they are using file references

This is my most popular question, so I hope this answer helps readers. I'm still very interested in further feedback from other users.



文章来源: Structuring projects & dependencies of large winforms applications in C#