2008-11-19 47 views
6

我已经在这方面做了很多搜索,并没有找到有凝聚力的运气。我是一个相对较新的开发人员,刚刚开始我的第一个职业发展职位。我知道,即使在基础知识领域,我也有很多东西需要学习。基于收听Podcast,阅读博客,论文等;我已经认识到,在设计和构建软件时,记住依赖注入,IOC,依赖注入的分离似乎是正确的。我将这些概念提到了很高的层次,并且想尽我所能地处理我在这方面的工作。国际奥委会设计资源

所以,这是蹭。这是怎么设计的东西?我工作的团队继承了一个基于Web的产品,这个产品的耦合非常紧密,文档记录很差,通常不易维护一些软件。 Evryone似乎喜欢去除这对夫妻的想法。他们喜欢开发自动化测试的想法(从我读过的内容来看,使用松散耦合的组件更容易)。似乎没有人知道如何去做。我愿意尝试一下,但我需要指导。我发现的每件事似乎总是以非常高的水平谈论这件事,或者相反,只关注整体的一小部分。我希望获得关于一本书,一系列教程,视频或SOMETHING的一些指导,这些指导需要一些真实世界的例子,并向您展示如何应用这些原则。理想情况下,我很乐意看到一些内容,例如......“以这个订单录入应用程序为例,这是大多数人如何使用标准的ADO.NET DataSet将它们放在一起,等等......等等......等等。现在,如果我们应用国际奥委会的原则使之成为一个松散耦合的项目,那么你的工作方式就会有所不同,这就是为什么你这样做的原因,以下是你试图完成这项工作时必须考虑的问题。

我知道这有点长啰嗦,我只是有点沮丧,我发现的大多数综合训练材料根本没有以某种开始的方式讨论这个话题,可以申请良好的做法从第一天起。

谢谢你们所有的时间。

Steve

回答

2

我只能描述我们想出了什么。我们从各种在线库中借用了可用性语法等,但代码都是我们的。

基本上,我们有我们所说的ServiceContainer,一个对象。它总是有一个全局实例,如果你愿意的话,可以是一个单例副本,静态的,因此在web应用程序中,在appdomain中的所有用户之间共享。

ServiceContainer包含规则。规则说明如这样的事情如果有人要求XYZ类型的对象,请按照以下步骤向他们提供

例如,一个规则可能是为了使某些代码获得实现IDbConnection的对象,容器将构造,配置并返回一个新的SqlConnection对象。

有问题的代码因此不知道,也不在意它使用的是SqlConnection对象,而不是OleDbConnection对象。

写完之后,我意识到这不是一个很好的例子,因为最终你最终会询问命令对象的连接,并且为该对象提供的SQL语法必须根据连接类型定制。但是,如果我们现在可以忽略这一点,代码就不会知道它连接到SQL Server,它只知道它有一个连接对象。

现在,代码在这里的问题将需要给予它应该使用的容器,从而规则。这意味着从单元测试的角度来看,我可以创建一个新的ServiceContainer实例,为了测试目的而写入新的规则,并要求代码完成它的工作。最终,代码想要执行一些SQl(在这种情况下),而不是与真正的数据库交谈,它会调用我对IDbConnection和IDbCommand的测试实现,从而使我有机会验证事情正在发挥作用。

更重要的是,它使我能够返回已知的适合测试的虚拟数据,而无需模拟整个数据库。

现在,对于注入部分,在我们的例子中,我们可以要求容器为我们提供依赖于其他对象的必须构建的对象。

例如,假设我们有一个IDataAccessLayer接口和一个MSSQLDataAccessLayer实现。

尽管接口并没有给我们任何向外的信号表明它做了任何日志记录,但实际的实现需要在某处记录它所执行的所有SQL。因此,对于类的构造函数可能是这样的:

public MSSQLDataAccessLayer(ILogger logger) { ... } 

在的ServiceContainer对象,我们已经注册了以下规则(这是我们的语法,你不会找到其他地方,但它应该很容易足以遵循):

ServiceContainer.Global.RegisterFactory<ILogger, FileLogger>() 
    .FactoryScoped() 
    .WithParameters(
     new Parameter("directory", @"C:\Temp") 
    ); 
ServiceContainer.Global.RegisterFactory<IDataAccessLayer, MSSQLDataAccessLayer>() 
    .FactoryScoped(); 

FactoryScoped意味着每次我问容器的对象,我得到一个新的。

规则,如果我用英语写他们,是这样的:

  • 如果有人需要一个实现,如果ILogger,构造一个新的FileLogger对象,并认为,需要一个“目录”参数的构造函数,并使用该构造,同时通过在“C:\ TEMP”作为参数
  • 如果有人需要IDataAccessLayer的实现,构建一个新的MSSQLDataAccessLayer

请注意,我说的构造函数MSSQLDataAccessLayer发生之前说的一个ILogger,但我没有在这里指定任何参数?这给了我下面的代码来获取接入层对象的保持:

IDataAccessLayer dal = ServiceContainer.Global.Resolve<IDataAccessLayer>(); 

现在会发生什么情况是,容器对象计算出有对象是MSSQLDataAccessLayer,而且它有一个构造函数。这个构造函数需要一个ILogger对象,但是看哪,容器知道如何制作一个对象。容器将因此构造一个新的FileLogger对象,并将其静静地传递给MSSQLDataAccessLayer对象的构造函数。

因此,大部分应用程序依赖关系的配置可以在启动过程中完成一次,在某个地方集中并执行,而其余代码完全没有意识到这里发生的所有魔法。

为了进行单元测试,我可以重写规则以提供我自己的虚拟记录器对象,该对象只是将记录的文本存储在内存中,这使我可以轻松地验证我期望代码记录的内容是否实际记录了之后阅读文件。

的规则给了我们大量的权力如何实际提供对象实例:

  • 从委托/方法,这意味着我们可以做的构建依赖对象自己,如果我们想
  • 的所有魔法
  • 自动从构造函数(自动想通了要使用哪一个,或者我们可以通过名称/类型提供了足够多的伪参数挑一)
  • 或者,我们可以向容器提供的现有实例(这将然后排序 - 像一个单身人士)

我们看了autofac未来与自己之前,基本上我们只是看着显示调用语法的例子维基,然后坐了下来,写我们自己的系统,做了我们所需要的。

+0

感谢此信息。实际上,我正在寻找在教授概念和展示实施方面非常全面的资源。我的答案有很多,可供我挑选。 – 2008-11-19 17:19:02

4

您一定要查看dimecasts.net上的IoC截屏视频。它们非常直接,可以帮助你掌握一些概念。

+0

感谢您的链接。我一定会检查出来。 – 2008-11-19 17:19:56

2

我必须引导你到同一个开放源代码项目,我回答了一个人要求例如良好的单元测试。

Looking for *small*, open source, c# project with extensive Unit Testing

我建议看CarTrackr它 具有广泛的.Net技术 的,开发人员应该熟悉 用(团结,MVC框架,尤其是) 并拥有丰富的单元测试。该项目 是很简单的在 1坐姿,但很复杂,无法 消化实际上比 证明的概念更多。他们的CodePlex网站网址 是 http://www.codeplex.com/CarTrackr

+0

非常感谢您的信息。看起来我在Silverlight 2和Western Civ之间有一点阅读能力(重返学校的喜悦)。 – 2008-11-19 20:43:17

3

我建议你看看这本书詹姆斯科瓦奇在this blog post提及。其中一个对你的情况特别敏感。这就是“有效地使用遗留代码”。它对重构的概念有很好的解释。它也给出了这些概念的例子,尽管在C#,Java和C++中,它们都很容易遵循。

+0

Thedric。非常感谢。你链接到James Kovac的博客是一个很棒的资源! – 2008-11-24 13:15:59

+0

没问题。我只是分享财富。我在我的回答中发现了我提到的这本书,内容丰富而且令人愉快。 – 2008-11-24 13:40:03