4
\$\begingroup\$

We use the architecture shown in the code below to initialize the DB context for our MVC 5 project using entity framework 6

We have the following questions related to it:

  1. Is it safe to initialize the Context in the constructor and use it throughout the class?

  2. What are the disadvantages of the given approach?

Constructor:

public class HomeController : Controller
{
    public DBEntities Context { get; set; }
    public HomeController()
    {
        Context = new DBEntities();
    }

    ...
}

We have a single point of entry to the controller using the Perform method (This method is invoked from the client using ajax):

[HttpPost]
public async Task<ContentResult> Perform(string operation, string entity, FormCollection form = null)
{
    var json = string.Empty;
    var returnTuple = new Tuple<string, int, string>(string.Empty, (int)HttpStatusCode.InternalServerError, "Default return value");

    switch (operation)
    {
        case "GET":
            switch (entity)
            {
                case ("ALLSCHOOLS"):
                    returnTuple = await GetSchools(form);
                break;

                ...
            }
        break;

        case "POST":
            switch (entity)
            {
                case "SCHOOL":
                    returnTuple = await SaveSchool(form);
                break;

                ...
            }
        break;
    }

    ...

    if (!string.IsNullOrEmpty(returnTuple.Item1))
    {
        json = returnTuple.Item1;
        Response.StatusCode = (int)HttpStatusCode.OK;
    }
    else
    {
        Response.StatusCode = returnTuple.Item2;
        Response.StatusDescription = returnTuple.Item3;
    }
    return Content(json, "application/json");
}

GetSchools method:

private async Task<Tuple<string, int, string>> GetSchools(FormCollection form)
{
    var json = string.Empty;
    var statusCode = int.MinValue;
    var statusDescription = string.Empty;

    var academicYear = Convert.ToInt32(form["academicyear"]);

    var schoolsObj = await Context.schools.Where(s => s.AcademicYear == academicYear).ToListAsync(); //Context is initialized in constructor shown above

    json = JsonConvert.SerializeObject(new
    {
        EntityObject = schoolsObj,
        Message = string.Empty,
        Formatting.None
    }, new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });
    return Tuple.Create(json, statusCode, statusDescription);
}

SaveSchool method:

private async Task<Tuple<string, int, string>> SaveSchool(FormCollection form)
{
    var json = string.Empty;
    var statusCode = int.MinValue;
    var statusDescription = string.Empty;
    var schoolObj = new school();
    var message = string.Empty;

    if (TryUpdateModel(schoolObj, form))
    {
        Context.schools.Add(schoolObj);
        var saveChanges = await Context.SaveChangesAsync();
        if (saveChanges == 0)
        {
            json = string.Empty;
            statusCode = (int)HttpStatusCode.InternalServerError;
            statusDescription = "Unable to save the data. Please try again later.";
            return Tuple.Create(json, statusCode, statusDescription);
        }
        else
        {
            json = JsonConvert.SerializeObject(new
            {
                EntityObject = schoolObj,
                Message = "Data saved successfully."
            }, new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });
        }
    }
    else
    {
        message = ModelStateValidationErrors(); //ModelStateValidationErrors() returns all modelstate errors
        statusCode = (int)HttpStatusCode.BadRequest;
        statusDescription = "Please check the error(s) below and resubmit the form.<br/>" + message;
    }
    return Tuple.Create(json, statusCode, statusDescription);
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

It is safe to use the context the way you are using it. However, I don't think you will be able to write unit test. This isn't bad in itself. It does become an issue when your business logic is middle tier. Also why aren't you all using the rest standard instead of your perform method? Rest leaverages http to make your api more clear and interoperable.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.