Search code examples
c#asp.net-mvcentity-frameworkmodel-view-controllern-tier-architecture

Need assistance restructuring an N-Tier MVC/WEB.API app


Currently have the following N-Tiers:

MVC/API UI <-> BLL / DAL / NLL / Model

Would like to accomplish the following:

MVC/API UI <-> BLL <-+-> DAL <-> Model
                     |
                     \-> NLL

I have a class in the DAL to return the context. However when I try and reference this class I get the following error (which is mentioned several times on StackOverflow, however all do not apply to this case):

A field initializer cannot reference the non-static field, method, or property 'Corporate.Web.API.Controllers.SiteAdminAPIController._oDataBaseContext'

The following code is in my DAL for the dbContext:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Text;
using System.Threading.Tasks;
using Corporate.Web.API.Model;

namespace Corporate.Web.API.DAL
{
    public class DataBaseContext
    {
        public DbContext dbContext()
        {
            Corporate_WebEntities _oContext = new Corporate_WebEntities();
            return _oContext;
        }
    }
}

The following code is in my MVC/API controller:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using System.Threading.Tasks;
using Corporate.Web.API.Model;
using Corporate.Web.API.DAL;
using Corporate.Web.API.BLL;
...
private readonly DataBaseContext _oDataBaseContext = new DataBaseContext();
private readonly DbContext _oDBContext = _oDataBaseContext.dbContext();
  1. What do I need to do to get this mess working properly?
  2. What am I Missing?

Solution

  • Doing wrong at the following line:

    private readonly DbContext _oDBContext = _oDataBaseContext.dbContext();
    

    (1) instead it should be like following:

    public class SiteAdminAPIController : Controller
    {
        private readonly DataBaseContext _oDataBaseContext = new DataBaseContext();
        private Corporate_WebEntities _oDBContext;
    
        public SiteAdminAPIController()
        {
             _oDBContext = _oDataBaseContext.dbContext();
        }
    }
    

    (2) Or make it property like below:

    private DbContext _oDbContextField;
    private DbContext _oDbContext
    {
        get{
            if(_oDbContextField == null)
            {
                _oDbContext = _oDataBaseContext.dbContext();
            } 
            return _ODbContext;
        }
    }
    

    (3) and third and easy option which many people do not recommend is like make _oDataBaseContext.

    Replace below line

    private readonly DataBaseContext _oDataBaseContext = new DataBaseContext();
    

    with

    private static readonly DataBaseContext _oDataBaseContext = new DataBaseContext();
    

    Update You also need to update dbContext() method's return type.

    public class DataBaseContext
    {
        public Corporate_WebEntities dbContext()
        {
            Corporate_WebEntities _oContext = new Corporate_WebEntities();
            return _oContext;
        }
    }