在web api控制器中,我曾经在using keyword
内创建实例,所以一旦它从使用中出来,将调用GC
并释放内存。
我现在正在使用的代码,
public class TemplateController : AutoVHCBaseApiController
{
[Route("{id}")]
[HttpGet]
[ResponseType(typeof(VHC.Core.Common.Beans.CheckTemplate))]
public IHttpActionResult Get(int id)
{
try
{
using(ITemplateManager manager=new TemplateManager())
{
CheckTemplate checkTemplate = manager.GetCheckTemplate(id, SiteCode);
return Ok(checkTemplate);
}
}
catch (ValidationException ex)
{
return BadRequest(ex.Message, FailureReason.ReasonCodeOptions.ValidationError);
}
}
}
我的一位同事让我修改如下:
public class TemplateController : AutoVHCBaseApiController
{
private readonly ITemplateManager manager;
public TemplateController()
{
manager = new TemplateManager();
}
[Route("{id}")]
[HttpGet]
[ResponseType(typeof(VHC.Core.Common.Beans.CheckTemplate))]
public IHttpActionResult Get(int id)
{
try
{
CheckTemplate checkTemplate = manager.GetCheckTemplate(id, SiteCode);
return Ok(checkTemplate);
}
catch (ValidationException ex)
{
return BadRequest(ex.Message, FailureReason.ReasonCodeOptions.ValidationError);
}
}
}
为什么我必须在constuctor中创建一个实例? 这两个代码与创建实例的区别是什么?
答案 0 :(得分:3)
第一个代码紧密耦合,这意味着trouble:您无法对您的操作进行单元测试,因为它取决于具体的TemplateManager
。
第二个代码更好一点,因为创建具体TemplateManager
的动作不是responsible,但它仍然紧密耦合,因为类仍然负责创建。
更好的解决方案是使用IOC容器来处理项目范围内的依赖项注入。例如。 Ninject也处理IDisposable,因此您无需亲自致电Dispose()
。
private readonly ITemplateManager _manager;
public TemplateController(ITemplateManager manager)
{
_manager = manager;
}
这样,您可以通过模拟Get
的行为来对ITemplateManager manager
行为进行单元测试,而不依赖于具体的TemplateManager
。