中大型项目的结构

时间:2012-04-16 18:34:01

标签: c# class namespaces

我是初学程序员,为任何愚蠢道歉。

来自python背景创建只有几个类的小项目,我会在大多数时间将所有代码放在一个文件中。

我最近一直在学习c#,而且我正在编写一个相当大的控制台应用程序(10,000行+)。我显然不能把所有内容放在一个文件中,但我不确定如何将项目分成更小的部分。

到目前为止,我这样做的方法是为我的解决方案中的每个命名空间创建一个新项目,并相应地将每个类拆分为一个单独的文件。到目前为止,我有四个名称空间。我已经独立编写了每个命名空间,以便在其他项目中使用每个命名空间。

我现在处于这个阶段,我希望将每个命名空间拼凑在一起以构建我的控制台应用程序。我该怎么做呢?

另外,我是以正确的方式构建代码吗?

另外+ 1,是否可以使用位于项目中完全不同的目录中的文件?

非常感谢提前。

4 个答案:

答案 0 :(得分:3)

在正确的轨道上听起来或多或少。解决您的问题/结构:

1)不需要让每个唯一的命名空间由自己的项目表示;如果它有助于组织您的类,您可以(并且可能应该)在同一个项目中拥有多个子命名空间。在您的情况下,听起来每个人都被编程为自己的独立组件,因此每个组件的项目都是有意义的。

2)将每个类拆分成一个单独的文件是好的,继续这样做。

3)不确定您要求将代码拼凑在一起的内容。您是指如何在Visual Studio中物理引用/链接项目或编写/访问API的最佳实践?如果是前者,可以右键单击项目下的“引用”项并指向项目(而不是其编译的DLL)。如果是后者,您可以遵循各种编程模式,但通常您会想要从项目中抽象出一个漂亮的API,这样您就不会担心代码的内部工作。

4)您绝对可以从完全不同的目录中引用文件。只需右键单击项目或文件夹,选择“添加 - >现有项目”,然后浏览到该文件。您可能希望将其添加为“链接”,以便它不会物理复制文件:http://msdn.microsoft.com/en-us/library/9f4t9t92%28VS.80%29.aspx

这是另一个StackOverflow问题,它涉及可能的解决方案结构:Solution: Per application, or per application suite

答案 1 :(得分:3)

当您从命名空间开始时,您通常会使用您的公司或组织名称(例如“A”)。如果您有多个产品/项目并且正在为该项创建代码,您将需要添加限定符(例如“B”,“C”等,因此您将拥有AB,AC等)。< / p>

然后,一般方法是您希望在相关的命名空间中将类型组合在一起。如果您创建了一个类型,并且它是针对常见问题的通用/实用/一次性解决方案,那么您将希望将其保留在更广泛的范围命名空间中。当您发现要创建多种类型以支持某些功能或目的时,您可能希望创建一个包含这些类型的窄命名空间。例如,假设您需要为A.B编写多个数据访问组件,其中包含数据传输对象,数据访问对象等。然后,您可能希望将这些类型放在A.B.DataAccess中。

但是,请记住.NET使用OOP范例。一个OOP范例是代码重用。因此,如果您访问A.B和A.C中的数据,您最好创建可重用的数据访问组件,以鼓励在两个项目中重用代码。在这种情况下,您可能希望有一个项目,例如A.Common,其中包含您的任何产品使用的常见类型,包含可在AB,AC等中使用的一般用途,通用或抽象概念。< / p>

让我尝试进一步说明这个例子。

  • 项目:A.Common(集会名称)
  • 目的:任何项目的可重用类型
  • 命名空间:A,A.DataAccess
  • 类型:A.DataAccess.DataAccessObjectBase

  • 项目:A.B(集会名称)
  • 目的:产品类型“B”
  • 参考文献:A.Commmon
  • 命名空间:A,A.B,A.B.DataAccess
  • 类型:A.B.DataAccess.DataAccessObject(实现A.DataAccess.DataAccessObjectBase)

  • 项目:A.C(集会名称)
  • 目的:产品类型“C”
  • 参考文献:A.Common
  • 命名空间:A,A.C,A.C.DataAccess
  • 类型:A.C.DataAccess.DataAccessObject(实现A.DataAccess.DataAccessObjectBase)

这是一个非常简单粗暴的例子,但希望它能帮助您可视化程序集和命名空间之间的关系。

其他一些提示:

  • 不要过度创建命名空间,尤其是在创建深层命名空间(例如A.B.Something.SomeMoreStuff.EvenMoreStuff)时,除非它是明智的。这让你找到更难的东西。
  • 命名空间应该从更广泛的目的到更窄的目的。此外,如果您在较窄的命名空间中创建一个类型,该类型严重依赖于更广泛的命名空间中的内容,请确保将其放在更宽的命名空间下。例如A.B.Broader.Narrower。

最后,您应该继续为每个源文件创建一个类型。

答案 2 :(得分:2)

命名空间可帮助您整理代码并提供separation of concerns。也可以通过创建文件夹或单独的项目来完成。通过良好的逻辑分离,您可以构建可维护和可伸缩的应用程

当您决定是创建新文件夹还是新项目时,您应该依赖常识。例如,为 hello world 应用程序创建多个项目是一种过度杀伤力。为单个类创建文件夹也是过度的。但是当您有几个彼此密切相关的类时,请考虑将此特定问题与其他应用程序分开。例如。如果您有CustomerRepository,则添加OrderRepositoryVendorRepository。它很好地决定突出他们所代表的关注点。创建Repositories文件夹并将所有这些类移到那里。

对于大型应用程序,通常将业务逻辑,数据访问逻辑和用户界面等问题分开。通常,与这些问题相关的课程分别进行项目。请记住,完成分离是为了使您的代码更易于理解和维护。因此,名称空间应该向您和将维护您的应用程序的任何人描述问题。例如。你可以使用三个项目:

FooCompany.BLL
FooCOmpany.DAL
FooCOmpany.UI

这是业务逻辑层,数据访问层和用户界面的首字母缩略词。没有'标准'名称。您可以使用任何可以更好地描述代码的内容。以下是我通常用于公司Foo产品栏的项目结构示例:

// Assembly for business logic
Foo.Bar.Domain
Foo.Bar.Domain.Model
Foo.Bar.Domain.Services
Foo.Bar.Domain.Repositories
// Assembly for data access
Foo.Bar.Persistence.NHibernate 
// Assembly for application services
Foo.Bar.Services
// Project for presentation    
Foo.Bar.Presentation.Web
Foo.Bar.Presentation.Web.Controllers
Foo.Bar.Presentation.Web.Views

通常的做法是使用您正在开发的公司名称启动命名空间名称。见Namespace Naming Guidelines。当在不同的名称空间中有两个具有相同名称的类时,这可以避免名称冲突。

答案 3 :(得分:1)

我将从最后一个问题开始到第一个问题。您可以使用位于项目中完全不同目录中的文件。我想你走的是正确的。关于不同的命名空间,您可以使用此代码

using System;
using namespace1; 
using namespace2;