Visual Studio解决方案的良好做法[关闭]


10

希望有一个相对简单的问题。我正在开始一个新的内部项目,以创建建筑物内已修复设备的易处理性。

该数据库远程存储在Web服务器上,并将通过Web API(JSON输出)进行访问并受OAuth保护。前端GUI在WPF中完成,而业务代码在C#中完成。

由此,我看到了不同的层Presentation / Application / Datastore。将提供用于管理对API进行所有身份验证的调用的代码,代表实体(业务对象)的类,构造实体(业务对象)的类,WPF GUI的各个部分,WPF视图模型的各个部分,等等。

最好在单个项目中创建此项目,还是将其拆分为单个项目?

我内心说应该是多个项目。我以前已经做过这两种方式,并且发现使用单个项目解决方案更容易进行测试,但是对于多个项目,则可能会产生递归依赖性。特别是当类具有使测试变得更容易的接口时,我发现事情可能变得很尴尬。


1
我将把它们分离成对该项目有意义的东西。
Ramhound,2011年

其他人是否有任何想法,如MattDavey所建议的那样,关于保留接口的项目。为了避免提到的依赖关系,我之前使用了这种方法。或者应该将类x的接口与类x放在同一项目中。
JonWillis 2011年

另外,你们都使用什么层。我看到了几个不同的变量,尽管主要变量是Presentation / Application / Infrastructure。有些还将应用程序分为两部分,即应用程序+服务。一些模型还提到了业务逻辑的特定层,对我而言,可以包含在业务对象本身中。
乔恩·威利斯(JonWillis)

Answers:


8

这取决于项目的规模

这是我倾向于使用的准则

  • 一个很小的项目,只有很少的页面或更少的页面,我几乎总是只关注一个项目。

  • 如果小型项目的数据访问层很大或很复杂,我可以将其分成自己的层,否则,它只能放在自己的文件夹中。

  • 如果项目更大,我几乎总是有一个单独的DAL项目,进一步的拆分取决于应用程序功能之间的界限。

  • 如果应用程序有多种用途,每个用途都有自己的视图,视图模型等,那么我通常将每个片段都分成自己的区域。如果每个部分都很小,我会用文件夹将它们分开。如果每个部分很大,我将通过一个项目将它们分开。

  • 如果我有需要引用同一组对象(多项目ViewModelBaseRelayCommand等等),我就对共享基础架构的对象创建一个项目。

  • 如果我有大量共享的自定义样式/模板/资源,则将为此创建一个项目。

附带说明,我在第一个大型WPF项目中犯了一个错误,将模型放在一个项目中,将视图放在另一个项目中,将视图模型放在第三个项目中,将它们分开。现在我可以告诉你,这不是路要走,因为维护成了一场噩梦:)


很好奇,通过分层将遇到哪些维护问题?
伊恩

@Rachel,我将使用WPF。因此,有兴趣知道您随后如何组织项目。我想我记得一个小MVC项目将3个部分分成3个dll时很痛苦。对于WPF,我的视图将是GUI,要更改的实体/业务对象,而ViewModel是它们之间的交互。ViewModel将处理调用存储库以加载/保存修复程序的逻辑(后者又具有工厂/ Web API等)。
JonWillis 2011年

1
@Ian最大的问题是,大多数较小的更改(例如添加单个字段)要求我在4个独立的库中查找Model,View,ViewModel和DAL。我当时从事的项目相当大,而且我浪费了很多时间在寻找特定文件上。从那以后,我改变使相关的对象组合在一起,因此,例如任何搜索相关的,例如SearchViewSearchViewModel以及SearchResultModel将所有的文件夹中组合在一起,我发现它使应用程序更易于维护。
雷切尔

@Ian我还记得有依赖性问题并遇到了循环引用,因为尽管尽了最大的努力,有些层仍需要引用其他层,但是该层正在引用它们,因此在重构之前,我有一些丑陋的解决方法
Rachel

1
@JonWillis我的大多数WPF项目都是根据我的答案中指定的要点细分的。通常,DAL是其自己的层,并且项目的每个模块或部分都被分组在一起(在其自己的文件夹,名称空间或项目中,具体取决于项目的大小)。因此,例如,所有搜索对象将在一起,包括Interface数据层的,但是搜索的实际数据访问层将在DAL库中。我经常有一个InfrastructureCommon库,其中包含常见的基类,接口和帮助程序类。
雷切尔

14

我已经看到了最好的结果,每层一个项目,每层一个测试项目。我看到解决方案涵盖了所有内容的解决方案,其中很少有10个或更少的项目无法完成。

不要陷入使用真正需要命名空间的项目的陷阱。大量的项目只不过增加了开销而已。


9

恕我直言,单独几乎总是更好。除非项目100%无关紧要,否则我几乎总是分离出我的数据层。原因是因为数据层倾向于最频繁地传递。您很少会把GUI连接到多个数据层,并期望它能正常运行。更常见的情况是,您只有一个数据层,并且希望将其分布在多个GUI(例如ASP.Net,WPF和Silverlight应用程序)中。当您可以仅构建数据层项目并将该dll作为下一个GUI的参考放置时,这真是太棒了。


+1当我开始新项目时,我经常会建立一个模拟数据层,将数据保存在内存中。让我先开始构建应用程序的其余部分。然后,我以后可以换出来的“真实”数据访问层..
MattDavey

您是否会考虑用于与Web服务器通信的实体(DTO),工厂和类,它们都是数据层的所有部分?
JonWillis 2011年

@JonWillis-不,可能不是全部。我会将Web服务器的工厂和类放在类库项目的名称空间中。我的典型数据层仅包含必需的dbml文件和/或edmx文件。通常,我会为“库/框架”提供自己的项目。尽管我确实看到人们一直在这样做,但绝对不需要将它们与GUI项目放在一起。
Morgan Herlocker 2011年

但是实际上,您需要花费多长时间将几个名称空间并将其分支到一个新项目中。我觉得这是一个非常容易的重构工作。
Didier A.

4

对我来说,4 *是神奇的数字。每层一个项目,一个定义所有接口/ DTO在它们之间进行通信的项目。

* 7如果计算单元测试


2

如果我正在这些不同的层上工作,或者与它们紧​​密耦合,那么我总是使用单个解决方案。我想按F5键,并在需要时重新构建所有项目。我认为没有“正确”的方法可以做到这一点。


2

它的个人品味,最重要的是要保持一致。我个人对应用程序的每一层都有一个单独的项目,因此分离很明显。


您分为哪几层?您是否有单独的应用程序/服务层,如果有,它们实际上有何不同。您的业​​务逻辑是否包含在应用程序/服务中,或者它们是实际业务对象上的方法?
JonWillis 2011年

1

项目数量的增加与启用单元测试和简化依存关系图有关,以至于事情并不那么复杂,以至于应用程序某一部分的更改会破坏应用程序中似乎无关的部分。

当我在进行某种依赖倒置时,它可以将所有“合同”,接口,抽象类,数据传输对象放到一个程序集中,从而得出结果。在另一个程序集中,我放置了所有与数据库有关的内容。单元测试需要自己组装。如果UI从根本上来说是不可测试的(例如ASP.NET winforms),则将UI分成可测试的代码和不可测试的代码-分别是一个程序集,将具有很大的好处。有时,一些代码开始出现,与数据库,UI或到目前为止我提到的任何内容都不相关-我希望代码是.NET框架中的代码。我将把该代码放入一个实用程序程序集,或者至少将其放入任何根程序集(可能是带有接口的程序集)中。

如果所有程序集都引用了或几乎引用了所有程序集,则应将它们合并回到单个程序集中。如果您或团队中的人员缺乏纪律,无法将数据层代码放入UI和数据层中的UI,则可以通过将其全部合并回单个层来简化操作。

某些版本的Visual Studio在大约15个程序集时会遇到性能问题,有时取决于存在的项目类型。从战略上来说,卸载项目文件有时会有所帮助。


目前,我是该公司的唯一开发人员。而且还刚从大学毕业,所以试图尽快在大型项目上灌输良好做法。我对使其可维护性感兴趣,因为在我什至开始对其进行记录之前,系统规范已经发生了很大变化,这与希望尽快实现系统的要求不符。您认为,仅包含接口的装配是合适的解决方案吗?这样,依赖关系应该仅取决于接口和工厂类。
JonWillis 2011年

1
是。最好了解组装拆分的动机,但是如果您(或您的团队成员)不理解拆分的动机,那么它仍然是一种廉价的操作。因此,即使最终所有的程序集都依赖于所有程序集并且没有单元测试的希望,将行为如契约(接口,抽象类)的事物移动到其自己的程序集上也是朝着正确方向迈出的一步,并且没有什么弊端。
MatthewMartin 2011年

-2

拥有多个项目的唯一很好的理由是,如果您需要在多个应用程序之间共享一组类和文件。

如果项目仅由一个应用程序使用,则不应首先创建它们。请改用名称空间。在查找文件时,省去了循环引用,dll开销和项目混乱的麻烦。

请阅读此文章,以更好地更深入地解释为何如此:http : //lostechies.com/chadmyers/2008/07/16/project-anti-pattern-many-projects-in-a-visual-studio-解决方案文件/

而且正如文章所述,我欢迎任何有正当理由拥有多个项目的人,除了跨应用程序共享代码以告诉我它是什么,因为我怀疑是否存在任何项目。


有关downvote的反议将不胜感激。
Didier A.14年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.