1

我的ASP.NET MVC 2控制器当前通过传递由Castle Windsor实例化的存储库实例在其构造函数中实例化服务对象。我有单元测试,在将存储库的Moq实例传递给控制器​​的构造函数后调用控制器动作。ASP.NET MVC消费WCF

我想允许第三方UI通过WCF访问这些服务对象。

我发现把我现有的服务层转换成Web服务,甚至在UI和现有服务层之间添加一个新的Web服务层将会破坏我的单元测试,除非我找到弥合这种差距的方法。

我试图找出一个解决方案,其中我的UI是根据服务层的接口进行编码的(现在已经是这样),我可以使用DI在运行时传递Web服务实现,并在现有实现期间传递单元测试。 Web服务实现只需调用现有的实现。

问题:

  1. 是这样的做法可取/可能吗?
  2. 在教程或开源项目中是否有这样的例子?

编辑:

我相信我有一个可行的解决方案现在多亏了下面的建议。我创建了一个WCF服务应用程序,它使用我的域模型中的现有服务接口。 WCF实现是一个类,构造函数从NinjectWCF extension获取存储库实例,并从域模型创建服务实例。 WCF中的每个方法/函数都只是从现有的服务层调用相同的方法/函数。

有一些注意事项。例如,当我在控制器中创建服务时(实际上,我使用Ninject创建WCF服务的实例并将其提供给控制器的构造函数),我无法再传递对ASP.NET MVC ModelState的引用。原因在于WCF是一个消息传递平台 - 每次调用都必须明确传达更改(即,我的验证错误现在作为各个函数/方法的参考参数传回)。

我还必须添加一些序列化/ servicemodel引用到我以前的POCO Core项目。

另外,我从Castle转换到Ninject,因为Castle's WCF solution的成熟度很低,我当时并不习惯使用它。

回答

1

您能否更详细地解释为什么您的测试会中断?

我一直在做这种类型的开发。作为类的服务=>作为WCF服务的服务。

您的测试不应该中断。 WCF服务几乎是100%的合同,底层的业务代码和逻辑不应该改变。

+0

我认为这是不可行的,但我会给它一个镜头,看看它是如何工作的。你真的托管你的WCF服务,并针对托管服务运行你的单元测试吗? – Mayo 2010-12-22 20:00:29

1

查看Web Services Software Factory由图案创建&实践团队。将服务构建为合同项目(数据,消息,服务)和“业务代码”是一种很好的方法。一旦你对如何构建代码有了更好的理解,你可以将它们的风格重构为适合你的东西。他们的例子倾向于将所有东西都分成许多VS项目,这对大多数商店来说可能有点矫枉过正。例如,我没有看到许多商店跨项目共享数据合同。是的,在一个完美的世界里,你应该可以在不同的项目中分享很多操作系统类型(比如地址),但是我不会经常看到它的完成。所以,我倾向于把我所有的合同放在一个VS项目中。

1

如果你的服务已经被定义为接口,那么你已经有了一个良好的开端。

将服务作为构造函数依赖关系传递给控制器​​,而不是存储库。让您的DI容器A)向服务提供存储库,并且B)向控制器提供服务。

如果您希望将服务层作为wcf服务站起来以供其他应用程序访问,则需要使用wcf服务工厂将实际的服务实现从您的DI容器中提取出来。 Here's an example with windsor,它应该很容易适应你使用的任何容器。

此时,您可以将您的网站修改为:A)继续直接调用服务;或者B)让他们使用服务客户端回调Web服务。这两种方法都有优点和缺点。