问题描述:

In web api controller, I used to create instance within using keyword so Once it come out from the using, GC will be called and memory will be released.

The code which I'm using right now,

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);

}

}

}

One of my collegue asked me to modify like below:

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);

}

}

}

Why should i have to create a instance at constuctor?

What is the difference of the both code to creating instance?

网友答案:

The first code is tightly coupled which means trouble: you can't unit test your action because it is dependent on the concrete TemplateManager.

The second code is a bit better because the action is not responsible for creating the concrete TemplateManager but it is still tightly coupled because the class is still responsible for the creation.

A better solution is to use an IOC container to handle dependency injection project wide. eg. Ninject also handles IDisposable so you don't have to call Dispose() yourself.

private readonly ITemplateManager _manager;
public TemplateController(ITemplateManager manager)
{
    _manager = manager;
}

This way you can unit test your Get action by mocking the behaviour of ITemplateManager manager while not depending on the concrete TemplateManager.

相关阅读:
Top