So I have created a provider which will handle all my code. Originally it looked like this:
public class AnswerProvider : ApiController
{
private readonly IUnitOfWork _unitOfWork;
private readonly AnswerService _answerService;
private QuestionService _questionService;
public QuestionService QuestionService => _questionService ?? (_questionService = new QuestionService(this._unitOfWork));
public AnswerProvider(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
this._answerService = new AnswerService(unitOfWork);
}
public async Task<IHttpActionResult> CreateAsync(AnswerRequestModel model)
{
try
{
// Validate our answer count
await ValidateAnswerCountAsync(model.QuestionId);
// Create our model
var answer = ModelFactory.Create(model);
// Add our images to our answer
answer.Images = model.Images;
// Save our model
this._answerService.Create(answer);
// Save the database changes
await this._unitOfWork.SaveChangesAsync();
// Return our updated model
return Ok(ModelFactory.Create(answer));
// If there is an error
}
catch (Exception ex)
{
// Return our error
return BadRequest(ex.Message.ToString());
}
}
/// <summary>
/// Validates the answers based on the question type
/// </summary>
/// <param name="id">The id of the question</param>
/// <returns></returns>
private async Task ValidateAnswerCountAsync(int id)
{
// Get our question
var question = await this.QuestionService.GetAsync(id, "Answers");
// If we have 3 answers or more
if (question.Answers.Count >= 3 && question.Type == QuestionType.Boolean)
{
// Throw an error
throw new InvalidOperationException("A Boolean question can only have 3 answers");
}
}
}
I inherited ApiController because I want to gain access to the Ok, BadRequest and other such methods, that is the only reason. When I try to run that code, even though it compiles I get this error:
HttpControllerContext.Configuration must not be null
I assume that is because I am trying to inherit the ApiController and I shouldn't be doing that. Is there another way I can get access the the Ok and other similar methods without inheriting the ApiController. Please bare in mind that I will have more than one provider.
Do not inherit from ApiController as this is instantiated by a factory in the request pipeline. You should only inherit it for actual api controller instances, not for convenience of some of the existing methods. The best solution would be to throw custom exceptions in your Provider/Service/ whatever and catch them in your controller and return the correct HttpStatus OR let the exception pass through and it would result in a 500 status.
As requested though I have created a small wrapper around the ApiController that you could reuse in your Provider/Service/etc based on an interface (so its easy to abstract this AND easy to test).