14

我正在开发一个新的 ASP.Net MVC 项目,我正在使用这个项目进入 DI。我很确定我将使用结构图,但这不是我要问的。我想弄清楚的是如何最好地组织我的解决方案。单元测试项目和模型是否都获得了一个配置文件来映射它们的依赖关系,或者是否有一个类来统治它们?

另外,在我深入这个之前,是否有任何新手陷阱需要避免?

非常感谢,所有......

更新 我应该补充一点,当我说“组织解决方案”时,我指的不是文件/文件夹的数量等,而是如何构造与 DI 相关的类。特别是如何管理引导程序。我可以看到我糟糕的措辞可能会导致混乱。

4

3 回答 3

11

如果你是唯一一个在这个项目上工作的人,我会先做对你有意义的事情。没有什么比强加给您不直观的目录或项目结构更糟糕的了。BaseController 类是在 \Core\ 文件夹还是 \Controller\ 文件夹中?我个人会查看控制器,但有些人发誓它应该在 \Core\ 或 \Bases 中。

一个新手陷阱是认为您可以以错误的方式组织代码,并以某种方式反映了项目的成功。我见过一个文件夹中有 30 个文件的项目,而其他项目中有 30 个文件的 20 个文件夹。

第二个新手陷阱是忘记了与其他语言相比,您可以从 Visual Studio 的出色智能感知、代码导航工具和重构支持中受益。您还有一个编译器,它可以让放错文件的痛苦大大减轻。如果你把东西放在“错误”的地方,没关系,你总能找到它并将它拖到需要的地方。

老实说,我现在正在做一个项目,我什至不确定某些类在我的文件结构中的位置。Go To Definition/Declaration 是我经常使用的键盘快捷键。因为只有我在使用代码,所以这很好。如果我不得不在项目中添加另一个开发人员,我可能会清理干净。

就我个人而言,我倾向于将接口及其实现类型放在同一个文件夹中。IPaymentGateway 与 AuthorizeNetGateway 和 PaypalGateway 位于同一文件夹中。如果我无法在我的解决方案资源管理器侧边栏中一次查看该文件夹中的所有文件,那么我将所有网关文件移动到 \Gateway\ 文件夹中。

随着依赖注入添加到组合中,我建议您只关注名称空间爆炸。你能做的最糟糕的事情就是用长的 using 声明和别名弄乱你的引导程序和文件。

ForRequestedType<Customer>

比干净

using KevDog.Models
using Customer=KevDog.Models.Customer

或者

ForRequestedType<KevDog.Models.Customer>

避免此问题的另一种方法是在命名事物时明确:Customer、CustomerViewModel、CustomerController、CustomerDataRow、CustomerView

对于 TDD,您几乎必须有两个引导程序来管理您的具体类型。您真的不希望您的单元测试使用 AuthorizeNetGateway : IPaymentGateway,而是 StubGateway : IPaymentGateway。

现在我也是 DI 的新手,所以我倾向于让事情变得非常简单,并反映 101 级教程和文档。仅当特定情况需要并且您确切知道为什么要这样做时,才应使用基于构建配置的动态注入。

我通常也会保留 MVC 应用程序的默认结构。让您的代码与 99% 的教程和视频具有相同的结构更容易。

希望这可以帮助。

于 2009-06-08T03:30:57.570 回答
2

鼓励更好的 TDD。有两个测试项目和/或命名空间 X.Unit.Tests & X.Integrations.Tests。

我在我的主项目中的“命名空间目录”(/Config)中有我的 DI 代码,但在我的集成代码测试中,如果我在我的基本装置或设置中需要,我可能只是调用这些注册表或覆盖。

例如

/Config/ServiceRegistry.cs /Config/RepositoryRegistry.cs /Config/Bootstrapper.cs

在 global.asax 我调用 Bootstrapper.Init() 这将调用 x.AddRegistry(new ServiceRegistry()) 等等。

在我的单元测试中,您不需要仅在集成测试中使用 DI。在我的IntegrationTests 中,例如,如果我正在通过数据库测试NHibernate,我可能会在TestSetUp 中使用RepositoryRegistry 初始化SM,并使用一个仅包装GetInstance() 的辅助方法。

我不会拆分到 .Bootstraper 和 .Domain 项目,直到我必须... 三个项目,X、X.UnitTests、X.Integration 如果您以后需要更多移动。我来自一个背景/公司强制执行的数十个项目,它第一次减少感觉很脏,但现在不是,我会快速运行增长并在需要时重新组织解决方案结构。

于 2009-07-22T10:59:11.003 回答
0

这是我为自己解决相同问题的第一次尝试,但由于这是我的第一次尝试,我希望人们可以尽可能多地评论或批评它,就像我希望它可以作为您可能的解决方案一样:

public VatManager()
 : this(new VatManagerRegistry()) { }

public VatManager(Registry registry)
 : this(new Action<IInitializationExpression>(x => { x.AddRegistry(registry); }))
  {
  }

public VatManager(Action<IInitializationExpression> action)
  {
   ObjectFactory.Initialize(action);
   data = ObjectFactory.GetInstance<IVatManagerData>();
  }

我有三个构造函数重载 - 无参数默认构造函数了解需要创建以在生产环境中使用的具体结构映射注册表。另外两个允许实例化此管理器类的其他代码提供它们自己的 StructureMap Registry(s) 或 Actions,以便它们可以自己控制依赖注入,例如在提供模拟而不是具体实例的自动化测试的情况下依赖关系。我应该补充一点,该解决方案并非特定于 ASP.NET MVC 上下文,并且不会从 *.config 文件中提取任何配置信息。

于 2010-06-18T17:54:36.597 回答