我正在设置一个应用程序,我正在使用Unity向服务中注入一堆行为。有一个构造函数,如:
public class WhateverService(IBehavior[] behaviors) : IService {}
所有这些都是在设置容器时设置的,例如:
container.RegisterType<IBehavior, LogBehavior>("LogBehavior");
container.RegisterType<IBehavior, SomeOtherBehavior>("SomeOtherBehavior");
container.RegisterType<IService, WhateverService>();
显然,注入是在WCF服务项目中完成的。
现在我想添加一个MailNotificationBehavior。所以有一堆SMTP设置需要保存在某个地方。由于此SMTP配置是部署的事情,我想使用deafault web.config SMTP设置配置。 web.config位于完成容器配置的同一项目中,因此MailNotificationBehavior需要注入所有这些设置,或者只是一个SmtpClient实例。
类似的东西:
container.RegisterType<IBehavior, MailNotificationBehavior>("MailNotificationBehavior", new new InjectionConstructor(new SmtpClient()));
问题是 - 我以后如何能够测试? 我应该写一个interface ISmtpClient with an adapter for the actual SMTPClient,所以我可以伪造它,或者这是一个糟糕的设计开始?
答案 0 :(得分:1)
为什么在自动化测试中依赖注射?您可以/应该编写一个单元测试来实例化服务并使用模拟“行为”设置服务。
推理:您的单元测试应该隔离您要测试的线。使用注射使您的单元测试也可以测试注射是否有效,以及在您的服务环境中是否有正确的行为。如果您为服务编写测试,则不需要。
关于设计; altough design by interface很好,如果你从未计划切换具体的smtp库,那就过度设计了。有点气味的另一件事是创造“行为”。你的服务有所作为(对周围环境有影响等),这就是它的行为。您的服务行为是调用IBehaviour实现的方法,从而更改应用程序状态。
您真正想要做的是使用AOP将日志记录/电子邮件行为添加到应用程序中,方法是将它们作为方面实现。